From c447b95aeb883113ff1d53a3178828929c1eb92f Mon Sep 17 00:00:00 2001 From: fredboy Date: Fri, 10 May 2024 16:56:29 +0700 Subject: [PATCH] Add furnace, more craft and items --- android/assets/chest.png | Bin 0 -> 3075 bytes android/assets/furnace.png | Bin 0 -> 3999 bytes android/assets/json/crafting.json | 51 ++++++ android/assets/json/game_items.json | 139 +++++++++++--- android/assets/json/texture_regions.json | 17 ++ android/assets/textures/blocks/furnace.png | Bin 0 -> 885 bytes .../assets/textures/blocks/furnace_off.png | Bin 387 -> 0 bytes android/assets/textures/blocks/furnace_on.png | Bin 450 -> 0 bytes android/assets/textures/items/bed.png | Bin 0 -> 371 bytes android/assets/textures/items/diamond.png | Bin 0 -> 270 bytes android/assets/textures/items/gold_ingot.png | Bin 0 -> 315 bytes android/assets/textures/items/iron_ingot.png | Bin 0 -> 291 bytes .../assets/textures/items/lapis_lazuli.png | Bin 0 -> 403 bytes android/assets/textures/items/spawn_egg.png | Bin 0 -> 335 bytes android/assets/touch_gui.png | Bin 6848 -> 2625 bytes .../cavedroid/game/GameModule.java | 18 +- .../cavedroid/game/GamePhysics.java | 4 +- .../deadsoftware/cavedroid/game/GameProc.java | 8 + .../cavedroid/game/GameRenderer.java | 6 +- .../cavedroid/game/GameSaver.java | 25 ++- .../game/actions/UseBlockActionsModule.kt | 9 + .../game/actions/UseItemActionsModule.kt | 8 + .../game/actions/useblock/UseFurnaceAction.kt | 23 +++ .../actions/useitem/UsePigSpawnEggAction.kt | 27 +++ .../game/debug/DebugInfoStringsProvider.kt | 2 +- .../game/input/MouseInputHandlersModule.kt | 7 + .../CloseGameWindowKeyboardInputHandler.kt | 2 +- .../keyboard/DropItemKeyboardInputHandler.kt | 4 +- .../OpenInventoryKeyboardInputHandler.kt | 2 - .../keyboard/PauseGameKeyboardInputHandler.kt | 6 +- .../mouse/CloseGameWindowMouseInputHandler.kt | 4 +- .../handler/mouse/HotbarMouseInputHandler.kt | 4 +- ...tCraftingInventoryItemMouseInputHandler.kt | 2 +- ...ctFurnaceInventoryItemMouseInputHandler.kt | 172 ++++++++++++++++++ ...tSurvivalInventoryItemMouseInputHandler.kt | 2 +- .../cavedroid/game/mobs/player/Inventory.kt | 2 +- .../cavedroid/game/mobs/player/Player.java | 4 +- .../cavedroid/game/model/block/Block.kt | 40 +++- .../cavedroid/game/model/dto/ItemDto.kt | 3 + .../game/model/item/CommonItemParams.kt | 2 + .../game/model/item/InventoryItem.kt | 4 + .../cavedroid/game/model/item/Item.kt | 20 +- .../game/model/mapper/BlockMapper.kt | 1 + .../cavedroid/game/model/mapper/ItemMapper.kt | 12 +- .../cavedroid/game/objects/{ => drop}/Drop.kt | 2 +- .../objects/{ => drop}/DropController.java | 8 +- .../cavedroid/game/objects/furnace/Furnace.kt | 147 +++++++++++++++ .../game/objects/furnace/FurnaceController.kt | 43 +++++ .../cavedroid/game/render/BlocksRenderer.kt | 14 +- .../cavedroid/game/render/DropsRenderer.kt | 2 +- .../cavedroid/game/render/WindowsRenderer.kt | 3 + .../render/windows/FurnaceWindowRenderer.kt | 139 ++++++++++++++ .../game/ui/windows/GameWindowsConfigs.kt | 31 ++++ .../game/ui/windows/GameWindowsManager.kt | 12 +- .../inventory/FurnaceInventoryWindow.kt | 15 ++ .../cavedroid/game/world/GameWorld.java | 31 +++- .../deadsoftware/cavedroid/misc/Assets.java | 9 + .../cavedroid/misc/utils/MeasureUnitsUtils.kt | 2 +- .../cavedroid/misc/utils/RenderingUtils.kt | 27 +++ 59 files changed, 1035 insertions(+), 80 deletions(-) create mode 100644 android/assets/chest.png create mode 100644 android/assets/furnace.png create mode 100644 android/assets/textures/blocks/furnace.png delete mode 100644 android/assets/textures/blocks/furnace_off.png delete mode 100644 android/assets/textures/blocks/furnace_on.png create mode 100644 android/assets/textures/items/bed.png create mode 100644 android/assets/textures/items/diamond.png create mode 100644 android/assets/textures/items/gold_ingot.png create mode 100644 android/assets/textures/items/iron_ingot.png create mode 100644 android/assets/textures/items/lapis_lazuli.png create mode 100644 android/assets/textures/items/spawn_egg.png create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt rename core/src/ru/deadsoftware/cavedroid/game/objects/{ => drop}/Drop.kt (96%) rename core/src/ru/deadsoftware/cavedroid/game/objects/{ => drop}/DropController.java (79%) create mode 100644 core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt create mode 100644 core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt diff --git a/android/assets/chest.png b/android/assets/chest.png new file mode 100644 index 0000000000000000000000000000000000000000..961891f208d6ec2683ac56668344b7f7e5eb69b3 GIT binary patch literal 3075 zcmeHJdpK0<8eeP8Ow7n}8?@Om#Y~fHTNk9us*Ew2H0`l5VV;p&E<+85P!=JIh+;=F zR7x_4uw61dJ9ODhx=1#osE9Oe(`7`?%-Nm&bpAU3pR>Q`ThI5d_qV?Fyz716-|t%) z3|Fc;&Hx7hfI7|D@kamv6($I%q7+N$HBUFif)3iYYa0O6W~(-`S*}zz%OjM-;)aLBL`9y=Oh13FK!N@}{?5Sva0X(8YW_;1ME&T>T>SqY0P~{? zQBi8_0cTbu0Q^Iwyugsh8CZqWAd2D{#f%7yit*(I01V&Y@F*)+iW`By)@r@g4{O%Q zc%=ZK5=3*{<`&C-Q+y)7Y@;USZF*MkV&VbG)rT}VY%-?;M-J-Srd5%R?vlNRq8_H5*&Xpqa*ZmQBM|y~2w|Yg)0sEh1z~+MA_E^K+J`$AZaN zO;qe~#?{}VH3jOs7vmDYP_+oM@Mf;m4&oV4q=!%MyA?erL%w8Qm-}HS-uSh8TbtYo zO$gCop!D0s9hC(MLS*U_waME`ZaTl#*kaVIYBA3$2IJV5a2=4#61Of*s7HKbH)=i6 z9Sl3Bsw;>eMeUF{8XVWhdXd%}M>sF{!%TF&{C$qp-)ir<T?tXXV#IUgZv6%!Y0w41SLNj0IQDZ@RwZqtnz-^Hz78BKT{vMJa`S!#jgQZn zi#x*4aQ?2VLGiwLTu%A(NaOCaV0+gi(-xfgNVb2&*7^;XEC)Rhy8YRuO4B|Qnd}*O zdb+{X8%Sd#?jS|pV|{)0l_PqzSZ>pGy2p$e%sor@(YD}l=}wrX_V;%?u}$5bc>b%+ zuURm!>@151dU>g5_7ut-eC|vIxUJsl_1OE z!PzT2J24ZbfzRLVb6Y65=#8ysKWrezt7^Vus#u&cb7@e9SE14a+R<|K<(-WdlLJkK z{*68`CbL2^_VVk!Ey%MQFiZ;Wvv!$VuSm>pARL)JES*H31_{gTiV)WMFW3C|JEj$T zFV+EV22`z{S0%maY3EiHMT9=h9mf3LZzR|Z7nUq>o;UEwo3S2oDYOU2M=q$Rw_f48{M9fFgpMZ|o~Uf{=w~79tP83iT))Lgzz%D;5?Og* z_eEAPTh8o&o;&f_qFIiIHghIQPv9{| zPHxlr2Ft^W#A;$Qf#TDIJeRO&K2a^*@b*EMeVFeHWyY@WwZyw_eNZoEiKsH9{^bXC zBI@lhD(caTA={l5aYx(Y;JLt*W&Y-C!G==xp%eN!TgqTiW3jE~OhcG(hlV(t%mBW` z`{HlZ1cz?sCk@(SNSZCBl6IR#38isxh5(z{`6R8Jbu5Vh-?!XoiMCTMe|zlU;^^AC z59U<7AbS4NLc5hTm-0E=j4^rCL zv1n42?Yz*$I=SqT|4&mHdI(>ay``@2FuXsZUy`4q)P`zfcX~WLWpc7%d<{gJBPk02 zgYH2dWSE4@$+EP)(if=IgKzyh9NWq7s-WY9EvNY916!?iEC|wHjzpI|a;{GFCN-;Y zMlaO_*I$-KWJDzmNX)b?MO{85sGH9wHP?Af9t%+L=kcn)$`Z>2$pL!@W`)psqm?&= z@?Drs51IpU6XtMr*B&(Y_UzGzkJq}5HxGhd1ant#1 zEpeeDRJ58%YW`>IDp@_;MeKk^KwP?xl$3%Mh4W)O(Fvv5%g_D$Ap3N@`$A-kSFz6? z@NycoW~(J0kq4Io_japcI7jx9f!PP!!JkX?aH9Eo2JrH7>VJRa#W-}ceNpAwM}ZMH Sx6xAhV@9L6ItsUQlK%;hhk{4| literal 0 HcmV?d00001 diff --git a/android/assets/furnace.png b/android/assets/furnace.png new file mode 100644 index 0000000000000000000000000000000000000000..fc04793c8811e6d078f02d8a9933c9a1f1b9821e GIT binary patch literal 3999 zcmd5lOYoIZDh%s&{)REw;h*p)b!|^H;aprzqd)6b-kUFU%hD_18$4W zw><}lo5gSTbvy8&JE?v)1L37Q@5B;amAj-&FBTbnT)i&Lr;J-4;jORS6Pg*&8MmzkH`UXHgB*c~@E{@P# zIEzo{uG8c5S87e&X$A7+jV#Tl5$79ffh(Gt)r#lt(qsHgF&It%;`q1*t(6^wLTJXq zuSUJ~kzVGwuxGw_4ajXpUSECU!sWQH0sGgSi(Omi&9?gaBJr2j4SaSiUkHn=Y7@^O?OLXZff$ zX=ff@e$!oV*7&Fte~ot7tI6n>QC2crxKHabe)XYil-SzFx?ILC$YJDixMOv7MU*E0 ztM1YCb|lc9dTZ%r^+wsw@d9GSt_7n7H&-urI(K@q;%|aJOy3mff6v zKW(Ic-|REt;jky-&se}VR?#L<^?TW2h87H~Q$630AlB0MwdS+85D3xLObM}cA-Mkf zSfG)qhpL7Hgxfg%^MivuG4jNKd|mBKqJ80mx)?VMf#_?z(=WL`YAQO?yAevAO`_IR zpXraXuHI~^D2ZHM{3+6oc0dA=As2Vc{Ei(kuc-3+aL<#G*ZFH?adAbR`%974WKB5Z ze@$PmXT0{MAeO*%_WUmgO>ZSED)&i)_KBKy~%0&xlDP5&*tGl6RaFpPFwIc zniLA1(Th+_QfSd1(Dkn*xUm7vQ$qgOUK;IY)MO$yJsXcznMKjoi$-}?_GE3M&&CUnKFFK-Zf#FP0do6@kegk~y>-!Q#X z*(_|)e6m+~(oa5pRUm)B|LR=0j`8|5_5#ScWB7dy=5n2Y$+;pM;J$P0KozIh%KkyD zUm$Y`tV#QzoJg4;ZlUG_Uc13BPbIJs`3YNR?nWZ|d zErgt>ylR3AqXRq5|1i5x?!T#fBYZNik;Ccl%XGo`$O(LO4~Fu|R2mQpox z?a-I#RPL?f=&?#GN_&$T#i?FQ(<`mx)fzC;<49Ouj{DGetk-)qxeO0~C*k4rc!o*CDW zr!icY<#_S%y0^d0PS9#cfqb;SWx(@&wrm*Xm%`M~pMnLfl-L~CC=@?^wmbmQYED4S zVZS8JJN9N!pGOOj9K#@=RDgZfU5Cb_hs@_RP@c;}zLzS*_OIO!)$uBJ4MnVBg)9Lx z8|jr*(>!>UIaIcVUHR^<%xMO*HI|MU@?|zB^uveRWkMWG-akKDt966)cMvEAs?%gj zMK5^Q@SF6vJ+}C3fBAKNPrRZ5IhRh-A*9cCw#EeVUj~~4gz%nvg6Ud4({oD)ncakh zz(njYjGE?nTa-`WqeD=*BerDb7j{xqM(sx(ekga(gzQ?Yge^V29Ovd7M zloa~XHDj_lOX<&{LB0YdkCCRLybLa6+xa#On{Jl7*6wH5sHVS!(vj$Id6Ek~UL7

