From 4f6c151e258eac1dc3e151435d9cfc0cc24d3bb0 Mon Sep 17 00:00:00 2001 From: Rendo Date: Fri, 26 Dec 2025 01:31:21 +0500 Subject: [PATCH] Interactions --- .../{test_draggable.tres => flask.tres} | 0 assets/draggables/spoon.tres | 11 ++ assets/meshes/big_flask.res | Bin 0 -> 31934 bytes assets/meshes/big_flask_fill.res | Bin 0 -> 14288 bytes assets/meshes/jar_fill.res | Bin 3561 -> 6780 bytes assets/meshes/spoon.res | Bin 0 -> 30516 bytes assets/meshes/spoon_fill.res | Bin 0 -> 1763 bytes assets/models/Chemistry.glb.import | 36 ++++++ assets/reactions/ch3oona_p_hcl.tres | 38 +++++++ assets/substances/H2O.tres | 11 ++ scenes/flask.tscn | 76 ++++++++++++- scenes/popup_container.tscn | 4 +- scenes/spoon.tscn | 51 +++++++++ scenes/substance_jar.tscn | 29 ++++- scenes/ui.tscn | 12 +- src/interactible/flask_interaction.gd | 12 ++ src/interactible/flask_interaction.gd.uid | 1 + src/interactible/interactible.gd | 5 +- src/interactible/spoon_interaction.gd | 20 ++++ src/interactible/spoon_interaction.gd.uid | 1 + src/interactible/substance_jar_interaction.gd | 22 ++++ .../substance_jar_interaction.gd.uid | 1 + src/inventory.gd | 107 +++++++++++++++++- src/resources/reaction.gd | 4 +- src/resources/reaction_substance.gd | 6 + src/resources/reaction_substance.gd.uid | 1 + src/resources/substance.gd | 1 + src/runtime_substance_data.gd | 12 ++ src/substance_display.gd | 46 ++++++++ src/substance_display.gd.uid | 1 + src/substance_holder.gd | 2 + 31 files changed, 498 insertions(+), 12 deletions(-) rename assets/draggables/{test_draggable.tres => flask.tres} (100%) create mode 100644 assets/draggables/spoon.tres create mode 100644 assets/meshes/big_flask.res create mode 100644 assets/meshes/big_flask_fill.res create mode 100644 assets/meshes/spoon.res create mode 100644 assets/meshes/spoon_fill.res create mode 100644 assets/reactions/ch3oona_p_hcl.tres create mode 100644 assets/substances/H2O.tres create mode 100644 scenes/spoon.tscn create mode 100644 src/interactible/flask_interaction.gd create mode 100644 src/interactible/flask_interaction.gd.uid create mode 100644 src/interactible/spoon_interaction.gd create mode 100644 src/interactible/spoon_interaction.gd.uid create mode 100644 src/interactible/substance_jar_interaction.gd create mode 100644 src/interactible/substance_jar_interaction.gd.uid create mode 100644 src/resources/reaction_substance.gd create mode 100644 src/resources/reaction_substance.gd.uid create mode 100644 src/substance_display.gd create mode 100644 src/substance_display.gd.uid diff --git a/assets/draggables/test_draggable.tres b/assets/draggables/flask.tres similarity index 100% rename from assets/draggables/test_draggable.tres rename to assets/draggables/flask.tres diff --git a/assets/draggables/spoon.tres b/assets/draggables/spoon.tres new file mode 100644 index 0000000..d2acf35 --- /dev/null +++ b/assets/draggables/spoon.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="Draggable" load_steps=4 format=3 uid="uid://6vpr6n7yruie"] + +[ext_resource type="Texture2D" uid="uid://bdyc1cwthn845" path="res://icon.svg" id="1_d0umj"] +[ext_resource type="PackedScene" uid="uid://emm545mj0kba" path="res://scenes/spoon.tscn" id="2_d0umj"] +[ext_resource type="Script" uid="uid://b3i73cilpra74" path="res://src/resources/draggable.gd" id="3_bov6l"] + +[resource] +script = ExtResource("3_bov6l") +scene_to_spawn = ExtResource("2_d0umj") +icon = ExtResource("1_d0umj") +metadata/_custom_type_script = "uid://b3i73cilpra74" diff --git a/assets/meshes/big_flask.res b/assets/meshes/big_flask.res new file mode 100644 index 0000000000000000000000000000000000000000..bc11be891fedb4360dd571a2b4bc0b1bc05172f5 GIT binary patch literal 31934 zcmdVD2Y6Lg+V{OSp@kAcC;>tsp?5+rft=7ggeIL3AV_El0Tc@)ND&p05d|#B2qG3x zqzH=Upn?UZj5tVwGii1m#N|MTuy5;6(+%PC}-gId9Uj%5>=$2oVI)1LTC;LxuBu3Rpxta5_7vxUK zOrMoKC1Y0l{Ot63Q!?jdnkc_+PR8s^QwhnetZS#wpPiADJ}>LW%=GD5bLLxd`s7)e zbEc-xo1T%AnJ(jbwzTQ<7UWLLm;zUkYyCE}v!`a7atNm^m^VLrc6vs}cYy zr<22UQwsgODY;oW^NjafK>u>&bP$H)Z;qtf@KIn=QHr|NgzrjM;5lUvCbDoA{r*LS3Ma zszp*JHAu2h$Egm}vU4e&X$0v+8&f*0l1WZ(*6ghLS=VJ6Wul~u)G*g&=FZPtm_9XQ zeuk+HpU;&;r$q!`8v8~t;n^_-k)>}8y!2*vFrm)zf=|+J4T?7A;NIsOyq+>_&?f<| z*n6PC>jf@-aPLijHM>Q3to3QZvmZz95q%;4)09f^p3RB$n!Ep;KQlOb@#wkM=&6El3ZE*FO#<`>V=oshp7O0N!!MIkExn=R zg_No-rb?SA8_$Ad38cLl5N7-ic(Vf(Ivelhif>Wd`$Vkf#I*r+|fN<3bmdQ~fZW3Vvs zc#217BvmgsIDL3v%@_L%R)pL91nqHT@0b*gpGl0P`@-$N2Rv&-?V#Ff8TiHB8J1T5 zdG&9$?K$b(iIkIj#}w$=)M*iFL)$*;7sg~j@-^iBcz8T4Ye!m-AAo8v~cZ?R9^2;h&$r>eki08>qw%ReN)6M~={Jox$vUhD@YbK?pJhN}J9d8%FbLK_vkc{Ees_?Q;0vF%DD@Fa)Xve5v zO1SSvfKNYPXzim*4o_*Hn`Qe{?OZ2(ZE5lzK5ES#_3vZOU4dW6PfXFX)}>v^z=f{; z1CqZFeg>U82J-i+9rS!%;yJsMeiFTge%l-#^E>I^vR6_AlIyvkPc6Ok+=+s37p%0j z#^=ppc@BA$3fo_~oElgb&NB!7w#_T{D4$Qct~B$G`u8XL@m}(hd^$E!;b-s?*D^=h zXZ!?xek*f?#@I^6$k|R&b{5+DR$d z@3gdYsmAs_UEj6zL1Yuc@`K1`hR46?_1NiI*ol5^m`*^S!PxcYu7_%!DbSc-!839f zN%TUVo9}Bav*UBkXJ=Bjku;}$iR`)0&J<|eeg<82>I-}HjMU4`3VhqOzn#-gF}Bxi zU231B>E!c6tz}l8Padb4H+5gN=jyP{>)ijlu+1s*?jK&8cJka@96zx@&(3&c{dj&v zC$VOcr!CtF?75dM^M3OAD*Sw1p)AjY%Y22r?+MQX8@T5tu2EeiKOZi$>~9ITgKSQ0 zj%%lJyJyU*;Ng=eQ@k;(aho*rlY%REjSt>`{IL|#7Y+{yrrg{+Ae(_V_YST){#b!0 zkN7z*AiDC;alv-zWRnKo5?-z8-H;HQ>S+He~ z+G-1BJQkj3lusbs&W*Sib+qldf%|NyFJ-T>cjaPSQ2kPke)%i?C;D~D|0(?{S~k?n z(mC|=BafW7YvrUFT?-x$(>t@erj+1%*?)I2F0eV=?}uoQ80<8^4gt*?b330t_egeN2ZqJ48eXY$wY`2k@?9<3w`$Ko0%-^f^RJ7L9GBeyf zU#E;31CncP{WZ%ikK~#^CD;5pow-i*LFPZvT8l+%4wPJTplHcOYo3(cn=>UBt^Jh%iqs_0A1soFn?*8brbyy%34qyp`wMQaRb4YG3XuX$Ls=HchV z*J|EY-6dDuHE)a7yzR-gKR?Vho?LUjXkB|0JJI>*wdWMA=j%jR9!+_)j!3R`#XTEBRNCj}Fuf*HQVm+4!eDlAm8XBS4vLy%MNv9{EcC9rkaNm+05Q zzrl;1j{aw^5v_SU6qfJgJ}1NW7bweZ*m-r&f9{uEvM;x6MzDXoI_-uWVeNZwZLq}P za|NPDuUi?6tvoa+x-Gcc;BzUSdQ zrPq6Ftz3OwC!Bvd@<VdtD;` z4(wyJpHcpm!)Lb(*m7RBdyj+cNy_)EXldEJmwnXk?e~LEhv`e%M+**DPu-)viov#K z%-&t1Yxb-djOH9@^C#~p_A!!oB=2gRF(g05y*}c4$(3gm*Vug6W53Sdtyc4AfKnT4Om4xq+SrY=eF~ zR2yI$Qvt35_S4PNaMMgCTpQ?2%k6~P3H>zJ?zGyr=$|6TXZSs7c9BK_cO#QT)E;QT zo#0()N0S}_js|W+GMaZvyTO9xOcIv6f#r~oC2a$W+e;b?Od{=p+Gd`G8f(Upo&|2> z_13e%F<=MyINEWhCANDlY-#p^$C>dK?}r|5_QO919>ndh0qEzEMj?Ne z{GurR9;8vwFOVJwJ_pyC^n!WO;un#0HU;GOoP`Bu0(p%G79g(yJ;6ki>wchQK~fFi z^Y9(W`+1-=6G=g!xPzpLzz(DXP(kw&)I^g`dI@*{t|KWOc!2aW7RhLW!{LVJzA~3m>Mp51Y2YL)c9QPDWGROhI}W z*cN&+INiL8KAn3DzlLlQl<@0lCqoIpZr%XC!BsDrPUv5vl)@S4UxgB`h}COQ!c(z* z9cn69ykU+2k1*aU0C&I_1HXYz_*x`KpoFhAt$?i<^G^Vq@oQz?1ir~L)e7xfz_;M8 z#r`PpC|ogf3|x%dj=>!@?a{wwj+5F0kD3$Uqv%dx@fYw^N+sL{$uX!d@Na`FQgY#U zko*Pe9r$;_8Pra=E0VXNy2Aez+=&(tK8fUAsFU#Tfs^S$;S?l)g-U@x1+KwZIz@WX za;MB`WT(-dLJ|jzgL~1O0l&z|JOdYJ&Z0kUa!F@_aV8rahb|k7c<>91XW{peoPl~D z{%_#NnURENA&G~Y1wRw~D6^ID2T1+~^#S~c;H|W;a0?_ep<2M#0zXDu)*>CZTrKkv zvX9W#Lh>>2W4PmHHuyNLJR9y~a}NDSCWdql_^~Mt{uo_xEdCB|PrD1BM=~4gJp3H+ z3EEw_CX&BH)r9{9+=X@*{uId^s88WP1HVJN3s*w&2~;Kc`QWa!yYK}hpFv%K{~Uah zw)~uwYq`%&09gR-=SaQ)egT)u!t(|2ti@j<37G4!379XzUzi2p2;di3dB_0m+yANh3sy8b{JTNDF}p@VCH+%q?&WjKgyAHBfem$Q+;~#T>_( z2b3<~Btqpw%`*{BG3Q&LbahNVR2`^qO>rl}nG2LI&(wj+gPLnfIK`dsfpclmAHgM@ z?&yjG^WYa*$s*Gox(D1v;E$#xTG2Pd{S3TlN;!+5O9D$drJWwgN&!ndKbxM=zW{%R zyV*oKk-(lvZUSBc{(`KhDdUs@-h`w!@K@j^WH*_zPFY}WB)x!_fxjZFZOS?2fW461 z2>cCr8JGYr@ALwe1D1E9oEwpq2S!0BmU>~#0>Y|ZVaF(Hq2KO-)or=I)jJTy{ zDb^L8QdlnI4^icu@^H797$*jph_<3r(v$?oIF%?%DN~7(mV-+)m7U7Ke6%r66@D@B zy(x7iU>U3`(^FNQs=zv?3fvO2glnogv9v*N6H5z~fvaPxIn{u9XsbHa`BjB4L2JbV zOJh}y9<1Ti0Cop=r}gV{O${uoLB&ByQp1VkSJGK*7GqJ$scCh$p z*W%Jl8n7|idrcFk2{6qxMz@^bQu=E)Gp8A_DO^d@+-c5esDgGme_UNJ3>;`B9ru~>q(xzmzgb0jU$B{@mJmT*fZEoEE}4BHs6luIys$y3FtdI z51I#oot#*-{Y)(PZwr^;bmo^puRnh$xbq`F0d|rxyf{f z8UWnHUw+YmlbzDg^_|UTGq8cv#p=2u-E6wT2{&*CnL)rtPKwhN%M{We)5Qs38z8?; zaE+XGW*xAJlZw?KlS*2Lwj26x)L{Tz6Q>M+jBY|-cE@U+=}szxwg>ti)b&BQX3ko( z7TCh+iB%cXle89XFZ8`=!K!dAoMC1dFbSMQoqKc5Fknw`A7rb5y}^B*K4|-rV$B-# zeVl$yU)raik{OOwUuQU)KF(cO^#cwE_lN3dfTp1tY3{;$B&okM0NcAbE#8GR(hR_Q zAkv1whV*4GXCS3p&2_l=! zW4LR8*O&*){m_lg5affMG;9U|hk)-lY0yKQp=i>8q6R<@Lw`T;ey$(tjG%OB&Tw=? zfg{Wa^Cu)D%y38ePt@{H)OxrXfz>c)1U6|%M>@!yk(Rm}{Tg#OZFV<3&>M?u(A;hA zfxCx(>j~EceG?>in`@v)B5#VODLvmEeiZyDxO>o!h9B*W0uF~3zX9EFXAIP6;0Ck7 z3`H`^8A=`-%ovN;lhaVM9?5z}oanL6dURv0^kHOUorlpq%s5RUm$K*|Hh+er&hTTM zA?V7QA;^aym#z!rx2zclKgJmcH3rLZ{Kg|0V#YgvMt2{09P<0HZ^RYjoko@l@HE_K zCcuw(CLp_y_7i@HQ9i+W2-}Ak%K@$&jMW6-Ls(1%kD!$&@*C!)1JjWVqj%Gx8q?Pg znT=dG82FGGjC3RE0l1Bf`fhL!fJ<<0*OwUXD~O_(9c}r5Lpr5d*;D7Sxpu$z&^I6- zT>P+WZE$`mKFi?+gbv<1j*o^O102Iq+C6sb6-7LpcbFFKa7=Cq9%m2YI!fzUtOIcz zDIPcuZhZKVJs!Ft%^vn&?G}4x>6^ zwzr&Kt6XcQLr>=wj9$0s#f*-s*J4r2;#x>rgg-T0cOWJoDxC2QqA*PY4lcH(6 z4y5YjQQpk7ucKx{&!nH5Q4V1p^JYS~fNo)C(W5#j*5WXxgPo3X?adqubs&pFmrc*< z@Hq>MZlu{9HFPNH22~t98$00~B*lR-Sa#!ZqbpLO=31Bo*6}EU+_FtBzijBPaJfj? zpabWEyTZ?>&vcyYLYhO$+H~JQ%3*t^?RE~ZC$zTYIl!BFV6|;8VWm0H zJ)pJC&jHTmr^CTwD_smFnGOw$NsFMnQ{H*NJT@(o)`gNx2a&p@Jm@;qV*xOqjgX{E zpd{1bW(g@DI+6Na2fT$%m!u`3B-2r;B*u%U|p~_yeok#(P=Ap8*m9&+qc_*x1rOP@OEHHu(p}n6!t}O2dRqP zX7&Y2nufjsurfFn>JGLG+WN&>svlHCHW>}z8$#d7uL}9IO@Lob(neq;co;UTfN5a6 zm0A*YI0S>s>>tN~#BRH$>V%X|r69P2vM!ZHnvB*IGceR6YQ&JT`*+v)L3LfJBR` z7FcbN`?FDf2)v13f5wj%=tg$g-b5(|Lv2D@+TzkkwCrmOAX?i8Z70@4X-mwO8Tc@q z-8j>J+K3DyX=}V0eh?CEfd@gaW5zIM@VbR5T8|G#Xfbcb{MsDY0=hXfb4#GZjNc4i zFTh*c^`IGZc{OXT^+0oR3;1HJ4y}N-SXJ~VfHu&2`LEeuFZeb8D;KR&ZA?3o)_``v z>c}Li4s6T%R}8A6wbPnZ3|hE7cWK8J9qjrbN~?vtez@y|yJobc#9BK#kxO-8MYzuJ z(a44MvbQ5tGMY}z$`$RJs#l4Xv5pKkLc}O#9DPTz?iO`yP6DeaNd<3OTWFAWdYmTnVuMT(9ykCM@r4&-lXmz1Q z)q^Sl*34H0SdZC;gECliXMdnxBWRu-V4t7T_DRsQp%Jawcc3l3I34=x!|Mqc#Pcx# z+z4D6nfL0TfgRsE)@eS`GcyP{2;P07G>0~TtIWKk*`W-xlV(HBN}8vJLN&2cZPbS{ zYiLGj0v?K9Gpy#{zRZP9;D?hW=}WCNU-q-JPZQ=6juz0OG^1*U9S+sl&O2p+?u;{% zd^Oj&GqpR9YktwpG1B5|sHNugs_+eg*MJ49BCl%OQFG7$Mgh-rT$O;H=Z_pcZROef zRs-q@)Dx?xRDYnCS>W;`5Mqvb;J0dkYV;EKL?xO@$4AxcbxO7LPI~FzaO4+ekpI+72 z)u^q)C@UIIYTx?dw$>=D46RvNW2gbRGL*(d6|g%#v>Lm87Kx@IeXpKtL@G_cMq0Wt zu&f=)8Uc-x2 zt*kv&N!zZKZHt$nh18}Rt-M%-)4oN#S}>M+%ffBPs?ep8sh)0&s0FLqwveUTPHj}0 zI~tSudbd=K_k|?hnKPm^x`iFeCmdmuN?(keHSXM!tGr(6RR@*6v@NwtQ;IvN4v{3i zj4DNG%2=s;Z}p5Tpim#{0uIuC4~kfN{D0;_(J}r%^Pu?edQwR%GPYl2Jh2JY9BK#HjA3ZVro)vzN z3%{4ef8wp-xBu^YW%#`>uI8cP_p-Q}SBBqnApzwQi_`Nm!_w{>s_`N~=9w2_N62Iq(-y_BEsiH4a)i0hmi##a)|LVoz_qgzT zV)#8M{9Ye^PY=I$hu<5-pO4=gMC1A2d4Tx6JN(`keh-lU#Ove#mZyi``@-*);rGP& zlrLEA7rlI;dNuD3zXyol6XR+gBYw|~PkbIGe$NxXr-$DI#P1pMpLksOJs6o32t zf5Gd+@1@}P0P%Y!_&pZi#d<{a>j2zg+i!iSGaU-2dge|BH72 zSKa=vvHf3c`@ib;f9>u6I@$l#vj0nE|Ci$aua^Dx{x6vQUrzhKAoqWX?*D?^|FydR zD}VpjVQujVb__X_ZT8SnS9@OxkQy%GFg3VzQ7zgL6b^TF@o;Qwmh|7E}bOMU+r z{Qj@u{a>;BzxMWj1@8Ys-TxK))xLW7e=+a>0^a{sz5fe%|5x>geP6))zsSGZ7x4Zs z`28LWey@hBc|rI+0sLMQe$N5_c=mf-_@9fbeTDD$*6@3J_`N&)o*RA-8NbJi-xEfA z20i=osPTKz_&sg>9yor_9G#nVt-({m@0H~DT=IJ;UCk@W@7?5iE6Iz=@A2jL1e5od z?kkTkzZaZ;ZSs4F`90|T9&x(Yzw;LJd(&ObbIGxptdl>q? z5dB_-es4p+*P`E>(eEMY_jvSsRQf$F{T`Bj4?w?{px=AY?=g5a&pN*sqTkEzKk-2G zdyx7)OSQgx-lTpH(%x$ioWEskC@`jdgXzW;#H={CV)BnmUg#oRc5#m$#)R@hp-_-y z@wx*@eEjsD>yj;>XK}#e_n!-eunhK&@4d0o;+J07J#}y;?h|}r^ooMzQaO!D<)$fSQx)za$%@2FZu0PcI>#ZL-OiARZbO#QfG@Fy8N}CkAD76TS^lk zsXPIa{soK06uaAxYwUjgKKMW=ulGjD_n+&%u`p!vzuHmn5u|~f{nvfFq2JVfGVK#|?S?Gx zcp(3w2GbYS4+R!y*!~$d;^AX+u?tikZQCs-V&Q@F#-uiXd(Wd;s@Dx0%N!PNx%1fZ zk8E~&nf*Sc#>Pg*Ze`MfZ7-&cj9f|%8PuKSjDZvM*Y6$fwL8VY#V ztvF}oKg5eA6CIU9Ixm`OxcN$(- z{L)r0of6*q3J`qLF_-6>Jb2(MJIFV%Co}m`jmu^O9?gQU9W$)nBjEHEsa78IO7mBC zXoM#>SaDF}vwppbZ*zU^@oU^~m zDdAu4E&0WJYoofq`ook?Dp&M3(Q|~8qDCePOW$zT_gxnTlONUd+W-FKM>Q_CzR_U1 zc+bAn)_IF>Mjpzu{T_H?qB~wjZW;C*`2-$3F!_-3Ti()@m!5U62^bcoBJ zOg?&C{K@1}UkNuln*zq zZ?!+7d}p0-?JB&r?{o2wzUubVi{Ib2l%rk8pED8wkh|T$Uas5!RR=w|<(<;aZ)u7#iLoeifO#i-pY@C zl^pZp-OtP#5O?#|LY@o8H|1QCdSuL^t)bwq%p+sy|6qk-jO$=1I5%Va`h580_S@G> z@0CB4cX^S<-!Eh5Eq3QcXFT-{)St3svhcptHONEhryq3rzYXd!Rq{T;HH)cV;MO&F zzNT?;VcVUrXCbpTu2mJ`G;mWb?b> zggZVKZgly{&%K(f`%s5G;Z{4{ak65vs}JSb@fx5mR{!%_S0Bo=<4t{G zEr)gCOqZ=agqODJ+EDo0HhroJZ+(Sc0KcEyJjuluD+%{4zvWfoD_;Y_ z^Wr|)@8VUgh@s$(@gtrW{zu(QTZH$=ojvNx>-}B0#QQ)n-_S29%sUr6YpOk}aeTx~ zJ*e?})*L*e@f_KwccUd^8E09cDvf4Ez5L_kOrpiu=jblJa?RT%Ud^8P4nR0%g(vwu5-w(=d(Y!^}OS} zTfY+TyY;E?mfJoz9dp~O&LOvbD!k>k=asMBb$aV7Zo9s=H+mrT4K&;7&KuQUbDyhm z&-J-e@+S`8uu-_~u6+*(e_R;9gc{_3a{5euVJPtR4F_K2uSuZ~2R!gwDTn%$-ME~9 zX`v58_lBxqAKJ0=DfLgN*JBqu{>F2AU+_pi?506$?Yi=H*R9GYb;t76W#c7(dX2Sv zoAFac&u=I%ehKp6knD>c^Uo9porMG9^xVEQ_DsI;nFrnSh4O6unRo3x6sR}Fm1m}M zzaafK$Sr^M250j1ysLjre%!$kon1R`JUln*Vn^w3m`i!M?)*S^A9Ht0cb?qR+ijOn zo^8j#ljGg_^x|5#{km?uX)xst^jYV&YbejQb6{VV%fB?*)pzLc^4|FVPoJ0VuRf*` z8hr2o5F83oTJW*&-Ss0BVupazvYbbwf7CIa!S|NzNKt0^1;5;jFMmI37X?@ zKlXpeha6)aG-m%SyU&`v%9+9Z-);7RIJcaO;?LB?F6g}P)+0U6tyjnLQ#wg*jN3j- z&bfBOI=St4_4Yn?oSXueZ#{5+QGJsd$}9PW_~nz!90u3cA7b@kMK~&5(Z|r&@#k78 z^%wYz`SWwLCNG$uSroNyCqCSvPz2#CkL=uXdHL!( z<-tDo}M{l$kuEyMRr{XL&c zwti|0{jpu;91^zCHM*b2tB+(Sc^Y!BJybu*bsrbI*Qvf~$d#|;N~+(7R?ajBP7Qn) z%IoTuPnNo0-apk}dcWM$yVuJ;Xze}h<{xeI)ph=MR5^6L?&n=!go8f0%B^~;%|cf0 z^_Sb9MfLUC!LN7AThu<{z5080McC_?q;Nka*mjcMZI@_^y>h62ZuyJKE8eS@Hx7g) zSN(;(c671IuYYO()IKVw*BThyPP+_UqrSAH*lZ(Mly^5kAQi~2!jQ@P#o?#>@Y<^5N= zTYt~a-%f5m-gED^ThaZzes=HY^>fJHH_ev8ZD+TAR9=_gWZO&i6Yth1E!?kZlsgZ7 z(ew1j{`cC)Yd5bwk&~DDPkH`pKf1Dn-`mCIz5aFO?sKJaqOq*;p?uUn(rX;3UgFii z?)dS>hsS%^Yv-%!i`p^O=2v9z_S+xFp;z7_9Br?2+s~sDC|4-lzFxbF|5v$pooD~A zyy~uelfw9q<#eA5ufBh57mxSq@72$%mv@~f_w25w_w4_7`MP@5*X=(yU$5VV-Trm$ zG~V2P^~R6N_E6h+?IPMs{`L|rxv*dEmuVci{q@iJdDj$S&#nl2 z{rk_@nSpBmJtmiN94_JC{eoP2>>z@0(tBm@W@cTO8^4>a`8n!Q554?H8%g4K) z#}}0&XzyFZd*$+%$GeaEMgRVl_wse?SyaCwxtp(7E)RS59`EJ#|7r*Ilgg=n-xTHpVD+cuUjK;?hV4Suu4tTy*Z5LfX?%QW zuPYjlo8XJu$E!z?UiQ)l!Z>L0e_5vNKDxJ8uhf9H^Gg4Z2Xfklzr${R?eOv2 z#W%R^@Dx-qqju1H@N23FHx+I#Ng;-I!##_1AKX;<{n*H#LcSFHtY_FR;4X4`4#|yt zcYPy#Ew~#A{Bu3>&T!WQuZKSX-5Fo2=fDTRwW#s|BnyB9r@}wt0O>jl<&##45H9lE zQc$8wHt>tVx`1D2ax1_?%%JOp_Bmi%EEdAQ0PF-E0bU3U0)qq->I6Q>FNkMDTR4U4 zIS5qHo_$bV2qW|o_+@@w@N3%#mq2YLDF!%iRq1CUh*uQMLAaTca9@(v6R2kcmS2%@9!IwUxB>oabYB3!fNzfNdfR)86}%V-qnXEXtP{(;41{M+Q2*Ao3d2zYmy z-*0eRfC>au2(<4sgNr~@!YM}3pK(ZwJMs7f#v^%HmJR`KoX@yo906k1kxBwf5Flop zDeaU3#+yj4j8w=NbY-wDwA}N|HwxW*&M$&$*Y)GG0NVXETXDe+~oWMQt1jT7Z_%Q|f z*-BW!s z{iFDy)gqVL=xaH{sLwEJ)Cy?=d@UydS-cYkUmK`v9zzoalq3-<4k%q6=P{G$)UlGf z$P%3q$P%5p;6hWEd(@={SMYUv68Q)u!fE7G2TC~2)FY32-1AAo<)vX!AL>cMzU+W* z0GHs@bMOZv$xE*xTpE_bPvbLI&uM6JBg#CCP%l*o2opzbY7)w)5t_zOjht=tcVnQa zO6a%Y$ydo4ieGOfg8ei>+5~Q!dD)z0dOMLw`xN^6&QsQ|1)8S_3Zu|56|ku9DEws$0{v7VbWLmcr_6Tv?WQFb zt)a!YfvZ3enVnpb#62ny`bWWY6dbcP!E}Jm5UifSE3vin1nmol9-mt{?3^p;8h~5V zhF6f*g>FFLp+V%=%6SG~$Ry~tBfpoH(h>#Qx5@EwE( zYD#LtuLEsX9WVBFPIXhp;*MCgBfL{bbe+%+B>>QBtRum9;7ip3y?oo{-5$w3I>ISL z&}w?3vlES7GS_u-l9AnRy1+*Qld-7Rxagofg3Li+UL`aY!PgzixcfxcLmApSvLN4~Br!1%SI znMV*G1^KCuqzCjoLiF^8>(7_Ha3s)ac-U09fkn|&%&j75eanJrvH39`K$7T>= ze+I!RBv3E-UPy8Y@-rBIFp>dIF~ar`{D%NOgZQOkI|L|dDD+UuTMdh0SPUbCPcKu9 zm==SbY`DP$ugQiVP97tmsv_$SHv%}qsX~~YY#XGfDp$;b>JA*qH97bLS0Q>t75t>H zffGzIiX<_LfIFj*DC|ymEJizXupI@L!%1P3GZ$~qIY_(O5ItSt6sl(o{1~S;zSm>n zWH%1kD1z#YL#oIfv$^jaY{tWncV=^)LgS3#H;&*p6P#`~j7~SC-H02apgA+SX119~ z=%ATEQFz&+oq>KPL2o8HGk~IIp_>S-if$5Nax&0#BQ#G2))|gsqGTbTVN&77IhElu zoK(CT#Z88qj4T!Vv2c@|p5&MgoQ2&K_{v0G$s$c5r>V|#uAA&kMVbkm%x|od$*%*t zu|P=`$E5>tTVy@WnF2oz>RNW;)11F*NA666z80Hlz-i7vJg=uYb-6=bwC`Hn57>`V zPXhKt|E{?fsxI(a=UsO2J@Hzej^tWrI+FMBF&0+bg7?f4w9}m|TBN7RLO;OFfSc~j zfLdZ^T0GO4=`1m`NX3EF)tOEE&N70t8EeDfhmf+IKJa}Qky%_P+=oz7eaLY>e&_R{ zXONTdd`9Yga_^6{KlDsz7Ic52cPOybGM)xvelV8%^QXdP+;a}pGLy{{ImgLHlFd`x zi))smFHSs=S-{iar6vc9IZh5%r_EgSOMyAiXTjMHA-k|x#r0jtVHLB^D(0#jrxA2A zbR(=9VUY~%?3^V|#9U{tb0_l7NbV$;#=y=mlJmQ;0ucKDw=~Vn;#M4kj!C{%ZBPQCV`(` z%+!MOUNz}OjM-JVw= z#54r9M-ppa^~72(fFza|CZ#ykD>%ax?WZ2wE0pXqGe263N+N0EmkCORd`djj45js5>07KNeY^zX)KbYZJH*t zrFJq?P@KlpwlVxr^sC7s66zMCW7%p_6Mj0V-NF&?E@&O~@=3RF_*xCG4fq-)dOg#G zr0_sGIOcP-{1dc}n2SjH91q=qLQS9+@$y7R&vcHhC4u)K(JPsfq>0daC9@c)U{!iC zqiE)WdOcGTdIG;XrZmT2j;-W(H`IEl2|5r%ZGb8bo&e>(ZqbXA8um5G2B2P~=wQ7b zsFx?>?JJgMNXFTN>^fd~jOR7V{iJfH1z1q=6W!MvW6|CZuU8`vLhGf7a?$IJu_V0| zQ7F6zNP4}Y*BB2%>orDMEFXl@>yS;*WuaRF^`b$qH1q;v6Xj6IGzHVss|dYv7zg|_ zcoT>JabUf0XoBNU0F74(zVM*mwu6zMT!L(F!Pj$-crRNx+Cb&#!zMQe_I?m^Z) z%;~tNW37&=I<`Ko!zA<$4vbHengVrX98B8IaZmrF!C)vI76)@oYYJAFn+iZtI)YW; zkfty=)!}qp8^oOR&w-qxnK|3>Ys)Mc4OYmccC4$lkZ9)D8lZW(t)0Q6p(Egu!J79Y zzGY`76XG3f?7gs}4AG!~e)_F-adur>eRbM-UK6W9s$(zqri_zV1nZrBW~GtnG_NTebl7M&RP4M(htJfio;0fX<-rwW~8?+AG`V*%!!3A(>)$Diz91&#L~n;9AheKC96@1%_12!f3`|G}e`o=$TQd zqS{;$!IK)n^O%6HBKN2Wl}OT4D(pS03cXW@t76zOS0+`3Qu*qFRq9wuCtMs!J)VcE z;A&9CEv+X?&!?dO32exd=ss!M%QVEg5qveEXth_YZ7DrDjlxe(6DS2j(s+%frL~`E z3@!;*no+6I>^?IZ>v7>HN6$=C`dfV&2UJKqh49e`P~U4bxMNzQP%CJ2D-l%|Nr6-m!q z1xhJ-Q#kdvKai8#-<9Yi^>HPjdR6nV`c=V`3{b(8)K9_+nxr62u_SliRXai-QZ1bAS#VzFJzPI zpc<&uZcTKL(%ea9RS+q!SEG=qKcj$Awzev({x_F0@FggR{^uoPH@W|dw&E8?kn~SV YrT-wxQz^`Jsh&vv^P)Zt<9{yyUuxixivR!s literal 0 HcmV?d00001 diff --git a/assets/meshes/big_flask_fill.res b/assets/meshes/big_flask_fill.res new file mode 100644 index 0000000000000000000000000000000000000000..47c86215fa7f0044d436fcbc5cf9ae8953124547 GIT binary patch literal 14288 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 literal 0 HcmV?d00001 diff --git a/assets/meshes/jar_fill.res b/assets/meshes/jar_fill.res index 615e968056860ae74d27c71860c89a46338e6ec9..66a95532ce9e739c52a8c0fc58fa7b91afa7e2af 100644 GIT binary patch literal 6780 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 literal 3561 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 j8|kj*fBUduZcDiLrsEu5r|qQ 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 Zq(%IX&S||Ej8fPlz7Q92GXB5Z{{>C~=M?|| literal 0 HcmV?d00001 diff --git a/assets/meshes/spoon_fill.res b/assets/meshes/spoon_fill.res new file mode 100644 index 0000000000000000000000000000000000000000..dbe22f0e2f066fe3910f3b03dc477c60312b9ad9 GIT binary patch literal 1763 zcmV<91|0cPQ$s@n000005C8!95C8xz1^@t>0000ewJ-f(01q880GdE33_u`rk`5uF z*WdyL0BE%-5C+L;V~Pnu7_ZSib<=l5>H}l?< z{l4$_Ed`|jr~s@0ANeFri!F!~gYf06KidZ$Q9Rjn3?8M8p0cTo>3q!YvXuC{XSyr#)X6m*hSv*$L8(4#D|s^v=WU2UakF$wOA z{+Aro;IhgImHTt5Wc^tPYRA#BWV{kI`C1AMeBrjqVzZ|$KDLdoIM=~{7%%WbLW~*} zX7GQIS94E*l$peTlK%q!hx`xl2MYB`$K5-pDR$^wydZt7bD5w_wFo%vl_DVMraUc^ zpfrto#u#DP2DRH+C(xl(O~K`!yxkLDGrFdW8ZHI3nRIVz@Q=QytdhxH$$?aBtN#h2 zYTId27EPj5%M;&J0+NwCP6ri`w8qA|uR+(AW6N>$w9NufEsjvrxftZw$}1zUd(!p0 zEC!-@;W7y>o6cGYb1tl?EAm?iwQB4Ef+u)$?`f~~2btMBr)DxC=3e-p;;%VgrsEw3 zFE;i=eiXV03*GB0E(Mj@+mDlMI!V%rf!bN_6In`*c{`DH;?x+6`P{zdnsq@#7v-{W zlS%t=6TG6O%oCZCyC@7;WAvVjn#$;jo+xd{ZClor%iGUQ8jVJyA(0+Ok7TVT<18sG zDLGVBE+-R9%7}{kkwZo0l0)TWQn`$%SW-?V>c@W$+gIec`v8L;H+*0?EaG{&A!bN6k1J73;s$cq`DJK(v38U_5qu zK8@Okd&=jsc~B7Uj%t$Gyk8b{W;%o?7(bDcoCv6xSe%4OT^iwtX7dT$Tf!Z94$IPp zRpeF-qr~wzyF+hOw}*y0v3czgW_}l%-Ri!6%x?_EXu(7wjU!T}%({e8LCdB|2&71wAH&ta+%E@3%m>z9OgSwk zD77#BAoz_00FntB9dJ!r4x)e77N%uNgKV<5r0jxR{VyDYAXqFG?Gy_L19HU86H8=D zW4M;QwXkKm4K7x5U~er~A3WD+P!t^1lVGZ<={XQh(@*qN;Ap_pG|vH=3P-r!QW6NJ zxc1{{Lbg~6M)J^j4*)hJ^jD=2fnqm-Owk@-h5$SOHeC3siK;@iP%N9e9k6f@C;?Ja FLqnDDJLUiY literal 0 HcmV?d00001 diff --git a/assets/models/Chemistry.glb.import b/assets/models/Chemistry.glb.import index 650df12..d2bffdb 100644 --- a/assets/models/Chemistry.glb.import +++ b/assets/models/Chemistry.glb.import @@ -67,6 +67,42 @@ _subresources={ "save_to_file/enabled": true, "save_to_file/fallback_path": "res://assets/meshes/jar.res", "save_to_file/path": "uid://dddqboph2ygmw" +}, +"Chemistry_Sphere_001": { +"generate/lightmap_uv": 0, +"generate/lods": 0, +"generate/shadow_meshes": 0, +"lods/normal_merge_angle": 20.0, +"save_to_file/enabled": true, +"save_to_file/fallback_path": "res://assets/meshes/spoon.res", +"save_to_file/path": "uid://cdvben7q8oxgf" +}, +"Chemistry_Sphere_003": { +"generate/lightmap_uv": 0, +"generate/lods": 0, +"generate/shadow_meshes": 0, +"lods/normal_merge_angle": 20.0, +"save_to_file/enabled": true, +"save_to_file/fallback_path": "res://assets/meshes/Chemistry_Sphere_003.res", +"save_to_file/path": "uid://q71x8vx4dkis" +}, +"Chemistry_Sphere_004": { +"generate/lightmap_uv": 0, +"generate/lods": 0, +"generate/shadow_meshes": 0, +"lods/normal_merge_angle": 20.0, +"save_to_file/enabled": true, +"save_to_file/fallback_path": "res://assets/meshes/Chemistry_Sphere_004.res", +"save_to_file/path": "uid://bsigmbc20m6pn" +}, +"Chemistry_Sphere_005": { +"generate/lightmap_uv": 0, +"generate/lods": 0, +"generate/shadow_meshes": 0, +"lods/normal_merge_angle": 20.0, +"save_to_file/enabled": true, +"save_to_file/fallback_path": "res://assets/meshes/Chemistry_Sphere_005.res", +"save_to_file/path": "uid://n4ibk6y8t7h3" } } } diff --git a/assets/reactions/ch3oona_p_hcl.tres b/assets/reactions/ch3oona_p_hcl.tres new file mode 100644 index 0000000..09b0d35 --- /dev/null +++ b/assets/reactions/ch3oona_p_hcl.tres @@ -0,0 +1,38 @@ +[gd_resource type="Resource" script_class="Reaction" load_steps=11 format=3 uid="uid://norc8wahican"] + +[ext_resource type="Resource" uid="uid://dr65qbkum4emy" path="res://assets/substances/CH3COONa.tres" id="2_8tq4d"] +[ext_resource type="Script" uid="uid://dwks86y6383p4" path="res://src/resources/reaction.gd" id="2_fmr2g"] +[ext_resource type="Script" uid="uid://bb8o8l6u6fiai" path="res://src/resources/reaction_substance.gd" id="2_mw1oh"] +[ext_resource type="Resource" uid="uid://bj3cdfwvgksee" path="res://assets/substances/HCl.tres" id="3_kro01"] +[ext_resource type="Resource" uid="uid://dn10p6rbdd7qb" path="res://assets/substances/CH3COOH.tres" id="4_2pq7p"] +[ext_resource type="Resource" uid="uid://chdrv5i45chwe" path="res://assets/substances/NaCl.tres" id="5_2dv8g"] + +[sub_resource type="Resource" id="Resource_ad7jh"] +script = ExtResource("2_mw1oh") +coefficient = 1 +substance = ExtResource("2_8tq4d") +metadata/_custom_type_script = "uid://bb8o8l6u6fiai" + +[sub_resource type="Resource" id="Resource_ohxs7"] +script = ExtResource("2_mw1oh") +coefficient = 1 +substance = ExtResource("3_kro01") +metadata/_custom_type_script = "uid://bb8o8l6u6fiai" + +[sub_resource type="Resource" id="Resource_6x1ca"] +script = ExtResource("2_mw1oh") +coefficient = 1 +substance = ExtResource("4_2pq7p") +metadata/_custom_type_script = "uid://bb8o8l6u6fiai" + +[sub_resource type="Resource" id="Resource_h3tvm"] +script = ExtResource("2_mw1oh") +coefficient = 1 +substance = ExtResource("5_2dv8g") +metadata/_custom_type_script = "uid://bb8o8l6u6fiai" + +[resource] +script = ExtResource("2_fmr2g") +input_substances = Array[ExtResource("2_mw1oh")]([SubResource("Resource_ad7jh"), SubResource("Resource_ohxs7")]) +output_substances = Array[ExtResource("2_mw1oh")]([SubResource("Resource_6x1ca"), SubResource("Resource_h3tvm")]) +metadata/_custom_type_script = "uid://dwks86y6383p4" diff --git a/assets/substances/H2O.tres b/assets/substances/H2O.tres new file mode 100644 index 0000000..1bc2de3 --- /dev/null +++ b/assets/substances/H2O.tres @@ -0,0 +1,11 @@ +[gd_resource type="Resource" script_class="Substance" load_steps=2 format=3 uid="uid://dp0e62nxlnaeg"] + +[ext_resource type="Script" uid="uid://b8q5buwgvppyh" path="res://src/resources/substance.gd" id="1_nb8j3"] + +[resource] +script = ExtResource("1_nb8j3") +formula = &"H_2O" +scientific_name = &"Вода" +boiling_point = 100.0 +color = Color(1, 1, 1, 1) +metadata/_custom_type_script = "uid://b8q5buwgvppyh" diff --git a/scenes/flask.tscn b/scenes/flask.tscn index c3d7873..eea7b42 100644 --- a/scenes/flask.tscn +++ b/scenes/flask.tscn @@ -1,8 +1,11 @@ -[gd_scene load_steps=8 format=4 uid="uid://bjxjcx2qu16q5"] +[gd_scene load_steps=15 format=4 uid="uid://bjxjcx2qu16q5"] [ext_resource type="Script" uid="uid://bjnv2g1ni0525" path="res://src/drag/draggable_object.gd" id="1_0xufn"] [ext_resource type="Material" uid="uid://64m17act0kwu" path="res://assets/materials/mat_glass.tres" id="2_dbm1u"] +[ext_resource type="Script" uid="uid://dig825r70a0sn" path="res://src/substance_display.gd" id="3_0xufn"] [ext_resource type="Script" uid="uid://bl0ojhc0thk1p" path="res://src/interactible/interactible.gd" id="4_dbm1u"] +[ext_resource type="Texture2D" uid="uid://cw3jw8qbvj3fv" path="res://assets/textures/solid.png" id="4_h7awq"] +[ext_resource type="Script" uid="uid://duirfi4j26g2i" path="res://src/interactible/flask_interaction.gd" id="5_pmegg"] [ext_resource type="Script" uid="uid://82ettbegollp" path="res://src/inventory.gd" id="7_h7awq"] [sub_resource type="CapsuleShape3D" id="CapsuleShape3D_vcwhe"] @@ -43,6 +46,28 @@ _surfaces = [{ blend_shape_mode = 0 shadow_mesh = SubResource("ArrayMesh_1ouf4") +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_ailwx"] +resource_local_to_scene = true +transparency = 1 + +[sub_resource type="CylinderMesh" id="CylinderMesh_h7awq"] +top_radius = 0.772 +bottom_radius = 0.772 +height = 8.0 +radial_segments = 16 +rings = 0 + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_kkw7a"] +resource_local_to_scene = true +albedo_texture = ExtResource("4_h7awq") +uv1_scale = Vector3(1, 3.07, 1) + +[sub_resource type="CylinderMesh" id="CylinderMesh_pmegg"] +top_radius = 0.772 +bottom_radius = 0.772 +radial_segments = 16 +rings = 0 + [node name="Flask" type="Area3D" node_paths=PackedStringArray("interactible") groups=["flask"]] collision_layer = 5 script = ExtResource("1_0xufn") @@ -58,6 +83,23 @@ transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0.1, 0) mesh = SubResource("ArrayMesh_nvewc") skeleton = NodePath("") +[node name="FillLiquid" type="MeshInstance3D" parent="Flash"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 3.8061247, 0) +visible = false +material_override = SubResource("StandardMaterial3D_ailwx") +mesh = SubResource("CylinderMesh_h7awq") +skeleton = NodePath("") +script = ExtResource("3_0xufn") + +[node name="FillSolid" type="MeshInstance3D" parent="Flash"] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.8061155, 0) +visible = false +material_override = SubResource("StandardMaterial3D_kkw7a") +mesh = SubResource("CylinderMesh_pmegg") +skeleton = NodePath("") +script = ExtResource("3_0xufn") +display_type = 1 + [node name="Inventory" type="Node" parent="."] unique_name_in_owner = true script = ExtResource("7_h7awq") @@ -65,5 +107,35 @@ open_on_top = true metadata/_custom_type_script = "uid://82ettbegollp" [node name="Interactible" type="ConfirmationDialog" parent="."] -cancel_button_text = "I WANNA MAKE YOU HATE ME" +oversampling_override = 1.0 +title = "Перелить вещество в колбе?" +position = Vector2i(0, 36) +size = Vector2i(301, 100) +ok_button_text = "Перелить" +cancel_button_text = "Нет" script = ExtResource("4_dbm1u") + +[node name="HBoxContainer" type="HBoxContainer" parent="Interactible"] +offset_left = 8.0 +offset_top = 8.0 +offset_right = 293.0 +offset_bottom = 51.0 + +[node name="Label" type="Label" parent="Interactible/HBoxContainer"] +layout_mode = 2 +text = "000%" + +[node name="HSlider" type="HSlider" parent="Interactible/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +max_value = 1.0 +step = 0.01 +value = 1.0 + +[node name="Interaction" type="Node" parent="Interactible"] +script = ExtResource("5_pmegg") + +[connection signal="inventory_changed" from="Inventory" to="Flash/FillLiquid" method="update_material_unfiltered"] +[connection signal="inventory_changed" from="Inventory" to="Flash/FillSolid" method="update_material_unfiltered"] +[connection signal="interacted" from="Interactible" to="Interactible/Interaction" method="_on_interactible_interacted"] +[connection signal="value_changed" from="Interactible/HBoxContainer/HSlider" to="Interactible/Interaction" method="_on_h_slider_value_changed"] diff --git a/scenes/popup_container.tscn b/scenes/popup_container.tscn index caed730..65af532 100644 --- a/scenes/popup_container.tscn +++ b/scenes/popup_container.tscn @@ -29,11 +29,11 @@ size_flags_vertical = 3 [node name="Label" type="Label" parent="."] layout_mode = 1 anchors_preset = -1 -anchor_left = 1.0 +anchor_left = 0.97900003 anchor_top = 0.0014401659 anchor_right = 1.0 anchor_bottom = 1.0 -offset_left = -25.0 +offset_left = -0.28308105 offset_top = 647.0668 offset_right = 622.0668 offset_bottom = 49.0 diff --git a/scenes/spoon.tscn b/scenes/spoon.tscn new file mode 100644 index 0000000..e388eef --- /dev/null +++ b/scenes/spoon.tscn @@ -0,0 +1,51 @@ +[gd_scene load_steps=10 format=3 uid="uid://emm545mj0kba"] + +[ext_resource type="ArrayMesh" uid="uid://cdvben7q8oxgf" path="res://assets/meshes/spoon.res" id="1_l12hh"] +[ext_resource type="Script" uid="uid://bjnv2g1ni0525" path="res://src/drag/draggable_object.gd" id="1_r8mox"] +[ext_resource type="Texture2D" uid="uid://cw3jw8qbvj3fv" path="res://assets/textures/solid.png" id="3_ckduo"] +[ext_resource type="Script" uid="uid://bl0ojhc0thk1p" path="res://src/interactible/interactible.gd" id="3_r8ydw"] +[ext_resource type="ArrayMesh" uid="uid://n4ibk6y8t7h3" path="res://assets/meshes/spoon_fill.res" id="4_5mau7"] +[ext_resource type="Script" uid="uid://cefmx4p018028" path="res://src/interactible/spoon_interaction.gd" id="4_fyayl"] +[ext_resource type="Script" uid="uid://dig825r70a0sn" path="res://src/substance_display.gd" id="5_33jiv"] + +[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1r65c"] +albedo_texture = ExtResource("3_ckduo") + +[sub_resource type="BoxShape3D" id="BoxShape3D_r8mox"] +size = Vector3(0.26538086, 0.1484375, 1.6950684) + +[node name="Spoon" type="Area3D" node_paths=PackedStringArray("interactible")] +collision_layer = 6 +script = ExtResource("1_r8mox") +interactible = NodePath("Interactible") +mask = PackedStringArray("flask", "solid_source") + +[node name="MeshInstance3D" type="MeshInstance3D" parent="."] +transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0.07224345, 0) +mesh = ExtResource("1_l12hh") + +[node name="SpoonFill" type="MeshInstance3D" parent="."] +transform = Transform3D(0.1, 0, 0, 0, 0.1, 0, 0, 0, 0.1, 0, 0.07224345, -0.66295564) +visible = false +material_override = SubResource("StandardMaterial3D_1r65c") +mesh = ExtResource("4_5mau7") +script = ExtResource("5_33jiv") +display_type = 1 + +[node name="CollisionShape3D" type="CollisionShape3D" parent="."] +transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0.07224345, 0) +shape = SubResource("BoxShape3D_r8mox") + +[node name="Interactible" type="ConfirmationDialog" parent="."] +title = "" +ok_button_text = "Подтвердить" +cancel_button_text = "Отменить" +script = ExtResource("3_r8ydw") +instant = true +metadata/_custom_type_script = "uid://bl0ojhc0thk1p" + +[node name="Interaction" type="Node" parent="Interactible"] +script = ExtResource("4_fyayl") + +[connection signal="interacted" from="Interactible" to="Interactible/Interaction" method="_on_interactible_interacted"] +[connection signal="inventory_updated" from="Interactible/Interaction" to="SpoonFill" method="update_material_unfiltered"] diff --git a/scenes/substance_jar.tscn b/scenes/substance_jar.tscn index bc03aad..5cc4214 100644 --- a/scenes/substance_jar.tscn +++ b/scenes/substance_jar.tscn @@ -1,13 +1,15 @@ -[gd_scene load_steps=8 format=3 uid="uid://cw6v8kbi76qak"] +[gd_scene load_steps=9 format=3 uid="uid://cw6v8kbi76qak"] [ext_resource type="Script" uid="uid://bjnv2g1ni0525" path="res://src/drag/draggable_object.gd" id="1_o7vug"] [ext_resource type="ArrayMesh" uid="uid://dddqboph2ygmw" path="res://assets/meshes/jar.res" id="2_o7vug"] [ext_resource type="Script" uid="uid://bl0ojhc0thk1p" path="res://src/interactible/interactible.gd" id="5_o7vug"] +[ext_resource type="Script" uid="uid://bhnptwotw5bs8" path="res://src/interactible/substance_jar_interaction.gd" id="6_00jpx"] [ext_resource type="ArrayMesh" uid="uid://dxeseuqcwne1m" path="res://assets/meshes/jar_fill.res" id="6_kfk5m"] [ext_resource type="Script" uid="uid://c8epd7gguvyop" path="res://src/substance_holder.gd" id="7_ymvgp"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_pcpcb"] resource_local_to_scene = true +transparency = 1 [sub_resource type="CylinderShape3D" id="CylinderShape3D_kfk5m"] height = 0.5024414 @@ -17,6 +19,7 @@ radius = 0.22460938 collision_layer = 5 script = ExtResource("1_o7vug") interactible = NodePath("Interaction") +mask = PackedStringArray("flask") [node name="Jar" type="MeshInstance3D" parent="."] transform = Transform3D(0.2, 0, 0, 0, 0.2, 0, 0, 0, 0.2, 0, 0, 0) @@ -35,4 +38,28 @@ shape = SubResource("CylinderShape3D_kfk5m") script = ExtResource("7_ymvgp") [node name="Interaction" type="ConfirmationDialog" parent="."] +title = "Добавить вещество?" +ok_button_text = "Добавить" +cancel_button_text = "Не добавлять" script = ExtResource("5_o7vug") + +[node name="HBoxContainer" type="HBoxContainer" parent="Interaction"] +offset_right = 40.0 +offset_bottom = 40.0 + +[node name="ProgressBar" type="HSlider" parent="Interaction/HBoxContainer"] +layout_mode = 2 +size_flags_horizontal = 3 +allow_greater = true + +[node name="SpinBox" type="SpinBox" parent="Interaction/HBoxContainer"] +layout_mode = 2 +allow_greater = true +suffix = "мг." + +[node name="Interaction" type="Node" parent="Interaction"] +script = ExtResource("6_00jpx") + +[connection signal="interacted" from="Interaction" to="Interaction/Interaction" method="_on_interaction_interacted"] +[connection signal="value_changed" from="Interaction/HBoxContainer/ProgressBar" to="Interaction/Interaction" method="_on_progress_bar_value_changed"] +[connection signal="value_changed" from="Interaction/HBoxContainer/SpinBox" to="Interaction/Interaction" method="_on_spin_box_value_changed"] diff --git a/scenes/ui.tscn b/scenes/ui.tscn index d040142..4d35019 100644 --- a/scenes/ui.tscn +++ b/scenes/ui.tscn @@ -1,9 +1,10 @@ -[gd_scene load_steps=5 format=3 uid="uid://dfxlr4svnsdyx"] +[gd_scene load_steps=6 format=3 uid="uid://dfxlr4svnsdyx"] [ext_resource type="PackedScene" uid="uid://bcj0mesdlfsfj" path="res://scenes/popup_container.tscn" id="1_nt7q6"] [ext_resource type="Script" uid="uid://c5pv2idedy1oy" path="res://src/ui/reagents_gen.gd" id="2_x4jx1"] [ext_resource type="PackedScene" uid="uid://vhn8h4mhb6nh" path="res://scenes/drag_and_drop.tscn" id="3_yev5y"] -[ext_resource type="Resource" uid="uid://cay05wpketmny" path="res://assets/draggables/test_draggable.tres" id="4_gdt2y"] +[ext_resource type="Resource" uid="uid://cay05wpketmny" path="res://assets/draggables/flask.tres" id="4_gdt2y"] +[ext_resource type="Resource" uid="uid://6vpr6n7yruie" path="res://assets/draggables/spoon.tres" id="5_wm3ai"] [node name="UserInterface" type="Control"] layout_mode = 3 @@ -49,9 +50,14 @@ anchor_right = 0.0 text = "Инструменты" metadata/_edit_use_anchors_ = true -[node name="DragAndDrop" parent="Intruments/ScrollContainer/VBoxContainer" index="0" instance=ExtResource("3_yev5y")] +[node name="Flask" parent="Intruments/ScrollContainer/VBoxContainer" index="0" instance=ExtResource("3_yev5y")] layout_mode = 2 text = "Пробирка" draggable = ExtResource("4_gdt2y") +[node name="Spoon" parent="Intruments/ScrollContainer/VBoxContainer" index="1" instance=ExtResource("3_yev5y")] +layout_mode = 2 +text = "Ложка" +draggable = ExtResource("5_wm3ai") + [editable path="Intruments"] diff --git a/src/interactible/flask_interaction.gd b/src/interactible/flask_interaction.gd new file mode 100644 index 0000000..ec77579 --- /dev/null +++ b/src/interactible/flask_interaction.gd @@ -0,0 +1,12 @@ +extends Node + +var amount: float = 1.0 + +func _on_interactible_interacted(with: DraggableObject) -> void: + if with.is_in_group("flask"): + with.get_node("%Inventory").add_inventory(%Inventory.extract(%Inventory.total_amount * amount)) + + +func _on_h_slider_value_changed(value: float) -> void: + amount = value + $"../HBoxContainer/Label".text = str(int(value*100.0)).pad_zeros(3) + "%" diff --git a/src/interactible/flask_interaction.gd.uid b/src/interactible/flask_interaction.gd.uid new file mode 100644 index 0000000..c2aed57 --- /dev/null +++ b/src/interactible/flask_interaction.gd.uid @@ -0,0 +1 @@ +uid://duirfi4j26g2i diff --git a/src/interactible/interactible.gd b/src/interactible/interactible.gd index 33d3c27..aa013df 100644 --- a/src/interactible/interactible.gd +++ b/src/interactible/interactible.gd @@ -7,6 +7,7 @@ class_name Interactible var current_draggable: DraggableObject var current_interaction: Interactible +signal begin_interaction(with: DraggableObject) signal interacted(with: DraggableObject) func _ready() -> void: @@ -15,7 +16,9 @@ func _ready() -> void: canceled.connect(cancel_interaction) func try_interact(draggable: DraggableObject) -> bool: - if draggable.interactible != null and visible == false: + if draggable.interactible != null and visible == false: + current_draggable = draggable + begin_interaction.emit(current_draggable) if instant: interact() else: diff --git a/src/interactible/spoon_interaction.gd b/src/interactible/spoon_interaction.gd new file mode 100644 index 0000000..9d0b30e --- /dev/null +++ b/src/interactible/spoon_interaction.gd @@ -0,0 +1,20 @@ +extends Node + +var mini_inventory: Array[RuntimeSubstanceData] = [] +signal inventory_updated(substances: Array[RuntimeSubstanceData]) + +func _on_interactible_interacted(with: DraggableObject) -> void: + if with.is_in_group("solid_source") and mini_inventory == []: + mini_inventory = [RuntimeSubstanceData.new()] + mini_inventory[0].substance = with.get_node("SubstanceData").substance + mini_inventory[0].amount = 5 + mini_inventory[0].temperature = 20 + elif with.is_in_group("solid_source") and mini_inventory != []: + mini_inventory = [] + elif with.is_in_group("flask") and mini_inventory != []: + with.get_node("%Inventory").add_inventory(mini_inventory) + mini_inventory = [] + + elif with.is_in_group("flask") and mini_inventory == []: + mini_inventory = with.get_node("%Inventory").extract_solid(5) + inventory_updated.emit(mini_inventory) diff --git a/src/interactible/spoon_interaction.gd.uid b/src/interactible/spoon_interaction.gd.uid new file mode 100644 index 0000000..fff3a57 --- /dev/null +++ b/src/interactible/spoon_interaction.gd.uid @@ -0,0 +1 @@ +uid://cefmx4p018028 diff --git a/src/interactible/substance_jar_interaction.gd b/src/interactible/substance_jar_interaction.gd new file mode 100644 index 0000000..c592f51 --- /dev/null +++ b/src/interactible/substance_jar_interaction.gd @@ -0,0 +1,22 @@ +extends Node + +var add_amount: float + +func _on_interaction_interacted(with: DraggableObject) -> void: + if with.is_in_group("flask"): + var subs: RuntimeSubstanceData = RuntimeSubstanceData.new() + subs.amount = add_amount + subs.substance = $"../../SubstanceData".substance + subs.temperature = 20 + with.get_node("%Inventory").add_substance(subs) + $"../HBoxContainer/SpinBox".value = 0 + + +func _on_progress_bar_value_changed(value: float) -> void: + $"../HBoxContainer/SpinBox".set_value_no_signal(value) + add_amount = value + + +func _on_spin_box_value_changed(value: float) -> void: + $"../HBoxContainer/ProgressBar".set_value_no_signal(value) + add_amount = value diff --git a/src/interactible/substance_jar_interaction.gd.uid b/src/interactible/substance_jar_interaction.gd.uid new file mode 100644 index 0000000..3df9de8 --- /dev/null +++ b/src/interactible/substance_jar_interaction.gd.uid @@ -0,0 +1 @@ +uid://bhnptwotw5bs8 diff --git a/src/inventory.gd b/src/inventory.gd index 11606db..59bef4f 100644 --- a/src/inventory.gd +++ b/src/inventory.gd @@ -3,4 +3,109 @@ extends Node class_name Inventory @export var open_on_top: bool -var inventory: Array[RuntimeSubstanceData] +var inventory: Dictionary[StringName,RuntimeSubstanceData] + +var mean_temperature: float: + set(new_temperature): + mean_temperature = new_temperature + temperature_changed.emit(new_temperature) + update_temperature() + +var total_amount: float: + set(value): + pass + get: + var result: float = 0 + for sub in inventory: + result += inventory[sub].amount + return result + +signal inventory_changed(substances: Array[RuntimeSubstanceData]) +signal temperature_changed(to: float) + +func add_substance(data: RuntimeSubstanceData) -> void: + if data.substance.scientific_name in inventory: + inventory[data.substance.scientific_name].add(data) + else: + inventory[data.substance.scientific_name] = data + check_for_reactions() + recalculate_temperature() + inventory_changed.emit(inventory.values()) + +func add_inventory(substances: Array[RuntimeSubstanceData]) -> void: + for sub in substances: + add_substance(sub) + +func extract(amount: float) -> Array[RuntimeSubstanceData]: + if len(inventory) == 0: + return [] + var result: Array[RuntimeSubstanceData] = [] + var extract_amount = amount/len(inventory) + var sorted_by_amount: Array[RuntimeSubstanceData] = inventory.values() + sorted_by_amount.sort_custom(sort_by_amount) + + for substance: RuntimeSubstanceData in sorted_by_amount: + var result_substance: RuntimeSubstanceData = substance.duplicate() + if substance.amount >= extract_amount: + result_substance.amount = extract_amount + inventory[result_substance.substance.scientific_name].amount -= extract_amount + else: + extract_amount += (extract_amount - result_substance.amount)/len(sorted_by_amount) + inventory[result_substance.substance.scientific_name].amount = 0 + result.append(result_substance) + if inventory[result_substance.substance.scientific_name].amount == 0: + inventory.erase(result_substance.substance.scientific_name) + + inventory_changed.emit(inventory.values()) + + return result + +func extract_solid(amount: float) -> Array[RuntimeSubstanceData]: + if len(inventory) == 0: + return [] + var result: Array[RuntimeSubstanceData] = [] + var extract_amount = amount/len(inventory) + var sorted_by_amount: Array[RuntimeSubstanceData] = inventory.values() + sorted_by_amount.sort_custom(sort_by_amount) + sorted_by_amount = sorted_by_amount.filter(filter_solids) + + for substance: RuntimeSubstanceData in sorted_by_amount: + var result_substance: RuntimeSubstanceData = substance.duplicate() + if substance.amount >= extract_amount: + result_substance.amount = extract_amount + inventory[result_substance.substance.scientific_name].amount -= extract_amount + else: + extract_amount += (extract_amount - result_substance.amount)/len(sorted_by_amount) + inventory[result_substance.substance.scientific_name].amount = 0 + result.append(result_substance) + if inventory[result_substance.substance.scientific_name].amount == 0: + inventory.erase(result_substance.substance.scientific_name) + + inventory_changed.emit(inventory.values()) + return result + +func sort_by_amount(a: RuntimeSubstanceData, b: RuntimeSubstanceData) -> bool: + return a.amount < b.amount + +func filter_solids(a: RuntimeSubstanceData) -> bool: + return a.substance.melting_point > a.temperature + +func update_temperature() -> void: + if len(inventory) == 0: + mean_temperature = 0 + return + for sub in inventory: + inventory[sub].temperature = mean_temperature + check_for_reactions() + +func recalculate_temperature() -> void: + if len(inventory) == 0: + mean_temperature = 0 + return + var temperature_sum: float = 0 + for sub in inventory: + temperature_sum += inventory[sub].temperature + mean_temperature = temperature_sum / len(inventory) + +func check_for_reactions() -> void: + pass diff --git a/src/resources/reaction.gd b/src/resources/reaction.gd index 7a5d3c2..ec6ab32 100644 --- a/src/resources/reaction.gd +++ b/src/resources/reaction.gd @@ -2,6 +2,6 @@ extends Resource class_name Reaction -@export var input_substances: Array[Substance] -@export var output_substances: Array[Substance] +@export var input_substances: Array[ReactionSubstance] +@export var output_substances: Array[ReactionSubstance] @export var reaction_temperature: float = -1 diff --git a/src/resources/reaction_substance.gd b/src/resources/reaction_substance.gd new file mode 100644 index 0000000..a5ed6d8 --- /dev/null +++ b/src/resources/reaction_substance.gd @@ -0,0 +1,6 @@ +extends Resource + +class_name ReactionSubstance + +@export var coefficient: int +@export var substance: Substance diff --git a/src/resources/reaction_substance.gd.uid b/src/resources/reaction_substance.gd.uid new file mode 100644 index 0000000..cfe7f0e --- /dev/null +++ b/src/resources/reaction_substance.gd.uid @@ -0,0 +1 @@ +uid://bb8o8l6u6fiai diff --git a/src/resources/substance.gd b/src/resources/substance.gd index 7f76033..f62a23b 100644 --- a/src/resources/substance.gd +++ b/src/resources/substance.gd @@ -6,6 +6,7 @@ class_name Substance @export var scientific_name: StringName @export var melting_point: float @export var boiling_point: float +@export var liquid_transparency: float = 0.5 @export var color: Color @export var prefer_scientific_name: bool @export var is_solution: bool diff --git a/src/runtime_substance_data.gd b/src/runtime_substance_data.gd index 2ff1edc..98f0a78 100644 --- a/src/runtime_substance_data.gd +++ b/src/runtime_substance_data.gd @@ -5,3 +5,15 @@ class_name RuntimeSubstanceData var substance: Substance var amount: float var temperature: float = 20.0 + +func add(data: RuntimeSubstanceData) -> void: + temperature = (temperature + data.temperature)/2.0 + amount += data.amount + +func duplicate() -> RuntimeSubstanceData: + var new_substance = RuntimeSubstanceData.new() + new_substance.substance = substance + new_substance.amount = amount + new_substance.temperature = temperature + + return new_substance diff --git a/src/substance_display.gd b/src/substance_display.gd new file mode 100644 index 0000000..f54b686 --- /dev/null +++ b/src/substance_display.gd @@ -0,0 +1,46 @@ +extends MeshInstance3D + +enum DisplayType{ + Fluid, + Solid, +} + +@export var display_type: DisplayType + +func update_material(substances: Array[RuntimeSubstanceData]) -> void: + var mat: StandardMaterial3D = material_override + if len(substances) == 0: + visible = false + return + else: + visible = true + + var total_weight = 0 + + for sub in substances: + total_weight += sub.amount + + var alpha: float = 0 + var color: Color = Color.WHITE + + for sub in substances: + if display_type == DisplayType.Fluid: + alpha += sub.substance.liquid_transparency + color = color.lerp(sub.substance.color,sub.amount/total_weight) + if display_type == DisplayType.Fluid: + alpha /= len(substances) + color.a = alpha + + mat.albedo_color = color + +func update_material_unfiltered(substances: Array[RuntimeSubstanceData]): + match display_type: + DisplayType.Fluid: + var fluids = substances.filter(filter_liquids) + update_material(fluids) + DisplayType.Solid: + var solids = substances.filter(filter_solids) + update_material(solids) + +func filter_liquids(sub: RuntimeSubstanceData): return sub.substance.melting_point < sub.temperature or sub.substance.is_solution +func filter_solids(sub: RuntimeSubstanceData): return sub.substance.melting_point > sub.temperature and not sub.substance.is_solution diff --git a/src/substance_display.gd.uid b/src/substance_display.gd.uid new file mode 100644 index 0000000..67e7227 --- /dev/null +++ b/src/substance_display.gd.uid @@ -0,0 +1 @@ +uid://dig825r70a0sn diff --git a/src/substance_holder.gd b/src/substance_holder.gd index 94adb1c..0bb65c5 100644 --- a/src/substance_holder.gd +++ b/src/substance_holder.gd @@ -9,6 +9,8 @@ func _ready() -> void: jar_fill_material.albedo_color = substance.color if substance.melting_point > 20 and not substance.is_solution: jar_fill_material.albedo_texture = preload("res://assets/textures/solid.png") + get_parent().add_to_group("solid_source") else: + jar_fill_material.albedo_color.a = substance.liquid_transparency get_parent().add_to_group("fluid_source")