xnzdLM6Gk7weCB zu(v0^68A(p=$+0oOZSJ_4M%N%aI|@4HH>>3SU@i7oTTFFkg^7KwEK+DwgvJK<2{dm zx`-M|+M0#s2{?xd3f|iGC^;Z9R;#5wpe)bQ$#Pr9hZ;<5-6=!o@##VLHihzK&8TOr zj&PYii>{;DGtL$=Xi|ONT@{eyFLs&p&jZ4-+9#bTwF9Kf?%!UWFoU6uh7QzJ;tW%q z6BqP340l(21YAw9g9mx+oQ@E_P}r+X$30+`);|z-FvR~3hMfJ(0zjd;Rio!tMj1m% z+BD`pn7#$6t2N_h(5G`ut)_U70wH{Me~AD=>89imy*n*s<(jAXW3@HxCnNb(Sjn-m z5CZYYS}F!+*LqpSx7n&pnpkc?b;IZ9d&zaeMxu&9^AyOs(Q;BsM)&Yn@H|(Hs%H{Kn|S4LK;rsjEYf@=o0cmsFpqX50F-5@-G zJK4&L?C#XqKJ#uL)Cm{N_m|pQC;kDoZ!oJ*Y3*S;Hw*ypJ8$j5fk<}gkIyR~2#?h| zl??keB<~GL-_PPHz&6vy!1qQuj>6hF0(MXFbzXdJz=5Ff9HUoU%0ETWYL}>m_c*m6MCma6kjSk0LA% z459zTq&RTNNKvl~NsiiGy!y?v>%P8FmVHqVKb^K;NbyqF5&-0Cb;uh&N$Otdi!or9 zCdP(LdBbaq#vp$NnHFcE@a9HNwkVIfq=q;^_Mrek?8AQt)|tm_@`nV7j<)cGnoa(j zh*5~tQdH&Q%0-WGQ3cDcZ_gNf7+sUMIbZ5KhK;>0RVd9??bg;MC>UexVcBxSeZ(zK zgLATcCRoMZBh_-^h9MVtfCDDb{~6b;pjpWM6n*pC5Rs-*I3)y|mTMDxq}Wb)dZa_- zw$l;VNzer3b>`pPP?i_t$!)j~Yh#BPzkKVARp7Nf4VoyWh7Xp={qAst%7|vz~#Y#wg>t?@rYLmzm(`Lo42Hg_sr2Wz zn4Y;tLYM$_f;MZbPsv@nI)K>);Qfp55d*MgmVExQlItYdDy@@F+mvfH0Ip0;0qC4^ z&7e`;1|S-;1f3q6n}3o{+gc64g)tMy@$`GSR%0^tj#d`!1Z@Bs&6h}-#Bn@4S4j*L zUAHw*=W$_75!y0KLYTx7!o(}BQ@HpkouG~Dwg`NmrN@s(8W{o^rorFcwpI`e6};Hq zQ6s7p+1=iw=^u_1r>t=W=%SCP6$HLd;1@OH>EbY!9gHvV)!3y>Dh0x_Sh(>S085V_ zohcq(*XQN|*eb09C#v)5dJ5G_k!nR14*v_nvUKyp3l&QUlZDT}cWN5q3c(??n5SlsC@3UCR@MV0H41uqN`ucx-Gq@L<#*pY$?%jBuVG#N*7~ zyutle2ltlbci_HEGLcO1w0OX@{11NcbMZid{Zb#q;&6C;t{?mZ!*T6_@z8(_00000 LNkvXXu0mjf)T*Nk literal 0 HcmV?d00001 diff --git a/android/assets/textures/blocks/furnace_off.png b/android/assets/textures/blocks/furnace_off.png deleted file mode 100644 index 6d9b4057495c3cdf05dc7649afb5135dcdec6bca..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 387 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61SBU+%rFB|Ea{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+L6~vJ#O${~LCF%=h?3y^w370~qEv>0#LT=By}Z;C1rt33Jwt=FTwDhj7#JBm zT^vI!{7WaS=Q>m%;`Uvr$=6{0%@)?lo~t{KigvTHy9pjtFgy4_Sm!63-Q4s!^5NzI zebawG|NZXnwAl0R75iWDef=ya$k@5jFv6mv&_Q$B&22jAlQ-%-4_;jItHHurRx8UW z!2S4Cm98Y0&4vN?dEys*Hr>x{U};u9mGYqf;E4k#BsPod2v*p{ae~cFdUX$4IKzH7xut1U5 zSD8G1Jgr=J&OJ-A<4i>7t-BH(QZem1k{OL`r3b2bIsSN^OgPP*D0b?d^@s1=0nL?D e_Fu4(UB#c=uDrxi_7o_%89ZJ6T-G@yGywqfx{$&E diff --git a/android/assets/textures/blocks/furnace_on.png b/android/assets/textures/blocks/furnace_on.png deleted file mode 100644 index ecbc607a4619f76aca95e25bd9178b610db4ca4a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 450 zcmV;z0X_bSP)N2bZe?^J zG%heMF)*zP3cvsW0Y6DZK~y+TU6C znhZ8BVjZ9rw#D&iw9{*ga@e#3|1Ca)|gGOMPPVNQ1NjwU`qXb*aZ*_R910rN-&EBqhV(Yl>M%NGkiH5a3Ulp zV4zXG*=+7FFM_L$B`R%l&ILJvT)-4Vs9zfka)t`PZvr>_dMY)j{_d?A!q96VO9m3m zVoLh@%4!V^xr49t&%l%&ry{D3TGe|SLaU+vAF!s-xqR diff --git a/android/assets/textures/items/bed.png b/android/assets/textures/items/bed.png new file mode 100644 index 0000000000000000000000000000000000000000..0e1565dfd65ee905dade309d773ee9d004ad7b73 GIT binary patch literal 371 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL8%hgh?3y^w370~qEv=}#LT=BJwMkFg)(D3 zQ$0gN_s>q|Kvj=CT^vI!{O3+Gm@ndl)i!cEUF#Pho}zhl6tScI9jiHHIV18Opw) z9M=!BY);(IkYSwfthU57YU;9240opcvb>lzL4l#QEkl`^;md;Q58vGP7iu!dcyhS2 zOERa!?Kwm<*n- KelF{r5}E*#1cpKY literal 0 HcmV?d00001 diff --git a/android/assets/textures/items/diamond.png b/android/assets/textures/items/diamond.png new file mode 100644 index 0000000000000000000000000000000000000000..eff11e002151df88d5761136544bc6d6051e2c0b GIT binary patch literal 270 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`Ea{HEjtmSN`?>!lvI6;>1s;*b z3=Dh+L6~vJ#O${~L5ULAh?3y^w370~qEv>0#LT=By}Z;C1rt33J+nVO$@hV3dOTem zLoEE0Ip)<(P&)JB|Nr_;A3cm0{JE2F;3jrB+u_eH>Hm&5mKW zYxq_(D)1^iKg`3JIKkosLrHjoDZ>(hmWxL>Caz(d(8S)%$S%q7BH@yj-}4_EfbL@O MboFyt=akR{0KXw&CjbBd literal 0 HcmV?d00001 diff --git a/android/assets/textures/items/gold_ingot.png b/android/assets/textures/items/gold_ingot.png new file mode 100644 index 0000000000000000000000000000000000000000..b1594550012c43ec7fcf067dd276d87b720667ec GIT binary patch literal 315 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|SkfJR9T^xl z_H+M9WCij$3p^r=85sBugD~Uq{1qucL8%hgh?3y^w370~qEv=}#LT=BJwMkFg)(D3 zQ$0figD*u3fvQ${x;Tbd_$MbUVEs|Q^NT&l2ExnB^$tD3Nkv z5|`>Do}HWSh~#OXVUX~hqNs4xVE^G5CSws7VH1`V1`oj#Hx+nqeApr)dgopyzc7yG|DPAR4!hC>G8fhinkq!kW3!lvI6;>1s;*b z3=Dh+L6~vJ#O${~L8%hgh?3y^w370~qEv=}#LT=BJwMkFg)(D3Q$0figD*u3fvVNQGoE#j17+RV9(QCjb;@9|s@j|KKO7$zvqxW6&6sjWdIMg91}zkR&I zCM+oo9Ea!d8S%IsHn`Z9P|WGUqrx8AC%a%bORTYn+$s@shjLEOS&0lc1tysuX7CW^ gac*6~Dj~se`jYVdB(B0rpi>z!lvI6;>1s;*b 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 aK>QC!DXvb literal 6848 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 diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameModule.java b/core/src/ru/deadsoftware/cavedroid/game/GameModule.java index fbbd294..2385230 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameModule.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameModule.java @@ -5,7 +5,8 @@ import dagger.Provides; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.model.block.Block; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; import ru.deadsoftware.cavedroid.game.ui.TooltipManager; import ru.deadsoftware.cavedroid.game.world.GameWorld; @@ -43,6 +44,16 @@ public class GameModule { return controller; } + @Provides + @GameScope + public static FurnaceController provideFurnaceController(MainConfig mainConfig, GameItemsHolder gameItemsHolder) { + load(mainConfig, gameItemsHolder); + FurnaceController controller = data != null ? data.retrueveFurnaceController() : new FurnaceController(); + makeDataNullIfEmpty(); + controller.init(gameItemsHolder); + return controller; + } + @Provides @GameScope public static MobsController provideMobsController(MainConfig mainConfig, @@ -62,12 +73,13 @@ public class GameModule { public static GameWorld provideGameWorld(MainConfig mainConfig, DropController dropController, MobsController mobsController, - GameItemsHolder gameItemsHolder) { + GameItemsHolder gameItemsHolder, + FurnaceController furnaceController) { load(mainConfig, gameItemsHolder); Block[][] fm = data != null ? data.retrieveForeMap() : null; Block[][] bm = data != null ? data.retrieveBackMap() : null; makeDataNullIfEmpty(); - return new GameWorld(dropController, mobsController, gameItemsHolder, fm, bm); + return new GameWorld(dropController, mobsController, gameItemsHolder, furnaceController, fm, bm); } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java b/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java index eee83c7..aebf8eb 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GamePhysics.java @@ -9,8 +9,8 @@ import ru.deadsoftware.cavedroid.game.mobs.Mob; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.mobs.player.Player; import ru.deadsoftware.cavedroid.game.model.block.Block; -import ru.deadsoftware.cavedroid.game.objects.Drop; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.Drop; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; import ru.deadsoftware.cavedroid.game.world.GameWorld; import javax.annotation.CheckForNull; diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java index d797680..a3fcabb 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameProc.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameProc.java @@ -6,6 +6,7 @@ import com.badlogic.gdx.utils.Timer; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.mobs.player.Player; +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; import ru.deadsoftware.cavedroid.game.world.GameWorldBlocksLogicControllerTask; import ru.deadsoftware.cavedroid.game.world.GameWorldFluidsLogicControllerTask; import ru.deadsoftware.cavedroid.game.world.GameWorldMobDamageControllerTask; @@ -18,6 +19,8 @@ public class GameProc implements Disposable { private final GamePhysics mGamePhysics; private final GameRenderer mGameRenderer; private final MobsController mMobsController; + private final FurnaceController mFurnaceController; + private final GameItemsHolder mGameItemsHolder; private final GameWorldFluidsLogicControllerTask mGameWorldFluidsLogicControllerTask; private final GameWorldBlocksLogicControllerTask mGameWorldBlocksLogicControllerTask; private final GameWorldMobDamageControllerTask mGameWorldMobDamageControllerTask; @@ -29,6 +32,8 @@ public class GameProc implements Disposable { GamePhysics gamePhysics, GameRenderer gameRenderer, MobsController mobsController, + FurnaceController furnaceController, + GameItemsHolder gameItemsHolder, GameWorldFluidsLogicControllerTask gameWorldFluidsLogicControllerTask, GameWorldBlocksLogicControllerTask gameWorldBlocksLogicControllerTask, GameWorldMobDamageControllerTask gameWorldMobDamageControllerTask @@ -36,6 +41,8 @@ public class GameProc implements Disposable { mGamePhysics = gamePhysics; mGameRenderer = gameRenderer; mMobsController = mobsController; + mFurnaceController = furnaceController; + mGameItemsHolder = gameItemsHolder; mGameWorldFluidsLogicControllerTask = gameWorldFluidsLogicControllerTask; mGameWorldBlocksLogicControllerTask = gameWorldBlocksLogicControllerTask; mGameWorldMobDamageControllerTask = gameWorldMobDamageControllerTask; @@ -57,6 +64,7 @@ public class GameProc implements Disposable { public void update(float delta) { mGamePhysics.update(delta); mGameRenderer.render(delta); + mFurnaceController.update(mGameItemsHolder); } public void show() { diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java index 36f6c75..2ae4756 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameRenderer.java @@ -109,7 +109,9 @@ public class GameRenderer extends Renderer { float camTargetX, camTargetY; - if (player.controlMode == Player.ControlMode.WALK) { + boolean followPlayer = player.controlMode == Player.ControlMode.WALK || !mMainConfig.isTouch(); + + if (followPlayer) { camTargetX = plTargetX + Math.min(player.getVelocity().x * 2, getWidth() / 2); camTargetY = plTargetY + player.getVelocity().y; } else { @@ -119,7 +121,7 @@ public class GameRenderer extends Renderer { Vector2 moveVector = new Vector2(camTargetX - camCenterX, camTargetY - camCenterY); - if (player.controlMode == Player.ControlMode.WALK && player.getVelocity().isZero()) { + if (followPlayer && player.getVelocity().isZero()) { mCameraDelayMs = TimeUtils.millis(); mCamCenterToPlayer.x = plTargetX - camCenterX; mCamCenterToPlayer.y = plTargetY - camCenterY; diff --git a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java index cb52b3c..dd16186 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java +++ b/core/src/ru/deadsoftware/cavedroid/game/GameSaver.java @@ -5,7 +5,8 @@ import com.badlogic.gdx.files.FileHandle; import ru.deadsoftware.cavedroid.MainConfig; import ru.deadsoftware.cavedroid.game.mobs.MobsController; import ru.deadsoftware.cavedroid.game.model.block.Block; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; import ru.deadsoftware.cavedroid.game.world.GameWorld; import javax.annotation.CheckForNull; @@ -24,11 +25,18 @@ public class GameSaver { @CheckForNull private DropController mDropController; @CheckForNull + private FurnaceController mFurnaceController; + @CheckForNull private Block[][] mForeMap, mBackMap; - public Data(MobsController mobsController, DropController dropController, Block[][] foreMap, Block[][] backMap) { + public Data(MobsController mobsController, + DropController dropController, + FurnaceController furnaceController, + Block[][] foreMap, + Block[][] backMap) { mMobsController = mobsController; mDropController = dropController; + mFurnaceController = furnaceController; mForeMap = foreMap; mBackMap = backMap; } @@ -47,6 +55,13 @@ public class GameSaver { return dropController; } + public FurnaceController retrueveFurnaceController() { + assert mFurnaceController != null; + FurnaceController furnaceController = mFurnaceController; + mFurnaceController = null; + return furnaceController; + } + public Block[][] retrieveForeMap() { assert mForeMap != null; Block[][] foreMap = mForeMap; @@ -183,10 +198,12 @@ public class GameSaver { int version = in.readInt(); DropController dropController; MobsController mobsController; + FurnaceController furnaceController; if (SAVE_VERSION == version) { dropController = (DropController) in.readObject(); mobsController = (MobsController) in.readObject(); + furnaceController = (FurnaceController) in.readObject(); } else { throw new Exception("version mismatch"); } @@ -201,7 +218,7 @@ public class GameSaver { throw new Exception("couldn't load"); } - return new Data(mobsController, dropController, foreMap, backMap); + return new Data(mobsController, dropController, furnaceController, foreMap, backMap); } catch (Exception e) { Gdx.app.error("GameSaver", e.getMessage()); } @@ -212,6 +229,7 @@ public class GameSaver { public static void save(MainConfig mainConfig, DropController dropController, MobsController mobsController, + FurnaceController furnaceController, GameWorld gameWorld) { String folder = mainConfig.getGameFolder(); FileHandle file = Gdx.files.absolute(folder + "/saves/"); @@ -229,6 +247,7 @@ public class GameSaver { out.writeInt(SAVE_VERSION); out.writeObject(dropController); out.writeObject(mobsController); + out.writeObject(furnaceController); out.close(); saveDict(Gdx.files.absolute(folder + "/saves/dict"), dict); diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt index 76127fa..5b2a169 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/UseBlockActionsModule.kt @@ -7,6 +7,7 @@ import dagger.multibindings.StringKey import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.actions.useblock.IUseBlockAction import ru.deadsoftware.cavedroid.game.actions.useblock.UseCraftingTableAction +import ru.deadsoftware.cavedroid.game.actions.useblock.UseFurnaceAction @Module class UseBlockActionsModule { @@ -18,4 +19,12 @@ class UseBlockActionsModule { fun bindUseCraftingTableAction(action: UseCraftingTableAction): IUseBlockAction { return action } + + @Binds + @IntoMap + @StringKey(UseFurnaceAction.KEY) + @GameScope + fun bindUseFurnaceTableAction(action: UseFurnaceAction): IUseBlockAction { + return action + } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt index 0206d5f..a6aed22 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/UseItemActionsModule.kt @@ -34,4 +34,12 @@ class UseItemActionsModule { return action } + @Binds + @IntoMap + @StringKey(UsePigSpawnEggAction.ACTION_KEY) + @GameScope + fun bindUsePigSpawnEgg(action: UsePigSpawnEggAction): IUseItemAction { + return action + } + } diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt new file mode 100644 index 0000000..88a6a7f --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useblock/UseFurnaceAction.kt @@ -0,0 +1,23 @@ +package ru.deadsoftware.cavedroid.game.actions.useblock + +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.model.block.Block +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import javax.inject.Inject + +@GameScope +class UseFurnaceAction @Inject constructor( + private val furnaceController: FurnaceController, + private val gameWindowsManager: GameWindowsManager, +) : IUseBlockAction { + + override fun perform(block: Block, x: Int, y: Int) { + val furnace = furnaceController.getFurnace(x, y, 0) ?: furnaceController.getFurnace(x, y, 1) ?: return + gameWindowsManager.openFurnace(furnace) + } + + companion object { + const val KEY = "furnace" + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt new file mode 100644 index 0000000..0c50d15 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/actions/useitem/UsePigSpawnEggAction.kt @@ -0,0 +1,27 @@ +package ru.deadsoftware.cavedroid.game.actions.useitem + +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.mobs.Pig +import ru.deadsoftware.cavedroid.game.model.item.Item +import ru.deadsoftware.cavedroid.misc.utils.px +import javax.inject.Inject + +@GameScope +class UsePigSpawnEggAction @Inject constructor( + private val mobsController: MobsController, +) : IUseItemAction { + + override fun perform(item: Item.Usable, x: Int, y: Int) { + Pig(mobsController.player.cursorX.px, mobsController.player.cursorY.px) + .apply { + attachToController(mobsController) + } + + mobsController.player.inventory.decreaseCurrentItemAmount() + } + + companion object { + const val ACTION_KEY = "use_spawn_egg_pig" + } +} diff --git a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt index 0886a07..df1dd06 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/debug/DebugInfoStringsProvider.kt @@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.debug import com.badlogic.gdx.Gdx import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt index 3d5f32a..fe9bba6 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/MouseInputHandlersModule.kt @@ -74,6 +74,13 @@ object MouseInputHandlersModule { return handler } + @Binds + @IntoSet + @GameScope + fun bindSelectFurnaceInventoryItemMouseInputHandler(handler: SelectFurnaceInventoryItemMouseInputHandler): IGameInputHandler { + return handler + } + @Binds @IntoSet @GameScope diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt index 6a8f019..89a7b69 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/CloseGameWindowKeyboardInputHandler.kt @@ -6,7 +6,7 @@ import ru.deadsoftware.cavedroid.game.input.IGameInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt index b46812c..04f5520 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/DropItemKeyboardInputHandler.kt @@ -7,8 +7,8 @@ import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.Item -import ru.deadsoftware.cavedroid.game.objects.Drop -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.Drop +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt index ce70054..ec8190a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/OpenInventoryKeyboardInputHandler.kt @@ -5,8 +5,6 @@ import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.input.IGameInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey -import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt index 60a9edf..8ba35c1 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/keyboard/PauseGameKeyboardInputHandler.kt @@ -7,7 +7,8 @@ import ru.deadsoftware.cavedroid.game.input.IGameInputHandler import ru.deadsoftware.cavedroid.game.input.action.KeyboardInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.KeyboardInputActionKey import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController import ru.deadsoftware.cavedroid.game.world.GameWorld import javax.inject.Inject @@ -17,6 +18,7 @@ class PauseGameKeyboardInputHandler @Inject constructor( private val dropController: DropController, private val mobsController: MobsController, private val gameWorld: GameWorld, + private val furnaceController: FurnaceController, ) : IGameInputHandler { override fun checkConditions(action: KeyboardInputAction): Boolean { @@ -24,7 +26,7 @@ class PauseGameKeyboardInputHandler @Inject constructor( } override fun handle(action: KeyboardInputAction) { - GameSaver.save(mainConfig, dropController, mobsController, gameWorld) + GameSaver.save(mainConfig, dropController, mobsController, furnaceController, gameWorld) mainConfig.caveGame.quitGame() } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt index ffda344..ddc41e2 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/CloseGameWindowMouseInputHandler.kt @@ -9,7 +9,7 @@ import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject @@ -23,6 +23,7 @@ class CloseGameWindowMouseInputHandler @Inject constructor( private val creativeInventoryTexture get() = requireNotNull(Assets.textureRegions["creative"]) private val survivalInventoryTexture get() = requireNotNull(Assets.textureRegions["survival"]) private val craftingInventoryTexture get() = requireNotNull(Assets.textureRegions["crafting_table"]) + private val furnaceInventoryTexture get() = requireNotNull(Assets.textureRegions["furnace"]) override fun checkConditions(action: MouseInputAction): Boolean { return gameWindowsManager.getCurrentWindow() != GameUiWindow.NONE && @@ -36,6 +37,7 @@ class CloseGameWindowMouseInputHandler @Inject constructor( GameUiWindow.CREATIVE_INVENTORY -> creativeInventoryTexture GameUiWindow.SURVIVAL_INVENTORY -> survivalInventoryTexture GameUiWindow.CRAFTING_TABLE -> craftingInventoryTexture + GameUiWindow.FURNACE -> furnaceInventoryTexture else -> throw UnsupportedOperationException("Cant close window ${window.name}") } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt index 6b86c8b..18cd41d 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/HotbarMouseInputHandler.kt @@ -12,8 +12,8 @@ import ru.deadsoftware.cavedroid.game.input.isInsideHotbar import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.mobs.player.Player import ru.deadsoftware.cavedroid.game.model.item.Item -import ru.deadsoftware.cavedroid.game.objects.Drop -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.Drop +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.misc.Assets import javax.inject.Inject diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt index 1b4838a..32c7a43 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectCraftingInventoryItemMouseInputHandler.kt @@ -10,7 +10,7 @@ import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.InventoryItem -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CraftingInventoryWindow diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt new file mode 100644 index 0000000..839135e --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectFurnaceInventoryItemMouseInputHandler.kt @@ -0,0 +1,172 @@ +package ru.deadsoftware.cavedroid.game.input.handler.mouse + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.utils.TimeUtils +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.input.IGameInputHandler +import ru.deadsoftware.cavedroid.game.input.action.MouseInputAction +import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey +import ru.deadsoftware.cavedroid.game.input.isInsideWindow +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.FurnaceInventoryWindow +import ru.deadsoftware.cavedroid.misc.Assets +import javax.inject.Inject + +@GameScope +class SelectFurnaceInventoryItemMouseInputHandler @Inject constructor( + private val gameWindowsManager: GameWindowsManager, + private val mobsController: MobsController, + private val gameItemsHolder: GameItemsHolder, + private val dropController: DropController, +) : IGameInputHandler { + + private val survivalWindowTexture get() = requireNotNull(Assets.textureRegions["survival"]) + + override fun checkConditions(action: MouseInputAction): Boolean { + return gameWindowsManager.getCurrentWindow() == GameUiWindow.FURNACE && + isInsideWindow(action, survivalWindowTexture) && + (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Right || action.actionKey is MouseInputActionKey.Screen) + && (action.actionKey.touchUp || action.actionKey is MouseInputActionKey.Screen) + } + + private fun handleInsideInventoryGrid(action: MouseInputAction, xOnGrid: Int, yOnGrid: Int) { + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + var itemIndex = ((xOnGrid.toInt() + yOnGrid.toInt() * GameWindowsConfigs.Furnace.itemsInRow)) + itemIndex += GameWindowsConfigs.Furnace.hotbarCells + + if (itemIndex >= mobsController.player.inventory.size) { + itemIndex -= mobsController.player.inventory.size + } + + if (action.actionKey is MouseInputActionKey.Screen) { + if (!action.actionKey.touchUp) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex, action.actionKey.pointer) + } else { + if (action.actionKey.pointer == window.selectItemPointer) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex, action.actionKey.pointer) + } else { + window.onRightClick(mobsController.player.inventory.items as MutableList, itemIndex) + } + } + } else if (action.actionKey is MouseInputActionKey.Left) { + window.onLeftCLick(mobsController.player.inventory.items as MutableList, gameItemsHolder, itemIndex) + } else { + window.onRightClick(mobsController.player.inventory.items as MutableList, itemIndex) + } + + Gdx.app.debug( + TAG, + "selected item: ${window.selectedItem?.item?.params?.key ?: "null"}; index $itemIndex, grid ($xOnGrid;$yOnGrid)" + ) + } + + private fun handleInsideFuel(action: MouseInputAction) { + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + if (!window.selectedItem.isNoneOrNull() && window.selectedItem?.item?.params?.burningTimeMs == null) { + return + } + + if (action.actionKey is MouseInputActionKey.Screen) { + if (!action.actionKey.touchUp) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX, action.actionKey.pointer) + } else { + if (action.actionKey.pointer == window.selectItemPointer) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX, action.actionKey.pointer) + } else { + window.onRightClick(window.furnace.items, Furnace.FUEL_INDEX) + } + } + } else if (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Screen) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.FUEL_INDEX) + } else { + window.onRightClick(window.furnace.items, Furnace.FUEL_INDEX) + } + } + + private fun handleInsideInput(action: MouseInputAction) { + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + if (action.actionKey is MouseInputActionKey.Screen) { + if (!action.actionKey.touchUp) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX, action.actionKey.pointer) + } else { + if (action.actionKey.pointer == window.selectItemPointer) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX, action.actionKey.pointer) + } else { + window.onRightClick(window.furnace.items, Furnace.INPUT_INDEX) + } + } + } else if (action.actionKey is MouseInputActionKey.Left || action.actionKey is MouseInputActionKey.Screen) { + window.onLeftCLick(window.furnace.items, gameItemsHolder, Furnace.INPUT_INDEX) + } else { + window.onRightClick(window.furnace.items, Furnace.INPUT_INDEX) + } + } + + override fun handle(action: MouseInputAction) { + val survivalTexture = survivalWindowTexture + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + val xOnWindow = action.screenX - (action.cameraViewport.width / 2 - survivalTexture.regionWidth / 2) + val yOnWindow = action.screenY - (action.cameraViewport.height / 2 - survivalTexture.regionHeight / 2) + + val xOnGrid = (xOnWindow - GameWindowsConfigs.Furnace.itemsGridMarginLeft) / + GameWindowsConfigs.Furnace.itemsGridColWidth + val yOnGrid = (yOnWindow - GameWindowsConfigs.Furnace.itemsGridMarginTop) / + GameWindowsConfigs.Furnace.itemsGridRowHeight + + val isInsideInput = xOnWindow > GameWindowsConfigs.Furnace.smeltInputMarginLeft && + xOnWindow < GameWindowsConfigs.Furnace.smeltInputMarginLeft + GameWindowsConfigs.Furnace.itemsGridColWidth && + yOnWindow > GameWindowsConfigs.Furnace.smeltInputMarginTop && + yOnWindow < GameWindowsConfigs.Furnace.smeltInputMarginTop + GameWindowsConfigs.Furnace.itemsGridRowHeight + + val isInsideFuel = xOnWindow > GameWindowsConfigs.Furnace.smeltFuelMarginLeft && + xOnWindow < GameWindowsConfigs.Furnace.smeltFuelMarginLeft + GameWindowsConfigs.Furnace.itemsGridColWidth && + yOnWindow > GameWindowsConfigs.Furnace.smeltFuelMarginTop && + yOnWindow < GameWindowsConfigs.Furnace.smeltFuelMarginTop + GameWindowsConfigs.Furnace.itemsGridRowHeight + + val isInsideResult = xOnWindow > GameWindowsConfigs.Furnace.smeltResultOffsetX && + xOnWindow < GameWindowsConfigs.Furnace.smeltResultOffsetX + GameWindowsConfigs.Furnace.itemsGridColWidth && + yOnWindow > GameWindowsConfigs.Furnace.smeltResultOffsetY && + yOnWindow < GameWindowsConfigs.Furnace.smeltResultOffsetY + GameWindowsConfigs.Furnace.itemsGridRowHeight + + val isInsideInventoryGrid = xOnGrid >= 0 && xOnGrid < GameWindowsConfigs.Furnace.itemsInRow && + yOnGrid >= 0 && yOnGrid < GameWindowsConfigs.Furnace.itemsInCol + + if (isInsideInventoryGrid) { + handleInsideInventoryGrid(action, xOnGrid.toInt(), yOnGrid.toInt()) + } else if (isInsideFuel) { + handleInsideFuel(action) + } else if (isInsideInput) { + handleInsideInput(action) + } else if (isInsideResult && action.actionKey.touchUp) { + val selectedItem = window.selectedItem + if (selectedItem == null || selectedItem.item.isNone() || + (selectedItem.item == window.furnace.result?.item && selectedItem.amount + (window.furnace.result?.amount ?: 0) <= selectedItem.item.params.maxStack)) { + + if (selectedItem != null && !selectedItem.item.isNone()) { + selectedItem.amount += (window.furnace.result?.amount ?: 0) + } else { + window.selectedItem = window.furnace.result + } + window.furnace.items[Furnace.RESULT_INDEX] = null + } + } + + } + + companion object { + private const val TAG = "SelectFurnaceInventoryItemMouseInputHandler" + + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt index 91ec311..263d59e 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/input/handler/mouse/SelectSurvivalInventoryItemMouseInputHandler.kt @@ -10,7 +10,7 @@ import ru.deadsoftware.cavedroid.game.input.action.keys.MouseInputActionKey import ru.deadsoftware.cavedroid.game.input.isInsideWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController import ru.deadsoftware.cavedroid.game.model.item.InventoryItem -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt index 8ce9592..c5e10d0 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Inventory.kt @@ -3,7 +3,7 @@ package ru.deadsoftware.cavedroid.game.mobs.player import ru.deadsoftware.cavedroid.game.GameItemsHolder import ru.deadsoftware.cavedroid.game.model.item.InventoryItem import ru.deadsoftware.cavedroid.game.model.item.Item -import ru.deadsoftware.cavedroid.game.objects.Drop +import ru.deadsoftware.cavedroid.game.objects.drop.Drop import ru.deadsoftware.cavedroid.game.ui.TooltipManager import java.io.Serializable diff --git a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java index 5fcfe31..40b7c79 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java +++ b/core/src/ru/deadsoftware/cavedroid/game/mobs/player/Player.java @@ -9,8 +9,8 @@ import ru.deadsoftware.cavedroid.game.mobs.Mob; import ru.deadsoftware.cavedroid.game.model.block.Block; import ru.deadsoftware.cavedroid.game.model.item.InventoryItem; import ru.deadsoftware.cavedroid.game.model.item.Item; -import ru.deadsoftware.cavedroid.game.objects.Drop; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.Drop; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; import ru.deadsoftware.cavedroid.game.ui.TooltipManager; import ru.deadsoftware.cavedroid.game.world.GameWorld; import ru.deadsoftware.cavedroid.misc.Assets; diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt b/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt index 76c6ac5..2e268d0 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/block/Block.kt @@ -20,14 +20,14 @@ sealed class Block { val spriteWidth: Float get() = 16f - params.spriteMargins.left - params.spriteMargins.right val spriteHeight: Float get() = 16f - params.spriteMargins.top - params.spriteMargins.bottom - private var animation: Array? = null + protected var animation: Array? = null private var _sprite: Sprite? = null get() { return animation?.get(currentAnimationFrame) ?: field } - val sprite: Sprite + open val sprite: Sprite get() = requireNotNull(_sprite) { "null sprite for block '${params.key}'" } private val currentAnimationFrame: Int @@ -111,6 +111,11 @@ sealed class Block { return this is Slab } + fun isFurnace(): Boolean { + contract { returns(true) implies (this@Block is Furnace) } + return this is Furnace + } + fun isNone(): Boolean { contract { returns(true) implies (this@Block is None) } return this is None @@ -133,6 +138,37 @@ sealed class Block { override val params: CommonBlockParams, ) : Block() + data class Furnace( + override val params: CommonBlockParams, + ): Block() { + + override val sprite: Sprite + get() = getSprite(false) + + private fun getSprite(isActive: Boolean): Sprite { + return animation?.let { animation -> + if (isActive) { + animation[1] + } else { + animation[0] + } + } ?: sprite + } + + fun draw(spriter: SpriteBatch, x: Float, y: Float, isActive: Boolean) { + getSprite(isActive).apply { + setBounds( + /* x = */ x + params.spriteMargins.left, + /* y = */ y + params.spriteMargins.top, + /* width = */ spriteWidth, + /* height = */ spriteHeight + ) + draw(spriter) + } + } + + } + data class Slab( override val params: CommonBlockParams, val fullBlockKey: String, diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/dto/ItemDto.kt b/core/src/ru/deadsoftware/cavedroid/game/model/dto/ItemDto.kt index f3c0544..373db46 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/dto/ItemDto.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/dto/ItemDto.kt @@ -17,4 +17,7 @@ data class ItemDto( @SerialName("bottom_slab_block") val bottomSlabBlock: String? = null, @SerialName("tool_level") val toolLevel: Int? = null, @SerialName("max_stack") val maxStack: Int = 64, + @SerialName("tint") val tint: String? = null, + @SerialName("burning_time") val burningTime: Long? = null, + @SerialName("smelt_product") val smeltProduct: String? = null, ) diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt index 0330a36..00af08b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/item/CommonItemParams.kt @@ -7,4 +7,6 @@ data class CommonItemParams( val name: String, val inHandSpriteOrigin: SpriteOrigin, val maxStack: Int, + val burningTimeMs: Long?, + val smeltProductKey: String?, ) \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt index 7652243..acc0d29 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/item/InventoryItem.kt @@ -4,6 +4,7 @@ import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.mobs.player.Inventory import ru.deadsoftware.cavedroid.misc.Assets import ru.deadsoftware.cavedroid.misc.utils.drawSprite import ru.deadsoftware.cavedroid.misc.utils.drawString @@ -119,4 +120,7 @@ class InventoryItem @JvmOverloads constructor( } } + companion object { + fun InventoryItem?.isNoneOrNull() = this?.item == null || this.item.isNone() + } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt b/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt index 1e6755a..bf2a55c 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/item/Item.kt @@ -46,8 +46,8 @@ sealed class Item { } fun isUsable(): Boolean { - contract { returns(true) implies (this@Item is Placeable) } - return this is Placeable + contract { returns(true) implies (this@Item is Usable) } + return this is Usable } @JvmOverloads @@ -66,10 +66,6 @@ sealed class Item { abstract val level: Int } - sealed class Usable : Item() { - abstract val useActionKey: String - } - sealed class Placeable : Item() { abstract val block: BlockModel override val sprite: Sprite get() = block.sprite @@ -82,6 +78,12 @@ sealed class Item { get() = throw IllegalAccessException("Trying to get sprite of None") } + data class Usable( + override val params: CommonItemParams, + override val sprite: Sprite, + val useActionKey: String + ) : Item() + data class Block( override val params: CommonItemParams, override val block: BlockModel @@ -134,11 +136,5 @@ sealed class Item { override val blockDamageMultiplier: Float, override val level: Int, ) : Tool() - - data class Bucket( - override val params: CommonItemParams, - override val sprite: Sprite, - override val useActionKey: String - ) : Usable() } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt index f45451f..2ec9727 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/BlockMapper.kt @@ -23,6 +23,7 @@ class BlockMapper @Inject constructor( "water" -> Water(commonBlockParams, requireNotNull(dto.state)) "lava" -> Lava(commonBlockParams, requireNotNull(dto.state)) "slab" -> Slab(commonBlockParams, requireNotNull(dto.fullBlock), requireNotNull(dto.otherPart)) + "furnace" -> Furnace(commonBlockParams) "none" -> None(commonBlockParams) else -> Normal(commonBlockParams) } diff --git a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/ItemMapper.kt b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/ItemMapper.kt index 4557cc8..a0949a0 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/model/mapper/ItemMapper.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/model/mapper/ItemMapper.kt @@ -11,6 +11,7 @@ import ru.deadsoftware.cavedroid.game.model.item.Item.* import ru.deadsoftware.cavedroid.misc.Assets import ru.deadsoftware.cavedroid.misc.utils.AssetLoader import ru.deadsoftware.cavedroid.misc.utils.SpriteOrigin +import ru.deadsoftware.cavedroid.misc.utils.colorFromHexString import javax.inject.Inject @Reusable @@ -23,7 +24,7 @@ class ItemMapper @Inject constructor( return when (dto.type) { "normal" -> Normal(params, requireNotNull(loadSprite(dto))) - "bucket" -> Bucket(params, requireNotNull(loadSprite(dto)), requireNotNull(dto.actionKey)) + "usable" -> Usable(params, requireNotNull(loadSprite(dto)), requireNotNull(dto.actionKey)) "shovel" -> Shovel(params, requireNotNull(loadSprite(dto)), dto.mobDamageMultiplier, dto.blockDamageMultiplier, requireNotNull(dto.toolLevel)) "sword" -> Sword(params, requireNotNull(loadSprite(dto)), dto.mobDamageMultiplier, dto.blockDamageMultiplier, requireNotNull(dto.toolLevel)) "pickaxe" -> Pickaxe(params, requireNotNull(loadSprite(dto)), dto.mobDamageMultiplier, dto.blockDamageMultiplier, requireNotNull(dto.toolLevel)) @@ -45,6 +46,8 @@ class ItemMapper @Inject constructor( y = dto.origin_y, ), maxStack = dto.maxStack, + burningTimeMs = dto.burningTime, + smeltProductKey = dto.smeltProduct, ) } @@ -55,7 +58,12 @@ class ItemMapper @Inject constructor( val texture = Assets.resolveItemTexture(assetLoader, dto.texture) return Sprite(texture) - .apply { flip(false, true) } + .apply { + flip(false, true) + dto.tint?.let { + color = colorFromHexString(it) + } + } } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/Drop.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/Drop.kt similarity index 96% rename from core/src/ru/deadsoftware/cavedroid/game/objects/Drop.kt rename to core/src/ru/deadsoftware/cavedroid/game/objects/drop/Drop.kt index f67c66c..9099864 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/objects/Drop.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/Drop.kt @@ -1,4 +1,4 @@ -package ru.deadsoftware.cavedroid.game.objects +package ru.deadsoftware.cavedroid.game.objects.drop import com.badlogic.gdx.math.Intersector import com.badlogic.gdx.math.Rectangle diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java similarity index 79% rename from core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java rename to core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java index e111f9c..6666fc8 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/objects/DropController.java +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/drop/DropController.java @@ -1,7 +1,9 @@ -package ru.deadsoftware.cavedroid.game.objects; +package ru.deadsoftware.cavedroid.game.objects.drop; +import org.jetbrains.annotations.NotNull; import ru.deadsoftware.cavedroid.game.GameItemsHolder; import ru.deadsoftware.cavedroid.game.GameScope; +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem; import ru.deadsoftware.cavedroid.game.model.item.Item; import javax.inject.Inject; @@ -37,6 +39,10 @@ public class DropController implements Serializable { mDrops.add(new Drop(x, y, item, count)); } + public void addDrop(float x, float y, @NotNull InventoryItem invItem) { + addDrop(x, y, invItem.getItem(), invItem.getAmount()); + } + public int getSize() { return mDrops.size(); } diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt new file mode 100644 index 0000000..a6915ef --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/Furnace.kt @@ -0,0 +1,147 @@ +package ru.deadsoftware.cavedroid.game.objects.furnace + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.math.MathUtils +import com.badlogic.gdx.utils.TimeUtils +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem.Companion.isNoneOrNull +import ru.deadsoftware.cavedroid.game.model.item.Item +import java.io.Serializable + +class Furnace : Serializable { + + val items = MutableList(3) { null } + + var fuel: InventoryItem? + get() = items[FUEL_INDEX] + set(value) { + items[FUEL_INDEX] = value + } + + var input: InventoryItem? + get() = items[INPUT_INDEX] + set(value) { + items[INPUT_INDEX] = value + } + + var result: InventoryItem? + get() = items[RESULT_INDEX] + set(value) { + items[RESULT_INDEX] = value + } + + val isActive: Boolean get() = currentFuel != null + + @Transient + var currentFuel: Item? = null + set(value) { + currentFuelKey = value?.params?.key + field = value + } + + var currentFuelKey: String? = null + + private var startBurnTimeMs = 0L + private var smeltStarTimeMs = 0L + + var burnProgress = 0f + private set(value) { + field = MathUtils.clamp(value, 0f, 1f) + } + var smeltProgress = 0f + private set(value) { + field = MathUtils.clamp(value, 0f, 1f) + } + + fun init(gameItemsHolder: GameItemsHolder) { + currentFuel = currentFuelKey?.let { gameItemsHolder.getItem(it) } + items.forEach { it?.init(gameItemsHolder) } + } + + fun canSmelt(): Boolean { + return (result.isNoneOrNull() || (result?.item?.params?.key == input?.item?.params?.smeltProductKey) )&& + !input.isNoneOrNull() && input?.item?.params?.smeltProductKey != null && + (!fuel.isNoneOrNull() || burnProgress > 0f) + } + + private fun startBurning() { + requireNotNull(fuel?.item?.params?.burningTimeMs) { "Cant start burning without fuel" } + currentFuel = fuel!!.item + fuel!!.subtract() + if (fuel!!.amount <= 0) { + fuel = null + } + startBurnTimeMs = TimeUtils.millis() + burnProgress = 0f + } + + fun update(gameItemsHolder: GameItemsHolder) { + if (currentFuel?.isNone() == true) { + currentFuel = null + } + + currentFuel?.let { curFuel -> + val burningTimeMs = curFuel.params.burningTimeMs ?: run { + Gdx.app.error(TAG, "Burning item has no burning time. Item : ${curFuel.params.key}") + return + } + + if (TimeUtils.timeSinceMillis(startBurnTimeMs).toDouble() / burningTimeMs >= 0.01) { + burnProgress += 0.01f + startBurnTimeMs = TimeUtils.millis() + } + + } + + if (currentFuel != null && burnProgress >= 1f) { + if (canSmelt()) { + startBurning() + } else { + currentFuel = null + burnProgress = 0f + smeltProgress = 0f + } + } + + if (!canSmelt()) { + return + } + if (currentFuel == null && !fuel.isNoneOrNull()) { + startBurning() + smeltStarTimeMs = startBurnTimeMs + smeltProgress = 0f + } + + if ((TimeUtils.timeSinceMillis(smeltStarTimeMs).toDouble() / SMELTING_TIME_MS) >= 0.01) { + smeltProgress += 0.01f + smeltStarTimeMs = TimeUtils.millis() + } + + if (isActive && smeltProgress >= 1f) { + val res = gameItemsHolder.getItem(input!!.item.params.smeltProductKey!!) + if (result.isNoneOrNull()) { + result = res.toInventoryItem() + } else { + result!!.add() + } + input!!.subtract() + if (input!!.amount <= 0) { + input = null + } + smeltStarTimeMs = TimeUtils.millis() + smeltProgress = 0f + } + } + + companion object { + private const val TAG = "Furnace" + + const val FUEL_INDEX = 0 + const val INPUT_INDEX = 1 + const val RESULT_INDEX = 2 + + const val SMELTING_TIME_MS = 10000L + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt new file mode 100644 index 0000000..ccc3972 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/objects/furnace/FurnaceController.kt @@ -0,0 +1,43 @@ +package ru.deadsoftware.cavedroid.game.objects.furnace + +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.misc.utils.px +import java.io.Serializable +import javax.inject.Inject + +@GameScope +class FurnaceController @Inject constructor() : Serializable { + + private val furnaceMap = mutableMapOf() + + fun init(gameItemsHolder: GameItemsHolder) { + furnaceMap.forEach { _, fur -> fur.init(gameItemsHolder) } + } + + fun getFurnace(x: Int, y: Int, z: Int): Furnace? { + return furnaceMap["$x;$y;$z"] + } + + fun addFurnace(x: Int, y: Int, z: Int) { + furnaceMap["$x;$y;$z"] = Furnace() + } + + fun destroyFurnace(x: Int, y: Int, z: Int, dropController: DropController) { + val furnace = furnaceMap.remove("$x;$y;$z") ?: return + val xPx = (x + .5f).px + val yPx = (y + .5f).px + + furnace.input?.let { dropController.addDrop(xPx, yPx, it) } + furnace.fuel?.let { dropController.addDrop(xPx, yPx, it) } + furnace.result?.let { dropController.addDrop(xPx, yPx, it) } + } + + fun update(gameItemsHolder: GameItemsHolder) { + furnaceMap.forEach { _, furnace -> + furnace.update(gameItemsHolder) + } + } + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt index 378ed7b..5af20e8 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/BlocksRenderer.kt @@ -2,7 +2,6 @@ package ru.deadsoftware.cavedroid.game.render import com.badlogic.gdx.graphics.g2d.Sprite import com.badlogic.gdx.graphics.g2d.SpriteBatch -import com.badlogic.gdx.graphics.g2d.TextureRegion import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.MathUtils import com.badlogic.gdx.math.Rectangle @@ -87,7 +86,11 @@ abstract class BlocksRenderer( if (foregroundBlock.canSeeThrough && !backgroundBlock.isNone()) { val drawX = x.px - viewport.x val drawY = y.px - viewport.y - backgroundBlock.draw(spriteBatch, drawX, drawY) + if (backgroundBlock.isFurnace()) { + backgroundBlock.draw(spriteBatch, drawX, drawY, gameWorld.getBackgroundFurnace(x, y)?.isActive ?: false) + } else { + backgroundBlock.draw(spriteBatch, drawX, drawY) + } } } @@ -97,7 +100,12 @@ abstract class BlocksRenderer( if (!foregroundBlock.isNone() && foregroundBlock.params.isBackground == background) { val drawX = x.px - viewport.x val drawY = y.px - viewport.y - foregroundBlock.draw(spriteBatch, drawX, drawY) + + if (foregroundBlock.isFurnace()) { + foregroundBlock.draw(spriteBatch, drawX, drawY, gameWorld.getForegroundFurnace(x, y)?.isActive ?: false) + } else { + foregroundBlock.draw(spriteBatch, drawX, drawY) + } } } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt index a17bd61..f14d36b 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/DropsRenderer.kt @@ -4,7 +4,7 @@ import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.graphics.glutils.ShapeRenderer import com.badlogic.gdx.math.Rectangle import ru.deadsoftware.cavedroid.game.GameScope -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController import ru.deadsoftware.cavedroid.game.world.GameWorld import ru.deadsoftware.cavedroid.misc.utils.cycledInsideWorld import ru.deadsoftware.cavedroid.misc.utils.drawSprite diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt index 03df48f..f87c5bd 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/render/WindowsRenderer.kt @@ -8,6 +8,7 @@ import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.render.windows.CraftingWindowRenderer import ru.deadsoftware.cavedroid.game.render.windows.CreativeWindowRenderer +import ru.deadsoftware.cavedroid.game.render.windows.FurnaceWindowRenderer import ru.deadsoftware.cavedroid.game.render.windows.SurvivalWindowRenderer import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager import javax.inject.Inject @@ -18,6 +19,7 @@ class WindowsRenderer @Inject constructor( private val survivalWindowRenderer: SurvivalWindowRenderer, private val craftingWindowRenderer: CraftingWindowRenderer, private val gameWindowsManager: GameWindowsManager, + private val furnaceWindowRenderer: FurnaceWindowRenderer, ) : IGameRenderer { override val renderLayer get() = RENDER_LAYER @@ -27,6 +29,7 @@ class WindowsRenderer @Inject constructor( GameUiWindow.CREATIVE_INVENTORY -> creativeWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.SURVIVAL_INVENTORY -> survivalWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.CRAFTING_TABLE -> craftingWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) + GameUiWindow.FURNACE -> furnaceWindowRenderer.draw(spriteBatch, shapeRenderer, viewport, delta) GameUiWindow.NONE -> return else -> Gdx.app.error(TAG, "Cannot draw window: ${windowType.name}") } diff --git a/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt b/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt new file mode 100644 index 0000000..a963502 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/render/windows/FurnaceWindowRenderer.kt @@ -0,0 +1,139 @@ +package ru.deadsoftware.cavedroid.game.render.windows + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.graphics.g2d.SpriteBatch +import com.badlogic.gdx.graphics.glutils.ShapeRenderer +import com.badlogic.gdx.math.Rectangle +import com.badlogic.gdx.utils.TimeUtils +import ru.deadsoftware.cavedroid.MainConfig +import ru.deadsoftware.cavedroid.game.GameItemsHolder +import ru.deadsoftware.cavedroid.game.GameScope +import ru.deadsoftware.cavedroid.game.mobs.MobsController +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace +import ru.deadsoftware.cavedroid.game.render.IGameRenderer +import ru.deadsoftware.cavedroid.game.render.WindowsRenderer +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsConfigs +import ru.deadsoftware.cavedroid.game.ui.windows.GameWindowsManager +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.FurnaceInventoryWindow +import ru.deadsoftware.cavedroid.misc.Assets +import ru.deadsoftware.cavedroid.misc.utils.drawSprite +import ru.deadsoftware.cavedroid.misc.utils.withScissors +import javax.inject.Inject + +@GameScope +class FurnaceWindowRenderer @Inject constructor( + private val mainConfig: MainConfig, + private val mobsController: MobsController, + private val gameWindowsManager: GameWindowsManager, + private val gameItemsHolder: GameItemsHolder, +) : AbstractWindowRenderer(), IGameRenderer { + + override val renderLayer get() = WindowsRenderer.RENDER_LAYER + + private val furnaceWindowTexture get() = requireNotNull(Assets.textureRegions[FURNACE_WINDOW_KEY]) + + + override fun draw(spriteBatch: SpriteBatch, shapeRenderer: ShapeRenderer, viewport: Rectangle, delta: Float) { + val windowTexture = furnaceWindowTexture + + val window = gameWindowsManager.currentWindow as FurnaceInventoryWindow + + val windowX = viewport.width / 2 - windowTexture.regionWidth / 2 + val windowY = viewport.height / 2 - windowTexture.regionHeight / 2 + + spriteBatch.draw(windowTexture, windowX, windowY) + drawItemsGrid( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + gridX = windowX + GameWindowsConfigs.Furnace.itemsGridMarginLeft, + gridY = windowY + GameWindowsConfigs.Furnace.itemsGridMarginTop, + items = mobsController.player.inventory.items.asSequence() + .drop(GameWindowsConfigs.Furnace.hotbarCells) + .take(GameWindowsConfigs.Furnace.itemsInCol * GameWindowsConfigs.Furnace.itemsInRow) + .asIterable(), + itemsInRow = GameWindowsConfigs.Furnace.itemsInRow, + cellWidth = GameWindowsConfigs.Furnace.itemsGridColWidth, + cellHeight = GameWindowsConfigs.Furnace.itemsGridRowHeight, + ) + + drawItemsGrid( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + gridX = windowX + GameWindowsConfigs.Furnace.itemsGridMarginLeft, + gridY = windowY + windowTexture.regionHeight - GameWindowsConfigs.Furnace.hotbarOffsetFromBottom, + items = mobsController.player.inventory.items.asSequence() + .take(GameWindowsConfigs.Furnace.hotbarCells) + .asIterable(), + itemsInRow = GameWindowsConfigs.Furnace.hotbarCells, + cellWidth = GameWindowsConfigs.Furnace.itemsGridColWidth, + cellHeight = GameWindowsConfigs.Furnace.itemsGridRowHeight, + ) + + window.furnace.fuel?.draw( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + x = windowX + GameWindowsConfigs.Furnace.smeltFuelMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.smeltFuelMarginTop + ) + + window.furnace.input?.draw( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + x = windowX + GameWindowsConfigs.Furnace.smeltInputMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.smeltInputMarginTop + ) + + window.furnace.result?.draw( + spriteBatch = spriteBatch, + shapeRenderer = shapeRenderer, + x = windowX + GameWindowsConfigs.Furnace.smeltResultOffsetX, + y = windowY + GameWindowsConfigs.Furnace.smeltResultOffsetY + ) + + if (window.furnace.isActive) { + val burn = GameWindowsConfigs.Furnace.fuelBurnHeight * window.furnace.burnProgress + + spriteBatch.withScissors( + mainConfig = mainConfig, + x = windowX + GameWindowsConfigs.Furnace.fuelBurnMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.fuelBurnMarginTop + burn, + width = Assets.furnaceBurn.width, + height = GameWindowsConfigs.Furnace.fuelBurnHeight, + ) { + spriteBatch.drawSprite( + sprite = Assets.furnaceBurn, + x = windowX + GameWindowsConfigs.Furnace.fuelBurnMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.fuelBurnMarginTop + ) + } + + if (window.furnace.canSmelt()) { + val progress = GameWindowsConfigs.Furnace.progressWidth * window.furnace.smeltProgress + + spriteBatch.withScissors( + mainConfig = mainConfig, + x = windowX + GameWindowsConfigs.Furnace.progressMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.progressMarginTop, + width = progress, + height = Assets.furnaceProgress.height + ) { + spriteBatch.drawSprite( + sprite = Assets.furnaceProgress, + x = windowX + GameWindowsConfigs.Furnace.progressMarginLeft, + y = windowY + GameWindowsConfigs.Furnace.progressMarginTop, + ) + } + } + } + + window.selectedItem?.drawSelected( + spriteBatch = spriteBatch, + x = Gdx.input.x * (viewport.width / Gdx.graphics.width), + y = Gdx.input.y * (viewport.height / Gdx.graphics.height) + ) + } + + companion object { + private const val FURNACE_WINDOW_KEY = "furnace" + } +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt index 8fa3fb2..faef993 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsConfigs.kt @@ -70,4 +70,35 @@ object GameWindowsConfigs { const val craftResultOffsetX = 128f const val craftResultOffsetY = 36f } + + data object Furnace { + const val itemsGridMarginLeft = 8f + const val itemsGridMarginTop = 84f + + const val itemsGridRowHeight = 18f + const val itemsGridColWidth = 18f + + const val itemsInRow = 9 + const val itemsInCol = 5 + + const val hotbarOffsetFromBottom = 24f + const val hotbarCells = 9 + + const val smeltInputMarginLeft = 56f + const val smeltInputMarginTop = 18f + + const val smeltFuelMarginLeft = 56f + const val smeltFuelMarginTop = 54f + + const val smeltResultOffsetX = 128f + const val smeltResultOffsetY = 36f + + const val fuelBurnMarginLeft = 56f + const val fuelBurnMarginTop = 36f + const val fuelBurnHeight = 14f + + const val progressMarginLeft = 79f + const val progressMarginTop = 34f + const val progressWidth = 24f + } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt index 05c8a9b..1b6611a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/GameWindowsManager.kt @@ -3,12 +3,10 @@ package ru.deadsoftware.cavedroid.game.ui.windows import ru.deadsoftware.cavedroid.game.GameScope import ru.deadsoftware.cavedroid.game.GameUiWindow import ru.deadsoftware.cavedroid.game.mobs.MobsController -import ru.deadsoftware.cavedroid.game.objects.DropController +import ru.deadsoftware.cavedroid.game.objects.drop.DropController +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace import ru.deadsoftware.cavedroid.game.ui.TooltipManager -import ru.deadsoftware.cavedroid.game.ui.windows.inventory.AbstractInventoryWindow -import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CraftingInventoryWindow -import ru.deadsoftware.cavedroid.game.ui.windows.inventory.CreativeInventoryWindow -import ru.deadsoftware.cavedroid.game.ui.windows.inventory.SurvivalInventoryWindow +import ru.deadsoftware.cavedroid.game.ui.windows.inventory.* import javax.inject.Inject @GameScope @@ -36,6 +34,10 @@ class GameWindowsManager @Inject constructor( } } + fun openFurnace(furnace: Furnace) { + currentWindow = FurnaceInventoryWindow(furnace) + } + fun openCrafting() { currentWindow = CraftingInventoryWindow() } diff --git a/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt new file mode 100644 index 0000000..5adaac6 --- /dev/null +++ b/core/src/ru/deadsoftware/cavedroid/game/ui/windows/inventory/FurnaceInventoryWindow.kt @@ -0,0 +1,15 @@ +package ru.deadsoftware.cavedroid.game.ui.windows.inventory + +import ru.deadsoftware.cavedroid.game.GameUiWindow +import ru.deadsoftware.cavedroid.game.model.item.InventoryItem +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace + +class FurnaceInventoryWindow( + val furnace: Furnace, +) : AbstractInventoryWindow() { + + override val type = GameUiWindow.FURNACE + + override var selectedItem: InventoryItem? = null + +} \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java index 686f1c9..0d5a80a 100644 --- a/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java +++ b/core/src/ru/deadsoftware/cavedroid/game/world/GameWorld.java @@ -8,7 +8,9 @@ import ru.deadsoftware.cavedroid.game.model.block.Block; import ru.deadsoftware.cavedroid.game.model.item.InventoryItem; import ru.deadsoftware.cavedroid.game.model.item.Item; import ru.deadsoftware.cavedroid.game.model.world.generator.WorldGeneratorConfig; -import ru.deadsoftware.cavedroid.game.objects.DropController; +import ru.deadsoftware.cavedroid.game.objects.drop.DropController; +import ru.deadsoftware.cavedroid.game.objects.furnace.Furnace; +import ru.deadsoftware.cavedroid.game.objects.furnace.FurnaceController; import ru.deadsoftware.cavedroid.misc.utils.MeasureUnitsUtilsKt; import javax.annotation.CheckForNull; @@ -20,6 +22,7 @@ public class GameWorld { private final DropController mDropController; private final MobsController mMobsController; private final GameItemsHolder mGameItemsHolder; + private final FurnaceController mFurnaceController; private final int mWidth; private final int mHeight; @@ -32,11 +35,13 @@ public class GameWorld { public GameWorld(DropController dropController, MobsController mobsController, GameItemsHolder gameItemsHolder, + FurnaceController furnaceController, @CheckForNull Block[][] foreMap, @CheckForNull Block[][] backMap) { mDropController = dropController; mMobsController = mobsController; mGameItemsHolder = gameItemsHolder; + mFurnaceController = furnaceController; boolean isNewGame = foreMap == null || backMap == null; @@ -170,6 +175,11 @@ public class GameWorld { public boolean placeToForeground(int x, int y, Block value) { if (!hasForeAt(x, y) || value == mGameItemsHolder.getFallbackBlock() || !getForeMap(x, y).hasCollision()) { + + if (value.isFurnace()) { + mFurnaceController.addFurnace(x, y, 0); + } + setForeMap(x, y, value); return true; } else if (value instanceof Block.Slab && isSameSlab(value, getForeMap(x, y))) { @@ -182,6 +192,9 @@ public class GameWorld { public boolean placeToBackground(int x, int y, Block value) { if (value == mGameItemsHolder.getFallbackBlock() || (getBackMap(x, y) == mGameItemsHolder.getFallbackBlock() && value.hasCollision()) && (!value.isTransparent() || value == mGameItemsHolder.getBlock("glass"))) { + if (value.isFurnace()) { + mFurnaceController.addFurnace(x, y, 1); + } setBackMap(x, y, value); return true; } @@ -206,6 +219,9 @@ public class GameWorld { public void destroyForeMap(int x, int y) { Block block = getForeMap(x, y); + if (block.isFurnace()) { + mFurnaceController.destroyFurnace(x, y, 0, mDropController); + } if (block.hasDrop() && shouldDrop(block)) { for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) { mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop())); @@ -221,6 +237,9 @@ public class GameWorld { public void destroyBackMap(int x, int y) { Block block = getBackMap(x, y); + if (block.isFurnace()) { + mFurnaceController.destroyFurnace(x, y, 0, mDropController); + } if (block.hasDrop() && shouldDrop(block)) { for (int i = 0; i < block.getParams().getDropInfo().getCount(); i++) { mDropController.addDrop(transformX(x) * 16 + 4, y * 16 + 4, mGameItemsHolder.getItem(block.getDrop())); @@ -229,4 +248,14 @@ public class GameWorld { playerDurateTool(); placeToBackground(x, y, mGameItemsHolder.getFallbackBlock()); } + + @CheckForNull + public Furnace getForegroundFurnace(int x, int y) { + return mFurnaceController.getFurnace(x, y, 0); + } + + @CheckForNull + public Furnace getBackgroundFurnace(int x, int y) { + return mFurnaceController.getFurnace(x, y, 1); + } } \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/misc/Assets.java b/core/src/ru/deadsoftware/cavedroid/misc/Assets.java index 329207f..ffc253f 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/Assets.java +++ b/core/src/ru/deadsoftware/cavedroid/misc/Assets.java @@ -44,6 +44,9 @@ public class Assets { public static Sprite joyBackground; public static Sprite joyStick; + public static Sprite furnaceBurn; + public static Sprite furnaceProgress; + public static void dispose() { minecraftFont.dispose(); loadedTextures.forEach(Texture::dispose); @@ -196,6 +199,11 @@ public class Assets { joyBackground = new Sprite(loadTexture(assetLoader.getAssetHandle("joy_background.png"))); } + private static void loadFurnace(AssetLoader assetLoader) { + furnaceBurn = new Sprite(textureRegions.get("furnace_burn")); + furnaceProgress = new Sprite(textureRegions.get("furnace_progress")); + } + public static void load(final AssetLoader assetLoader) { loadMob(assetLoader, playerSprite, "char"); loadMob(assetLoader, pigSprite, "pig"); @@ -205,6 +213,7 @@ public class Assets { loadItems(assetLoader); loadTouchButtonsFromJSON(assetLoader); loadJoystick(assetLoader); + loadFurnace(assetLoader); setPlayerHeadOrigin(); minecraftFont = new BitmapFont(assetLoader.getAssetHandle("font.fnt"), true); minecraftFont.getData().setScale(.375f); diff --git a/core/src/ru/deadsoftware/cavedroid/misc/utils/MeasureUnitsUtils.kt b/core/src/ru/deadsoftware/cavedroid/misc/utils/MeasureUnitsUtils.kt index ecf1ce0..24103e7 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/utils/MeasureUnitsUtils.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/utils/MeasureUnitsUtils.kt @@ -15,4 +15,4 @@ val Int.px get() = this * 16f /** * Converts this value in PIXELS into blocks */ -val Float.bl get() = MathUtils.floor(this / 16) \ No newline at end of file +val Float.bl get() = MathUtils.floor(this / 16f) \ No newline at end of file diff --git a/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt b/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt index 8976c99..917f69b 100644 --- a/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt +++ b/core/src/ru/deadsoftware/cavedroid/misc/utils/RenderingUtils.kt @@ -1,9 +1,12 @@ package ru.deadsoftware.cavedroid.misc.utils +import com.badlogic.gdx.Gdx import com.badlogic.gdx.graphics.Color +import com.badlogic.gdx.graphics.GL20 import com.badlogic.gdx.graphics.g2d.GlyphLayout import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.math.Rectangle +import ru.deadsoftware.cavedroid.MainConfig import ru.deadsoftware.cavedroid.misc.Assets private fun Rectangle.shifted(shift: Float) = Rectangle(x + shift, y, width, height) @@ -69,3 +72,27 @@ fun colorFromHexString(hex: String): Color { rgba = (rgba shl 8) or 0xFF return Color(rgba) } + +fun SpriteBatch.withScissors( + mainConfig: MainConfig, + x: Float, + y: Float, + width: Float, + height: Float, + block: () -> Unit +) { + val scaleX = Gdx.graphics.width / mainConfig.width + val scaleY = Gdx.graphics.height / mainConfig.height + + flush() + Gdx.gl.glEnable(GL20.GL_SCISSOR_TEST) + Gdx.gl.glScissor( + /* x = */ (x * scaleX).toInt(), + /* y = */ ((mainConfig.height - y - height) * scaleY).toInt(), + /* width = */ (width * scaleX).toInt(), + /* height = */ (height * scaleY).toInt() + ) + block.invoke() + flush() + Gdx.gl.glDisable(GL20.GL_SCISSOR_TEST) +} -- 2.29.2