From feb4500c6cb6c19a0ec36c8d8b54a096132050e6 Mon Sep 17 00:00:00 2001 From: Halica Date: Sat, 29 Aug 2026 10:45:34 +0200 Subject: [PATCH] small update boss prototype, auto planter, visual reworks, bug fixes --- README.md | 2 +- assets/sprites/daisy.png | Bin 47198 -> 0 bytes assets/sprites/fairy.png | Bin 54795 -> 0 bytes assets/sprites/gnome.png | Bin 27806 -> 0 bytes assets/sprites/poppy.png | Bin 52668 -> 0 bytes assets/sprites/snowdrop.png | Bin 41034 -> 0 bytes engine/battle.py | 64 ++++++++- engine/bosses.py | 83 +++++++++++ engine/collection.py | 140 +++++++++++++++--- engine/plants.py | 2 +- engine/relics.py | 6 +- engine/roster.py | 47 ++++-- engine/runes.py | 51 +++++-- engine/skills.py | 1 + ideas/test_ignore_me.txt | 0 main.py | 19 ++- tests/test_battle.py | 106 +++++++++++++- tests/test_bosses.py | 139 ++++++++++++++++++ tests/test_relics.py | 6 +- tests/test_runes.py | 59 ++++++-- tests/test_soil.py | 96 +++++++++++++ ui/extract.py | 2 +- ui/main.py | 189 ++++++++++++++++++++---- ui/menu.py | 277 ++++++++++++++++++++++++++---------- ui/picker.py | 193 ++++++++++++++++++++++--- ui/presets.py | 4 +- ui/relic_choice.py | 2 +- ui/runes.py | 4 +- ui/starter.py | 6 +- ui/tower.py | 4 +- ui/typepopup.py | 4 +- 31 files changed, 1293 insertions(+), 213 deletions(-) delete mode 100644 assets/sprites/daisy.png delete mode 100644 assets/sprites/fairy.png delete mode 100644 assets/sprites/gnome.png delete mode 100644 assets/sprites/poppy.png delete mode 100644 assets/sprites/snowdrop.png create mode 100644 engine/bosses.py create mode 100644 ideas/test_ignore_me.txt create mode 100644 tests/test_bosses.py diff --git a/README.md b/README.md index 9370165..6fa3c40 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Plants — Turn-Based Battle Game +# Flora — Turn-Based Battle Game A turn-based battle game in Python. Normal battles are 4v4; the Tower mode starts small and ramps up. diff --git a/assets/sprites/daisy.png b/assets/sprites/daisy.png deleted file mode 100644 index 55c76e1cc02ff9e1c5c6c0a7cc020eff721444ec..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 47198 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 diff --git a/assets/sprites/fairy.png b/assets/sprites/fairy.png deleted file mode 100644 index 2e38944c5dc859437453d92aee85e0ad9959f111..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 54795 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 diff --git a/assets/sprites/gnome.png b/assets/sprites/gnome.png deleted file mode 100644 index 44a762d8bac8dd0c1d49ac8c185eb99018a36537..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 27806 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

VBd^K~g$i{&4qU>`}NO-s(o$vlNlv_R@?Q zudSh^Ly z4%^)K{e9Vys#e{}Yc%Ro%zb~5ETz!aviuceG|tHH=Pq$_dCouEA$zRDS_kwU1)@Ai zL>#{F`zU0e$4bCWgdmA@>NSul1(Eyx!7CHryDD$2#wOIo@<#sA0}SZ@bQ-r?oZTlj zL`Kb?g(bOh$y_M{W^=l@crqdN?-jvp_DJyjDHh?hpoJX=59hL1aVEk_R`%CK95>i# zx4Nbo&?R+4kgwX|k5Tq@s@3+PCi`p4{awAWELtlRK(&vmVVizZXAAD~qmq}S8I*VD z-zVoU5+Lxp22bGKx&EJClO+}IP&NFg9!^OKmlWxRU7HxAix9ZgY#GvvV$$F@lBz;wV?9`fgFh(u`a1R9Lu z4HWWv{Sw6eCgT}IK)=)8`y*BG_^U)J%Ht+_Vs_B@L!zGtu8NJIz|hr*y*iv5 z`c!C4UelZU-BIiq-)tc(5(_CR9;-@)_UtF=u~J0%cf-~<_|jO0*sVP86Q3QiL0^_< zFjs&Rh!)JzlaSsm2+M`O!*>8R&Vl??dP~75PF>kr`;Xw-_QC8edZti~XFMh=UBJs&Fz%AG9ASSwy|Ozw&D6 zAB^?IYti4-K0z?UU=-yyi>gh$iK=6HW0{jU>dme z6g!CW*6f?}j6$D2+=>CeCG_e!3CaUSd)acoN?-6zUT}{9!M&^2ID?)CNNkaoCUz+u zngA0<&C>Dgmn>z^Zk;I=v_Z>*KC9ciVWPM_M+=FF-xW8}9N?!BEfa=KU=j>X$hSG( z%7%-keaBCm3V-}Jkux7ei>?_B_N4Na=u@-jshC>_kHsud(B0D7g`52|cy@6As3ilfm zJ@p^2Cyigej@HeEniBsOSNPtFnHh+3=6Eh=j!QmHl_mcdq8p1+UP)2Ip8D=2WOOs- z^z}D3G@KN2e(Z#s`^rh=rcb%5lbT6T_pXnPq*{&bmL9?uru)wK4|zme(y|AVQ(1!i zDZr+chf2nt5F{ldcizFDB#xZMOd$!!_%A0@3->-~E)k4;-{xp|c!Y96(${5}yzSYK zsavw1OtbMF@6=MaySs58G07t^wMx=$+?u57#U-ldhHd^~?$=jEaou}6^wXcrQkwO5 z4P>yYsk7B2g{O52b<^S~x9oJMNgXTmlZia24sQtvt!922uuqfize~(TT_u5bDtevH zQkO^XO_%Spm7<6Gk|Jb}4HE`ZN4*1!iyK{l^5Q7g6`q&mx_LzW#BLc`JVe+)iawwx z3ZmCD6H-%j*YaC-OCPcYkZS!i_7-itU-k-)?&XJGib5Z%X);7{-iy(tPy7@|@<2WP zm*yK5S8BiQW3UygW_9)tqYYd|O+&;KPKh0{Vt$0}7u52a5<8R14GLH^P7AOxE>+Y8 zJwu@HEU_q96R~>xYGT9Ox3~D<48^pDu9`(U%d}>JhaGBX0T|<0g}sN8&LY+}ag%$x zInW!(1)~=(H~gO4atBV=xKWuD3Dv36|83MT$HIArCtcsC@R|_UqWO8u&l^Vl!ZgRA zmykzWe0X!al!a5lCCC(Y?5RR8p?R#SNeIj8t|d+#)bl(Yb~uZdi(Ud>xVZgav^HPh zSJ(JLWtmX4{KKB0v`TnxG5q3}lnoAk(QdpSo1>Hlfz6z^#p?t%Qz!AleB_1CF-c!z;$tc6lmsE3rV zmL5bgnZ)CX<185ruvNpIh2&5@O7~dYsn00GWf~9m#TySZ7f-+f_l=geBNr z%0D8=q&u3aeQ9TZPec`$-_(bcqU$b9V>>F~p9uFxHWzzd5D02{5{yQKGm`u5#tx;- zW{1FHl!x0Cag}-f_MVh*e^SZ%f+i9n+1ojyZCby@sB*jjLFQT@!TH|&2ID2 zG}e|gdoHCu+dlQH^heMZ#e0uWY?R2~)AS+J174V(owvS|renNTs0fE017tXdWkDmK z-rVDwVbtkY{lA`0_fjjq@Lcra`LEYC53n4JNNmR-acZzrCEO+Uo}#xWgxZ}g!(Ed( zf)a9Gf4KN}O&gbdrabtjeP3~xp+UGYefzu%oz4(5J+fi#!>GVdn7HUahqwAoH>%?O z`|M$Ysb4&n)+g}Qf#`*E8^OkT0VWjb>}MxEO15P?bZ_0{*;Kc`>uWa;fJ7h2^08ci z*epVZT7KQ!*bfD_pfNP19K27etfnuV50VeFJWjS_f3BKNlMmVxEASw?(26G#!57^Q z#!m?nZ*(xeO$(HFXfXdJ2S+|o-Lwtdi=X)^|;QSKmAWo z62p%hXGExk4*Z5>`wF^mZth7I1?;zbwdXx(ucOJJik^zS&vG!5x`FwRRq5OgKUm^R zH^w8;w!R{+5#i;&Io%1gv34s#3e8r6(V`lgZ)NL>pZ}h7I>8f zUbjzasRLb8E70}i;XAIo77u3on(QJ-+E)wO`}~5wow`iJ>xXHKq7kpA_Q@?Obe2G$ z$Gs{{{tqO{DTes5T`K{C34eqU2HrKfp*Jm)dO{K9QB<4r&@aLLaUjNm@1EKF8V!v5 z7jTriGQUVPlC*?6zb&E|o%uG;(=NkM{D))=An^c3P9FpzQ3M%a6fnt#wh*42)43J> z82EkeNdtduBt{%x9e?1V#KgM|T)Kp`jXeo74+?XA+8Xmq7m^t}?7L|It8bAdgYF^U z<1zotzvn&N6)ta+FEhTc`Gp68L0|aOwiGsC<@&u6*?8=9KwKUqoRd(Sx_9hXkB{a{ z$0K{f>f3aQ#wfo03>`RR+!5n7n=qXy?5?mytTftWVTDbIwCCWDv@0QvTV@F1GtG6S z*vRi!b*}&wiHAO?=jU|jn+DsvL@;ol?j~M)ga`Runy5uC1=uJhnGfp^Shom_<4ym1 zyrer2B*ls^ze~PvEi+-!MT0JeT;tbz0gA#xm2jeJ8k`3sjM2=2;_gA?L*Q0b+UT5I z{kKc&9MqzZH#;7n7q5FD4Q{4*3syN^U0%_DF}7&}1O6^@GZ-W--B=iFkA#PC5`Q8~ zqs9Un5uj#_$wj3Cla~QzycA4uK_6+Zf$G8TWYALbE8;stniGRmyKhN*cl%r|*MVXK za^9%Ov31VQ2OaMTn5mLf%u)Gi@-k)_2lMOkV!R;N{o)@Eu8xn8%!{D*oBD^ge`lM^ zm!BbJ@DVpdTj7BF?%LfJx{V@H=SC^S4Blndp?oJcyMUH~TC2DQ_({rz>1ia<<5;Z! zq5l+)TkuIX4I=Kflz7zWfWIgLETNwvda^9nq0h9jrxKU|_H4{~AMdvTf6db_<1^d9 zQsDRCe&u(`JHF5C+FeAQYiP1=uJ&KbBCV9V8>5m!fR334VXb6yXaa@?0ZJL8Q<&QN zrlUfS312ONnw4rsppr)&Hqst>L5z&aT6#mMiXO#oy#=>b@=8>sS?ZTklT>-c)Um}? z)*NMux{XKOiln-7fvt#j2THt&m4>-sXHLaEt;c-FKudm@#RxhPLxNL#m*4U zmiGVNK+$#08`&A$Qbc!pF+F_>@h025)46^5$ht9Z>|?w#r4BHm!7gi;j}duW0Zgkh z;HuTJfm(q&E#j@y7%)A(pnV@8IwJ!VY>E@zJ2&0zIH;meieDxVJmUDMjpmAAigNFs z;;_RbSQ|R@5=M0R?dY!9AJ^_)ZIclZCxgB2}EZWBW$I5>#sP{Q_Vb@>cThQ_1 z)V6P@g*elyorgXgHGf($EI`%j-O@bDWtOM^^AK!5-{;}Hey1i^zo?^Rjyr* zee-B;$}~` z0KbA?DxY#&G06LpU$r60(VP)05MvR5o{`}&?j~z^2f)CE9H=V{^a&hX>u=kCuB;*cv zzSN1@nxwMCJzVosqa<>-nOK`r{Glq6dyDO~Y%s+F0JQ&!UxYHp5I=38b&|pq_;IC* zzM$Bg?imVk*jX(9ZC()opowb>I3hF%t7wpf#FSiHV8@XE%~UaDTO1&P1+vg06VayE z=)x;UChlzJw@y<(oXbJ|?)y~zJu3;ntR*+OX@qS>k3CmJ-m?%L0tDS*MMZqVT-x`Q z?9|iw9w~ex?ii=ZBZg&w^y^Ya901U#D#$#4Q<)&D?X?Z9C2VtQBN+>X^%P$CYSf^?b zMabi+#SD;@KIp(GlyyBHYQ(@I`2K7KG4zxzHu3~+KPmfA__(xLC4-jSA<%Wh<|d~xZh z_nlIxyxyco$QY$O^@ddT=m8%s@-?FxS-;TURhLzHTjYwzgdqOkUhPT2t>_lNWn0u8ur{Q;0^~5id(WJ5pFk^7i8ak1` zX5Egy7=p15O>&4L#u5AZ!c*L0`LQTw_roC)fm&J{)o6*@qah>5WG1Amn!VP7}t|aV<(P}kEIwq_vndw0s-yvre?*UeNV{WJhI~l zGx#c^2ES4q_R;->#GK7@zY_l!5;7QR2~fqz??N-bn#`D<2Y?4>2BPF@u`f&lpYY>a zWuWy)_^`7$i%#OY#lu)y`OGl8u)#$BJ@Jl*6FIH9JNYfz7Nsm;_uuoy5x{e?@*mj9 zN^Hl8kLRc(+o2K2qp+7()?VK>S3F$Z9>z$&{5e24kolm0y?^@VNS6*@bP{u%o- zS7Z`WfV zcf*L;f{X4`b@!~cHb!kxZ#kweZWKjr5l2J<#+EC<2Knp|y~Y=-_U&)LHHY|FKl!5v zZxTK?FFa==px(gYL}&4uufu=c6aHUGR~`@L*TtV%WNaf$mh5F2NhY$C7+FG=C`#6m zgtG6Y%qSFzP$-2c+4_-Pwm}q;U9v|hI}yVe&wHnL{(L^4yPR{rXS?UzJM3#e7GB(z z4p^3UE;w=Ds^{m2czsqOO{dEJ0Oh#e6^M z@8d^T2Fe9NC~2kd+hmnz_4#dvbQ1s8?CMooJZ@Rb8yzHtx$@MBcu6PY!bm+_q*Wm= zR`{`xLJYOrr|&-Sst=L+pe@kG!u}a)ZBt3o+X$FDpK}GM`)JXMBMIL$q?%!Q{-)TX z9}A*u!b8qgv2Q~}rTm#th{Zqnu!D)95Z$Iv`9{0OsP$pfs|0f+aAEnO zzsnw&a~!oX+BJ@)BvC3e_MLBaezWAWWTjLAURqj6Tm%+5*KP@xqx$W6nT3zh=v{r-v_0<+ZV6 z7HkKzcOk(XDDA@l4QPw1ZhJ6Vy)b>Q0Z;uBI;;V`o_AI^qNzS%@%`#~H?ZwXRJK`} zDk`<_FJ1BT5E7(#v;prQ3z3J-;5d}{gAYYvlS0&z{iiH&Et<1I5af_TD7ohMDfr>} z+h`Gr+e6)!!5Os;K;fJOmKJSyeaygHTR$&WfuISWizHW6!$OXYIe|*o5$!#F4Ow_0 z89pr4l@b^nqVMn=R5}i&kKZ_pxNVbIfEqgKI8zQ!UExvo7{fTmCck6x`A`H7VSX;K z$dAzH{F*+9FVUn>$WcUVYsagQ!{mlH;#PuPm#2+8yQ+_WX~+ z#&`IO{r6%=n>55^oj|9Y?VaaAelcVc4nDw-NK!m~>h)-lJ$C0jQ*trJN>Km|i@Dm#IObsP&@yUft!7`1S^)^Ew8al5?toP zpnk4IG}BLK%!?2{n0zgLDRX6e_qF7?H}|QK2%W zUi?QM)60PR*Gt&SCDIr@@&fZ~@d0|Gr{dbb44t4SJ zAPC$dK-vzi+=)ndlB5d~#@s!R-B{50w-+&0f$vQI!e`@4YwBy!T70j!3iD2L*7U%Bzb{WtCz#){#x?PahxZhn zdJ^c^9yA&oN4LVYyaCfd=Q-UJW-nGLo%w#P+G$bM&~#6s%V!QnOnp@beG2 zWXNKWA>+)kzz!#O-n%i_YdNwitz&-#?8ISGfR)5WuxRS;_1#tXF~T7SEu}C|r0*Mu zvR@d|P-U<-AJH9iY`84h!5F?NMD(dAjW|{f-~R4cwMT2Oh%;wDMCK{a#e;a=Q3Tq1 zjm?f&8b$J*u|>X?K_z?Lx2QUF=CFr2Oq_Dt{CWZ#ixVM*QWJ_Z%tss#IQhX|LYts0 z*Iwu%91j)fD}c}#GcC(XI-KLy9-}9cZ2IYzF)3yITfl-BypdcOpHOKivqP@Zr;)!L ztDd82Yga5PT7R!!@n#%K)j9<%#&Lo8Xd7lw1QCxzzLU~yy7CR|(a%#oXEiN#cnD|G zwdsysTE%oi@YfS;=OtuY&c;^?9LSg6e^m08+J~&Gj}mNuy#z7uPEQ<=c`rH)y#MBa zDh#eMBs9*+J&i}Mk9XE%Gr{@w+&Q}F+=}D-ueI<#ES7KWbnGO7JmRArB`+C~v9vc%zcTlDFi-HG|9JA$6TMea&_=@U$;&CGe>V zBtp0SEi1LnR~RsnP#m_;WLxj5=m;L=#mnUIlw_Dcr0wQ#6PQ!eH6`Kb#iQmqd%Kg( z>`4=MN9{Fk-x-ywc9vCNJ11oO4j*BsdMgCC-M}$T1zat|?EHp05cN+8Wm3%w;i92e zdj3nQJCLbB7k66UI4{lrL^L|Iy}G+DrB0MpqcMGTIp*GO1IhvSZ{ee10pO|2WI{=x zQN&dFQ=UD3A^;yZIltV(O+Lz~uJM{v$9E)M(ybKp8NQ)ZaVf30n2>@@~AuVQn#jVAY@^qAW7N~l2tO54l3$7a<< zC4qGFarjii;&PwAPms-$Z3ct;?CmvC_=u&otOF-q1kGBrpq*=++k5*rc^hr5^c4_j zNXp-}XWt7lDH;k)1$7w;Mn{PxlM|xwlxYtE1oS)MC5F0d@M>cxpZ#FGd<)F@Hh%ip zl-7DfAYbf_kua{mA^Rm?umi7c(#tDCc}i6Sh`)WIu6fq(S;*mH-T#iCkEF1^`VGaB z1@aYI=LUa1$|e;t7CqEQ%67+g9_VMUY?QW!@4a%=C;lIEID2?SAd0MXY(zU>;hzvg z^DG2w_6S9!#IM&DqfWxCFQx3P$+u5Fuu$5>q9+SKFDzPGRejxte<%z+zupjaLXX1H z(+wQ<+lb^TC>D_ntnRvzN_1+l1;rXwQCjkHgt9(}c(s2wW2IgWdJGWV>_s2?cE4YH z=;uxT4nj5AX^Ev?pfVo>$C5TNs7KT?`%8R>V@j{ZsNGZlxMhJT)*9{ zqS_K1QKE@EYYl?ZDRd$zAq04Hpho(4M?d{-ot9Z%u5c^nxkG&|7PP&OK|2Sa>fRu=H%yzgeZE8dg41QEFkoSnspkS1B3%dW<1Fd6V>{ z$_k9<>`MeZ{fbD~3gFOs9FP2PYYJKj_4(8Ff|g)60XsEBjBNyxZy%o1;(Zs8{?q~A z@dlG;0q{k8m^=gZlll>F+4x&7X__8kC$++=yPKfJGO6#V<_ie4eP;8}JYIEZdiuk0 zrJX#!-;?$UP|2|Lk-xT(o#ZtO5M3IS9Rql0$+T?h)@j6RA6Pn8cY`Iy z68R%ZuWPP1Y>8Yo3kvq+>)5lz&xFR5vQ0k9oU`_jQ?3&6%Us?DyLuaE!K`XG9it6y z0qP-JcP`F^g&zjy8Tg(!p@I3RzXg-oYGd{z=$};B$r9w=7B(sh10bzn#~2IR5Drx} zLm8HYEizdT+Az@}lLxO1y|>_NLqGUc3>yZ}Kb(f9E~iraX@V?T}nzP?PN8tYT*lGGVpX;|UGPov9k zK7#v%=NgXihhIy%0mqL=SUq6UV@wfldCQz7HF*i#v@r7;?6;J$KJnl1KzSSZ6R!8% z>qoeXe}#1tT{}jUHrcN<3Z=XXdyzz7?0VhYXh_32l9RUsJI%SC*DRg|XjRoU4u&8x z-QS->+o~kKx8wAGi+%*JXGW*+P-a9ZEu~HmKbhz!(I;HoVgx+-=)T!&4M9S&yhgMI zsulQOAaE3smZhQ&-Jm|;jXE%ZebD-9#`wc@-ixbshtM7Fth#AJjq+Ao+$(9soG??X zNR1b8qD~0IDBE75gA6qW>jQ-R?A|W|5iFntA)n7OmgnuC?eM684!ZXX{awPWq_1_E z_ViXbjB&{N#Kjp0&^a4)z4cq}S#`9^k$jZ{P9cj&&u=Mqm`r+4UDyZ2jCtFFz-t?d z62yG12`6qme5rT1JbyQCtmMuO7))`Ww9=buSppL1j6Btc|SW@3|sGDn}3b;9%9t6o-JHde=~%i*BG zUYB3%C!h?nL<*6}Xu_q}n$C7T9O{ZK>d3v!UB#OEJK6*b6TWeCZT zZ}c&4=gq*^XNL_oJiWh)1$`_3-cXPi)u!X@xo3&}-tNh*Ul*<3%WvD33u=W(|D8`H z9bU@9BQb!W5oc-kWs>bKf8^3Hn@|pp#uADD3 zeYMU>d*7AYUdx;!@AHu~<@UUQ(|1=cQ)PuZ@L!Q^y5L;3kp7=<-LU00Jm0HdwTHBM zx(QybVuOvl3lv2HFZ*>pj2e?;SUqm~%w03j?-m6fq>aeZ1!m=K_~38I63J~Wl%`ga z-*f6zG){^#f509+WDUcGZRTZGGh%OExR&h!_GKhzJtd3b!&SS3dCXsJOpD3;KDf=&0ymTxk-embGwSK_;p$ylBN|F^{-Hi&x*-&VR_+rU9{*pE9E zTfdI8`Ny0spCXFgQ_HwxI^OZUhEH($|9m#N9tbt1Ui0SRzcobB^J%($==fgHc<(a4 zU04_;eIupwUf^eauSO#>1uL2s7FTLIqc#vj{usXLcx?VJ1xCh)UcLm79NA|h3Q>Y7 zH-IiQqB)4;4sP8QhNk)0Oqk?0;q);ho_z7cNzoHcY_2Ns$x5Y$jCw9***9VKyd5pS zcR*l(=jwhY3bFF-?sNJUvG>UqQOtV`$U7k)C0Is}BaW1a)eG=;A7A23Lb}C}UMFmu zK526%^$G^hUyJIb&i;-d0?wRv@5DmXUzq56sms_>gB|PPbRS8t^8$GnsFI-zw9>9| z<*g9g6937^rD!6gV94L4uj1m%;8!^eER z=om_ets@a>Zo%Fsdp~tXKvs7->>+$xiu07fe)#iDvj!X_%RS18^(pk++E?|r?|x%%U+y{j8Z_ne*R)82G!ckpC9Xt!;Ab+)h*>C=7o z;kvi(hiP+%#BH{)KAVH7e!jfxZRKc}#swY;v zn75wMJ1jzqAkWEjT(C-Y(#$irLcm+BKfDt!UDUjsS`2TdTVDjm09B>}?oAz*=$GSu zpoQhlGgIJXzAS-WtN|^qs$?@!)&!i|@2F2-!uh@o?YcIeIk=I;UY_f|)Y=3qqs><1A26MhKsMXy9>zf+jIZHV zhVA*3WVbAHu}vJCjjiQM^X`;N!W}cPb`0eC4S{D_N>RE1pgHH>_V7azxN#7oneWr%obAk4C!gPPr!DN!d@S@gqgc#XLBqtr;N(sqcVJ+rW zN8r~NuuOT01VWs`d!O@}Tj5-1tD*+{bzW~6(L+Yv;1OO7IF>w=2G7`)ZiT*D5!KI^QE4C7wL$|0|43QS-_%R9Wg z{|{OOgA8`}JT?-t-MDl=<}J}{J1iR7SwMd}Gv!Dg4xueKRP1BFsVn5eemWg^3VkEK zIcUL9%ctn^JG~C4B@HX}5nhfq49gAE3#vQow497-^_5xj_vWu#PK#pZv29yjYya4H z=58*kn*bwbfa*F3yL6WA7h%;wdQvJD$W=VN*JAaM<76YRcGAKAC`RBK0C^iU2OTpJ zp>aqA**WgGKk6MF!s>@Voy<+z57z+4x-EE1t*1}ggC&lI|K?2rW;|w5qFe`wm$D79 z7?xQ6=gxZ+Z@o|2=Eb)gssNkHiYoh|zjBI4pX^?*?QHdKe7@6Sa|GCw$NfDR?Y>cV zk7Om8qbO=}wwXuB+QfUF-5UZPf4s89!2z9M*)Yfmqyc=okNu=(DA!@+fEW7Y9JI65 zuD`NiZ$9;QWoeJe5c$cQV8A1bMDT|mGg~<2`1%(Am9EU|n~P-C>q@oj68*;t?GEc7 z0gsQg_SFDLr7+X;pXQfl@9(241hYyp_v&A=+6J56rNBgF z(c*1a8gtUyr{8>>whKU+)daa$PhccI&Ts)$vcM4&@3wim-f}*>@$Ofcd(GD*ZPXzY z)3)@UP{-V#yxTb@8;|z6H=qIXpe(#X1nZ}r*7J`##E80BLRyD6_3153 zWJAU6gFqCx*RPL?U=p?-s`JGwP$f6KnYEBawt)SaqLHaPo2yS944+-P)AQFcVK$OE z>zSNS$a9MeWUu4ofWy%mz9=2|4~jaZBvS7!3heV?7djG9}K7~5o6 z*+(EueTyIo=$6@x+VxowJiMHwgIY5P9^&l7{gfKqjWsJEgP3||)ECoxruun@_b6}t za=2vE@%+OcO&_V|LCxC!lKpYV! zd1>=C26GovM=vI9aWyPui>NpET?7$E7M>ki2CSNBT;E*&zIxq?xt@!#=Fyg*r=vSC zYryJuBuKaLF(sNGA>ZDH)q9kJI`R$Xm#ky0j90;Hj#!b@8 zKTA(}{qK|idh7F!x?$Q~>TCBycgDCSJ~JSB*>r@9li3W&*I zekjBEQ5sMKRTJPgYJ>4+6H}`C?_4n}BIc+52*dj)y|v$P7G4A&-5b$Lb&w0|3B;Sr x$57bT+>O8w9yEQb4GBv?(6HIFMa=o-R^iUsxIxqXZ|x!QGtxKH`%i~-=YMGqqp$z~ diff --git a/engine/battle.py b/engine/battle.py index 2674095..7ba64c4 100644 --- a/engine/battle.py +++ b/engine/battle.py @@ -9,6 +9,7 @@ from .skills import ( S_HEAL_REDUCTION, S_HOT, S_ICICLES, S_INTOXICATE, S_LYING_WAIT, S_MADNESS, S_OBLIVION, S_PREVENT_FIRST_DAMAGE, S_SEED, S_SHIELD, S_SLEEP, S_SNOWFLAKES, S_SPEED_DOWN, S_SPEED_UP, S_TETHER, S_VULNERABLE, S_WILT, S_ZINNIA_WEAKEN, + SHIELD_DURATION, EFF_DOT, EFF_HEAL, EFF_HOT, EFF_SHIELD, EFF_STATUS, EFF_WILT, TARGET_ALL_ALLIES, TARGET_ALL_ENEMIES, TARGET_ALLY, TARGET_ANY, TARGET_ENEMY, TARGET_SELF, TARGET_TWO_ENEMIES, Skill, roll_crit, @@ -135,6 +136,7 @@ class Battle: def _crit(self, unit: Unit) -> float: pct = unit.crit * 100 - self._status_value(unit, S_CRIT_DOWN) + pct += self._rune_pct(unit, "crit") * 100 return max(0.0, pct / 100) # --- tank protection ---------------------------------------------- @@ -278,6 +280,15 @@ class Battle: del unit.status[key] else: unit.status[key] = (value, dur) + # Shields decay like any buff: each application counts down SHIELD_DURATION + # turns from when it was applied, independently of newer shields. + shields = unit.status.get(S_SHIELD) + if shields: + remaining = [(amount, turns - 1) for amount, turns in shields if turns > 1] + if remaining: + unit.status[S_SHIELD] = remaining + else: + unit.status.pop(S_SHIELD, None) # --- status ticking ------------------------------------------------ def _tick_dot(self, unit: Unit) -> None: @@ -371,13 +382,20 @@ class Battle: blue = self._rune_pct(target, "shield") if blue: amount = int(amount * (1 + blue)) - target.status[S_SHIELD] = target.status.get(S_SHIELD, 0) + amount + # Each application has its own decay timer; stacking does NOT refresh + # shields already up (they still decay SHIELD_DURATION turns after being + # applied). + target.status.setdefault(S_SHIELD, []).append((amount, SHIELD_DURATION)) if self._action is None: src = f" from {source.name}" if source else "" self.log.append(f"{target.name} gains {amount} shield{src}") if self._action is not None: self._action["shield"] += amount + def _shield_total(self, unit: Unit) -> int: + """Total shield remaining across all applications.""" + return sum(amount for amount, _ in unit.status.get(S_SHIELD, [])) + def _shield_power(self, user: Unit, base: int) -> int: """Shield amounts scale with the caster's Attack so they keep up with growing health pools (like the Sunflower passive).""" @@ -396,7 +414,7 @@ class Battle: if weaken: mult *= 1 - weaken / 100.0 # tulip_equinox: any ally of Tulip with a shield deals +10% - if attacker.status.get(S_SHIELD, 0) > 0: + if self._shield_total(attacker) > 0: team = self.players if attacker.team == TEAM_PLAYER else self.enemies if any(u.passive == "tulip_equinox" for u in team): mult *= 1.1 @@ -507,10 +525,25 @@ class Battle: def _absorb(self, attacker: Optional[Unit], target: Unit, dmg: int) -> int: self._consume_hits_statuses(target) reflect = isinstance(target.status.get("bulb_reflect"), tuple) and target.status["bulb_reflect"][0] > 0 - shield = target.status.get(S_SHIELD, 0) + shield_list = target.status.get(S_SHIELD, []) + shield = sum(amount for amount, _ in shield_list) if shield > 0: if shield >= dmg: - target.status[S_SHIELD] = shield - dmg + # Consume the damage across applications (oldest first). + remaining = dmg + new_shields = [] + for amount, turns in shield_list: + if remaining <= 0: + new_shields.append((amount, turns)) + elif amount > remaining: + new_shields.append((amount - remaining, turns)) + remaining = 0 + else: + remaining -= amount + if new_shields: + target.status[S_SHIELD] = new_shields + else: + target.status.pop(S_SHIELD, None) self.log.append(f" {target.name}'s shield absorbs {dmg}") self.events.append({"type": "shield", "target": target, "amount": dmg}) if target.passive == "camelia_frigid": @@ -674,6 +707,8 @@ class Battle: if skill.requires_form and skill.requires_form != user.status.get("form"): return [] if skill.target == TARGET_ENEMY: + if skill.mechanic == "boss_landslide" and user.status.get("boss_stacks", 0) < 3: + return [] # Landslide only becomes available at 3 stacks return self._targetable(self.foes_of(user), self._bypass_tanks(user, skill)) if skill.target in (TARGET_ALL_ENEMIES, TARGET_TWO_ENEMIES): return self.foes_of(user) @@ -755,6 +790,10 @@ class Battle: return False if skill.cooldown_left > 0: return False + if skill.mechanic == "boss_landslide" and user.status.get("boss_stacks", 0) < 3: + return False + if user.acted and not skill.extra_action: + return False # a unit acts once per turn (extra-action skills still allowed) if skill.requires_form and skill.requires_form != user.status.get("form"): return False if isinstance(user.status.get(S_OBLIVION), tuple) and user.status[S_OBLIVION][0] > 0: @@ -891,6 +930,8 @@ class Battle: if skill.mechanic == "dissolve": skill.power += self._status_value(user, S_LYING_WAIT) power_bonus = int(self._defense(user) * 0.5) if skill.mechanic == "def_bonus" else 0 + if skill.mechanic == "boss_landslide": + power_bonus += 55 * user.status.get("boss_stacks", 0) if skill.target in (TARGET_ALL_ENEMIES, TARGET_TWO_ENEMIES): targets = self.foes_of(user) if skill.target == TARGET_TWO_ENEMIES: @@ -931,9 +972,12 @@ class Battle: else: self._apply_wilt_damage(target, int(dealt * 0.3)) if skill.mechanic == "heal_random_ally": - allies = self.allies_of(user) - if allies: - self._heal(user, random.choice(allies), 40) + # Only pick from allies that are missing HP, so the heal always + # lands on someone it can actually help (a random full-HP ally + # would silently heal for 0). + injured = [a for a in self.allies_of(user) if a.hp < a.max_hp] + if injured: + self._heal(user, random.choice(injured), skill.power) if skill.mechanic == "strip_buffs": self._strip_buffs(target) if skill.mechanic == "tether_lowest": @@ -942,6 +986,12 @@ class Battle: low = min(allies, key=lambda a: a.hp) low.status[S_TETHER] = (1, 1) self.log.append(f" {low.name} is tethered to {user.name}") + if skill.mechanic == "boss_stack": + user.status["boss_stacks"] = min(3, user.status.get("boss_stacks", 0) + 1) + self.log.append(f" {user.name}'s power stacks ({user.status['boss_stacks']}/3).") + if skill.mechanic == "boss_landslide": + user.status["boss_stacks"] = 0 + self.log.append(f" {user.name} unleashes Landslide and releases all stacks!") def _strip_buffs(self, unit: Unit) -> None: for k in (S_ATTACK_UP, S_DEFENSE_UP, S_SPEED_UP, S_SHIELD): diff --git a/engine/bosses.py b/engine/bosses.py new file mode 100644 index 0000000..9b2c938 --- /dev/null +++ b/engine/bosses.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +from .plants import HP_MULT +from .skills import Skill, TARGET_ENEMY +from .types import TYPE_GARDEN +from .unit import TEAM_ENEMY, Unit + +# A boss appears every BOSS_FLOOR_STEP floors (20, 40, 60, ...). Bosses are +# fought alone (1 vs the player's team) and have far bigger stats than normal +# floor enemies. +BOSS_FLOOR_STEP = 20 + +# Chance (0..1) a defeated boss drops one of its signature runes — much higher +# than the ~5-15% rune drop chance anywhere else. +BOSS_RUNE_DROP_CHANCE = 0.80 + +BOSS_SPECS = { + "Stones": { + "type": TYPE_GARDEN, + # (attack, speed, defense, health) — medium attack, very low speed, + # medium defense, high health (before HP_MULT). + "stats": (110, 30, 90, 380), + "sprite": "stones", + "drop_runes": ("ruby", "amethyst"), + "desc": "A slow, rocky guardian. Each Pebble Throw stacks its power " + "(up to 3); at 3 stacks it unleashes Landslide for huge damage.", + }, +} + + +def is_boss(name: str) -> bool: + return name in BOSS_SPECS + + +def boss_for_floor(floor: int): + """The boss that appears on `floor`, or None if it's a normal floor.""" + if floor > 0 and floor % BOSS_FLOOR_STEP == 0: + return "Stones" + return None + + +def boss_type(name: str) -> str: + return BOSS_SPECS[name]["type"] + + +def boss_stats(name: str) -> tuple: + return BOSS_SPECS[name]["stats"] + + +def boss_sprite(name: str) -> str: + return BOSS_SPECS[name]["sprite"] + + +def boss_drop_runes(name: str) -> tuple: + return BOSS_SPECS[name]["drop_runes"] + + +def boss_floor_level(floor: int) -> int: + """Display level for a boss at `floor` (scales with each boss appearance).""" + return 1 + floor // BOSS_FLOOR_STEP + + +def make_boss(name: str, floor: int) -> Unit: + """Build the boss unit for `floor`. Boss stats are already far above normal + enemies and grow a little with each appearance so they stay threatening.""" + spec = BOSS_SPECS[name] + atk, spd, dfn, hp = spec["stats"] + lvl = boss_floor_level(floor) + mult = 1 + 0.06 * (lvl - 1) + atk = int(atk * mult) + dfn = int(dfn * mult) + hp = int(hp * mult) + pebble = Skill("Pebble Throw", power=60, target=TARGET_ENEMY, cooldown=0, + mechanic="boss_stack", priority=2, + description="Medium damage; stacks the boss's power (up to 3).") + landslide = Skill("Landslide", power=140, target=TARGET_ENEMY, cooldown=0, + mechanic="boss_landslide", priority=1, + description="Huge damage, releases all stacks. Needs 3 stacks.") + u = Unit(name, TEAM_ENEMY, spec["type"], max_hp=int(hp * HP_MULT), + attack=atk, speed=spd, defense=dfn, skills=[pebble, landslide], + role="tank", crit=0.05) + u.hp = u.max_hp + return u \ No newline at end of file diff --git a/engine/collection.py b/engine/collection.py index 6ad102d..c0bb8a8 100644 --- a/engine/collection.py +++ b/engine/collection.py @@ -49,6 +49,8 @@ def init_starter_pinwheel(ptype: str) -> bool: "fertilizer_accrued_at": 0.0, "auto_farmer": False, "auto_farmer_active": False, + "auto_planter": False, + "auto_planter_active": False, "coins": 0, "coins_accrued_at": 0.0, "water_used": 0, @@ -59,6 +61,7 @@ def init_starter_pinwheel(ptype: str) -> bool: "open_history": [], "lesser_opened": 0, "floor": 1, + "bosses_fought": [], "soil": {"seed_cd_until": 0.0, "seeds": [], "plots": []}, } save(data) @@ -80,6 +83,8 @@ def _default() -> dict: "fertilizer_accrued_at": 0.0, "auto_farmer": False, "auto_farmer_active": False, + "auto_planter": False, + "auto_planter_active": False, "coins": 0, "coins_accrued_at": 0.0, "water_used": 0, @@ -91,6 +96,7 @@ def _default() -> dict: "lesser_opened": 0, "soil": {"seed_cd_until": 0.0, "seeds": [], "plots": []}, "floor": 1, + "bosses_fought": [], } @@ -128,6 +134,9 @@ def load() -> dict: data.setdefault("soil", {"seed_cd_until": 0.0, "seeds": [], "plots": []}) data.setdefault("floor", 1) data.setdefault("wins", 0) + data.setdefault("auto_planter", False) + data.setdefault("auto_planter_active", False) + data.setdefault("bosses_fought", []) # normalize runes: older saves lack the per-rune stat roll, and use the old # color names (blue/red/white/yellow) instead of the current gems. for r in data.setdefault("runes", []): @@ -252,8 +261,9 @@ def grant_xp(names, xp: int, count_battle: bool = True, fertilizer: int = None) for n in names: prog = data["progress"][n] bonus = gap * CATCH_UP_PER_GAP if prog["level"] == low else 0 - # all XP gains are cut by 2/3 (only a third is awarded) - gain = (xp + bonus) // 3 if (xp + bonus) > 0 else 0 + # all XP gains are cut to a sixth (half of the old third) so leveling + # takes twice as long; water (a direct +1 level) is unaffected + gain = (xp + bonus) // 6 if (xp + bonus) > 0 else 0 prog["xp"] += gain while prog["level"] < MAX_LEVEL and prog["xp"] >= xp_to_next(prog["level"]): prog["xp"] -= xp_to_next(prog["level"]) @@ -338,6 +348,7 @@ def available_fertilizer() -> int: FERTILIZER_CAP = 100 # fertilizer stops accruing once this cap is reached FERTILIZER_PER_HOUR = 1 # test build: earn 1 fertilizer every real hour AUTO_FARMER_COST = 100 # coins (WIP value) +AUTO_PLANTER_COST = 200 # coins: plants retrieved seeds automatically def add_fertilizer(amount: int) -> None: @@ -404,6 +415,37 @@ def buy_auto_farmer() -> str: return "" +def auto_planter_owned() -> bool: + return bool(load().get("auto_planter", False)) + + +def auto_planter_active() -> bool: + """Whether the owned auto planter is currently toggled on.""" + return bool(load().get("auto_planter_active", False)) + + +def toggle_auto_planter() -> bool: + """Turn the owned auto planter on/off. Returns the new active state.""" + data = load() + data["auto_planter_active"] = not data.get("auto_planter_active", False) + save(data) + return data["auto_planter_active"] + + +def buy_auto_planter() -> str: + """Buy the auto planter for AUTO_PLANTER_COST coins. Returns '' or a reason.""" + data = load() + if data.get("auto_planter", False): + return "Already owned" + if data.get("coins", 0) < AUTO_PLANTER_COST: + return "Not enough coins" + data["coins"] -= AUTO_PLANTER_COST + data["auto_planter"] = True + data["auto_planter_active"] = True + save(data) + return "" + + def buy_rune(tier: int): """Buy a random rune of `tier` (1 = common types, 2 = brown) for coins. Returns the rune dict on success or a reason string.""" @@ -502,6 +544,30 @@ def roll_pack_rune(data=None): return add_rune(data=data, save_now=False) +# --- bosses --------------------------------------------------------- +def bosses_fought() -> set: + """Boss names the player has defeated at least once.""" + return set(load().get("bosses_fought", [])) + + +def mark_boss_fought(name: str) -> None: + data = load() + fought = data.setdefault("bosses_fought", []) + if name not in fought: + fought.append(name) + save(data) + + +def boss_rune_drop(name: str): + """Roll a boss's signature rune drop. Much higher chance than normal rune + drops. Returns a rune dict or None.""" + from . import bosses + if random.random() >= bosses.BOSS_RUNE_DROP_CHANCE: + return None + color = random.choice(bosses.boss_drop_runes(name)) + return add_rune(color) + + def rune_slots(name, data=None) -> int: """Permanent rune slots for `name` (1 + evolutions ever achieved).""" data = data or load() @@ -544,20 +610,20 @@ def free_runes(data=None) -> list: def reroll_rune(rune_id: int, sacrificed_ids) -> str: """Reroll `rune_id`'s stat to a higher value (at least 1% better, never - above its max roll), sacrificing the given 10 runes. Equipped sacrifices are - removed from their plants. Returns '' on success or a reason string.""" + above its max roll), sacrificing runes.RUNE_SACRIFICE_COST runes. Equipped + sacrifices are removed from their plants. Returns '' on success or a reason.""" data = load() rune_list = data.get("runes", []) target = next((r for r in rune_list if r["id"] == rune_id), None) if not target: return "No such rune" - max_pct = runes.BROWN_PCT_MAX if target["color"] == "brown" else runes.PCT_MAX + max_pct = runes.max_pct(target["color"]) current = target.get("pct", 0) if current >= max_pct: return "Already max roll" sac_set = set(sacrificed_ids) - if len(sac_set) != 10: - return "Pick exactly 10 runes to sacrifice" + if len(sac_set) != runes.RUNE_SACRIFICE_COST: + return f"Pick exactly {runes.RUNE_SACRIFICE_COST} runes to sacrifice" if rune_id in sac_set: return "Cannot sacrifice the rune being upgraded" by_id = {r["id"]: r for r in rune_list} @@ -629,20 +695,6 @@ def add_tower_packs(count: int) -> None: save(data) -def convert_water_to_pack(pack_type: str) -> bool: - """Spend 5 water from the pool to gain one pack of the chosen type.""" - data = load() - if pack_type not in REWARD_PACK_TYPES: - return False - if data.get("water", 0) < 5: - return False - data["water"] -= 5 - packs = data.setdefault("packs", {t: 0 for t in PACK_TYPES}) - packs[pack_type] = packs.get(pack_type, 0) + 1 - save(data) - return True - - def evolve(name) -> bool: """Evolve at the milestone level by consuming duplicates.""" data = load() @@ -750,7 +802,7 @@ def add_lesser_pack() -> list: def add_pack(pack_type: str, count: int = 1) -> list: - """Grant `count` packs of a specific type. Returns the granted type list.""" + """Add `count` seed packs of `pack_type`.""" data = load() packs = data.setdefault("packs", {t: 0 for t in PACK_TYPES}) packs[pack_type] = packs.get(pack_type, 0) + count @@ -758,6 +810,33 @@ def add_pack(pack_type: str, count: int = 1) -> list: return [pack_type] * count +# Pack shop (seed packs page): coins buy packs. Tower packs can't be bought. +PACK_COSTS = { + "lesser": 50, + "general": 100, + "radiant": 100, + "nocturnal": 100, + "ice": 100, + "garden": 100, + "wildflower": 100, +} + + +def buy_pack(pack_type: str) -> str: + """Buy a pack of `pack_type` with coins. Returns '' on success or a reason.""" + cost = PACK_COSTS.get(pack_type) + if cost is None: + return "That pack can't be bought" + data = load() + if data.get("coins", 0) < cost: + return "Not enough coins" + data["coins"] -= cost + packs = data.setdefault("packs", {t: 0 for t in PACK_TYPES}) + packs[pack_type] = packs.get(pack_type, 0) + 1 + save(data) + return "" + + def battle_wins() -> int: """Total number of battle wins the player has recorded.""" return load().get("wins", 0) @@ -1189,6 +1268,23 @@ def auto_farm() -> str: return "" +def auto_plant() -> str: + """If the player owns an auto planter that's toggled on, automatically plant + a retrieved seed into the first empty plot (if any seeds are available). + Returns '' on success or when idle, else a reason.""" + data = load() + if not data.get("auto_planter", False): + return "No auto planter" + if not data.get("auto_planter_active", False): + return "Auto planter off" + soil = data.setdefault("soil", {"seed_cd_until": 0.0, "seeds": [], "plots": []}) + if not soil.get("seeds", []): + return "" # nothing to plant + if len(soil.get("plots", [])) >= unlocked_plots(data, soil): + return "" # no empty plot + return plant_seed(0) + + def harvest_plot(index: int) -> str: """Harvest a grown plot, gaining a copy (duplicate) of the plant.""" data = load() diff --git a/engine/plants.py b/engine/plants.py index 4f36782..3af56f9 100644 --- a/engine/plants.py +++ b/engine/plants.py @@ -281,7 +281,7 @@ POOL: Dict[str, dict] = { ]), "Butterfly": dict(role=ROLE_SUPPORT, type=TYPE_GARDEN, stats=(30, 40, 26, 40), skills=[ - _sk("Nectar", power=20, kind="heal", target=TARGET_ALLY, cd=2, + _sk("Nectar", power=15, kind="heal", target=TARGET_ALLY, cd=2, desc="Heal an ally (scales with Attack)"), _sk("Cocoon", power=25, kind="shield", target=TARGET_ALLY, cd=2, desc="Shield an ally (scales with Attack)"), diff --git a/engine/relics.py b/engine/relics.py index 1dd13cf..8c5d410 100644 --- a/engine/relics.py +++ b/engine/relics.py @@ -5,9 +5,9 @@ from typing import Callable, Iterable, List, Optional from . import runes from .skills import ( - S_ATTACK_DOWN, S_ATTACK_UP, S_DEFENSE_DOWN, S_DEFENSE_UP, + S_ATTACK_DOWN, S_ATTACK_UP, S_CRIT_DOWN, S_DEFENSE_DOWN, S_DEFENSE_UP, S_HEAL_BOOST, S_HOT, S_PREVENT_FIRST_DAMAGE, S_SHIELD, S_SNOWFLAKES, S_SPEED_DOWN, - S_SPEED_UP, S_VULNERABLE, + S_SPEED_UP, S_VULNERABLE, SHIELD_DURATION, ) @@ -70,7 +70,7 @@ def _crit(pct): def _shield(pct): def apply(battle): for u in _players(battle): - u.status[S_SHIELD] = u.status.get(S_SHIELD, 0) + int(u.max_hp * pct) + u.status.setdefault(S_SHIELD, []).append((int(u.max_hp * pct), SHIELD_DURATION)) return apply diff --git a/engine/roster.py b/engine/roster.py index 554d6f2..c70355a 100644 --- a/engine/roster.py +++ b/engine/roster.py @@ -20,6 +20,12 @@ FLOOR_RARE_PLANTS = ["Marigold", "Daffodil", "Peony", "Primrose", # Low-rarity tank plants used as enemy tanks on later floors. FLOOR_TANK_PLANTS = ["Marigold", "Daffodil", "Venus Flytrap"] +# Floor enemies scale up faster and hit harder / are beefier than player units +# of the same level (a flat boost on top of the leveled stats). +FLOOR_ENEMY_LEVEL_STEP = 4 # +1 enemy level every 4 floors (was every 5) +FLOOR_ENEMY_ATK_MULT = 1.20 # +20% attack (more damage) +FLOOR_ENEMY_HP_MULT = 1.25 # +25% max health (tankier) + def floor_enemy_count(floor: int) -> int: """Number of enemies on a battle floor: 1 on floors 1-3, 2 on 4-9, 3 on @@ -39,7 +45,11 @@ def floor_enemy_names(floor: int, player_type: str) -> List[str]: 4 from floor 16. Teams mix pinwheels, butterflies and toadstools, and duplicates are allowed (e.g. two pinwheels). Tank plants join from floor 40 and low-rarity plants from floor 45, replacing critter slots so a team - never exceeds 4 enemies.""" + never exceeds 4 enemies. Boss floors field the boss alone.""" + from . import bosses + boss = bosses.boss_for_floor(floor) + if boss: + return [boss] count = floor_enemy_count(floor) # Lead with an attacker; the rest cycle through the trio so each floor gets # a deterministic mix of roles (with repeats) built from the critters. @@ -58,24 +68,29 @@ def floor_enemy_names(floor: int, player_type: str) -> List[str]: def roll_enemy_types(names: List[str], player_type: str, floor: int) -> List[str]: """Types for a floor's enemies (parallel to `names`). The floor 1-3 pinwheel is - always the type the player is strong against; other critters roll a random - type; plants keep their own fixed type.""" - import random + always the type the player is strong against; other critters get a fixed type + derived from the floor (no rerolling — the same floor always fields the same + team, and duplicate types within a team are allowed); plants keep their own + fixed type.""" + from . import bosses types = [] for i, n in enumerate(names): - if n in VARIABLE_TYPE_UNITS: + if bosses.is_boss(n): + types.append(bosses.boss_type(n)) + elif n in VARIABLE_TYPE_UNITS: if floor <= 3: types.append(TYPE_BEATS.get(player_type, "garden")) else: - types.append(random.choice(ALL_TYPES)) + types.append(ALL_TYPES[(floor * 7 + i * i) % len(ALL_TYPES)]) else: types.append(POOL[n]["type"]) return types def floor_enemy_level(floor: int) -> int: - """Enemy level for a floor (ramps toward ~20 at floor 100).""" - return 1 + (floor - 1) // 5 + """Enemy level for a floor (ramps one level every FLOOR_ENEMY_LEVEL_STEP + floors, steeper than the old every-5 curve).""" + return 1 + (floor - 1) // FLOOR_ENEMY_LEVEL_STEP def make_floor_enemies(floor: int, player_type: str) -> List[Unit]: @@ -88,11 +103,21 @@ def make_floor_enemies(floor: int, player_type: str) -> List[Unit]: def build_floor_enemies(names: List[str], types: List[str], floor: int) -> List[Unit]: """Build enemy units from an already-rolled name/type list (so the picker and - the actual battle always show the same enemies).""" + the actual battle always show the same enemies). Floor enemies also get a + flat attack/health boost so they out-stat player units of the same level. + Boss floors build the boss instead.""" + from . import bosses + if names and bosses.is_boss(names[0]): + return [bosses.make_boss(names[0], floor)] level = floor_enemy_level(floor) stage = max(1, min(5, 1 + (floor - 1) // 20)) - return [make_leveled(n, TEAM_ENEMY, level, stage, ptype=t) - for n, t in zip(names, types)] + units = [make_leveled(n, TEAM_ENEMY, level, stage, ptype=t) + for n, t in zip(names, types)] + for u in units: + u.attack = int(u.attack * FLOOR_ENEMY_ATK_MULT) + u.max_hp = int(u.max_hp * FLOOR_ENEMY_HP_MULT) + u.hp = u.max_hp + return units def difficulty_pool(difficulty: int) -> List[str]: diff --git a/engine/runes.py b/engine/runes.py index 667c966..ca994ae 100644 --- a/engine/runes.py +++ b/engine/runes.py @@ -3,18 +3,19 @@ from __future__ import annotations import random # Rune kinds (gems). Each rune is an item equipped into a plant's slots. -RUNE_COLORS = ("sapphire", "ruby", "amethyst", "jade", "brown") +RUNE_COLORS = ("sapphire", "ruby", "amethyst", "jade", "brown", "pearl") RUNE_NAMES = { "sapphire": "Sapphire Rune", "ruby": "Ruby Rune", "amethyst": "Amethyst Rune", "jade": "Jade Rune", "brown": "Brown Rune", + "pearl": "Pearl Rune", } -# Tier classification: sapphire/ruby/amethyst/jade are Tier 1, brown is Tier 2. +# Tier classification: sapphire/ruby/amethyst/jade are Tier 1, brown & pearl Tier 2. TIER1_COLORS = ("sapphire", "ruby", "amethyst", "jade") -TIER2_COLORS = ("brown",) +TIER2_COLORS = ("brown", "pearl") RUNE_TIERS = {c: 1 for c in TIER1_COLORS} RUNE_TIERS.update({c: 2 for c in TIER2_COLORS}) @@ -25,6 +26,7 @@ RUNE_ICON_FILES = { "jade": "jade_rune", "amethyst": "amethyst_rune", "brown": "rune_brown", + "pearl": "pearl_rune", } # Old color names kept in earlier saves, mapped to the current gem names. @@ -43,31 +45,39 @@ def canonical_color(color: str) -> str: # Primitive effects: each rune rolls its own stat and stacks additively with # other equipped runes of the same effect. Brown is rarer and rolls lower, but -# turns part of the damage this plant deals into a Wilt. +# turns part of the damage this plant deals into a Wilt. Pearl rolls a chunk of +# critical hit chance. RUNE_EFFECTS = { "ruby": "damage", # +damage dealt "sapphire": "shield", # +shielding "jade": "healing", # +healing received "amethyst": "damage_taken", # -damage taken "brown": "wilt", # damage dealt also Wils the target + "pearl": "crit", # +critical hit chance } PCT_MIN = 25 PCT_MAX = 35 BROWN_PCT_MIN = 5 BROWN_PCT_MAX = 15 +PEARL_PCT_MIN = 20 +PEARL_PCT_MAX = 40 # a plant can't stack more than this many runes of the same type MAX_RUNES_PER_TYPE = 2 +# runes sacrificed to reroll one rune to a higher stat +RUNE_SACRIFICE_COST = 3 # coin costs to buy a random rune of a tier in the runes shop T1_RUNE_COST = 100 T2_RUNE_COST = 150 -# brown drops less often than the other runes (relative weights) -RUNE_WEIGHTS = {"sapphire": 1.0, "ruby": 1.0, "amethyst": 1.0, "jade": 1.0, "brown": 0.75} +# brown & pearl drop less often than the other runes (relative weights) +RUNE_WEIGHTS = {"sapphire": 1.0, "ruby": 1.0, "amethyst": 1.0, "jade": 1.0, + "brown": 0.75, "pearl": 0.75} _EFFECT_TEXTS = { "ruby": "+{pct}% damage dealt", "sapphire": "+{pct}% shielding", "jade": "+{pct}% healing", "amethyst": "-{pct}% damage taken", "brown": "deals {pct}% of damage as Wilt", + "pearl": "+{pct}% critical chance", } RUNE_SUMMARIES = { "ruby": "Increases damage dealt", @@ -75,6 +85,7 @@ RUNE_SUMMARIES = { "jade": "Increases healing received", "amethyst": "Reduces damage taken", "brown": "Deals a portion of damage as Wilt", + "pearl": "Increases critical hit chance", } MAX_RUNE_SLOTS = 3 @@ -91,12 +102,23 @@ def random_color() -> str: def roll_pct(color: str = None) -> int: - """Roll a rune's stat percentage. Brown rolls 5-15; the rest 25-35.""" + """Roll a rune's stat percentage. Brown rolls 5-15, pearl 20-40, the rest 25-35.""" if color == "brown": return random.randint(BROWN_PCT_MIN, BROWN_PCT_MAX) + if color == "pearl": + return random.randint(PEARL_PCT_MIN, PEARL_PCT_MAX) return random.randint(PCT_MIN, PCT_MAX) +def max_pct(color: str) -> int: + """The highest stat a rune of `color` can roll (brown/pearl have their own caps).""" + if color == "brown": + return BROWN_PCT_MAX + if color == "pearl": + return PEARL_PCT_MAX + return PCT_MAX + + def name(color: str) -> str: return RUNE_NAMES.get(color, "Rune") @@ -106,11 +128,11 @@ def tier(color: str) -> int: def roll_ratio(rune) -> float: - """How close a rune's roll is to its own maximum (0..1). Brown's 5-15 range - is compared to its 15 cap, so a maxed brown ranks equally with a maxed - yellow even though 15 < 35.""" - max_pct = BROWN_PCT_MAX if rune.get("color") == "brown" else PCT_MAX - return rune.get("pct", 0) / max_pct + """How close a rune's roll is to its own maximum (0..1). Each color is + compared to its own cap, so a maxed brown or pearl ranks equally with a + maxed ruby even though 15 < 35.""" + cap = max_pct(rune.get("color")) + return rune.get("pct", 0) / cap def effect_text(color: str, pct: int) -> str: @@ -124,6 +146,7 @@ _CARD_TEXTS = { "jade": "+{pct}% heal", "amethyst": "-{pct}% taken", "brown": "Wilt {pct}%", + "pearl": "+{pct}% crit", } @@ -149,9 +172,11 @@ def summary(color: str) -> str: def roll_range(color: str) -> str: - """The stat range a rune of `color` rolls between (brown is lower).""" + """The stat range a rune of `color` rolls between (brown/pearl are lower).""" if color == "brown": return f"{BROWN_PCT_MIN}–{BROWN_PCT_MAX}%" + if color == "pearl": + return f"{PEARL_PCT_MIN}–{PEARL_PCT_MAX}%" return f"{PCT_MIN}–{PCT_MAX}%" diff --git a/engine/skills.py b/engine/skills.py index 3ed33ee..cb06915 100644 --- a/engine/skills.py +++ b/engine/skills.py @@ -110,6 +110,7 @@ S_WILT = "wilt" S_DOT = "dot" S_HOT = "hot" S_SHIELD = "shield" +SHIELD_DURATION = 3 # turns a shield lasts before decaying (per application, doesn't refresh) S_ICICLES = "icicles" S_SNOWFLAKES = "snowflakes" S_ZINNIA_WEAKEN = "zinnia_weaken" diff --git a/ideas/test_ignore_me.txt b/ideas/test_ignore_me.txt new file mode 100644 index 0000000..e69de29 diff --git a/main.py b/main.py index 743ab15..f812dee 100644 --- a/main.py +++ b/main.py @@ -1,7 +1,7 @@ from collections import Counter from assets import icon -from engine import collection, runes +from engine import bosses, collection, runes from engine.battle import Battle from engine.relics import RELIC_BY_KEY, grant_rune_rewards, roll_relics, rune_reward_count from engine.roster import make_enemy_team, pick_team, player_team_level, player_team_stage @@ -24,6 +24,7 @@ def _pack_reward_items(pack_types): }) return items +#test_ignore def _rune_reward_item(rune): """Reward entry for a rune drop (label + rune sprite path).""" @@ -51,7 +52,8 @@ def _totals_txt(total_water, total_packs, run_relics): def _battle_win_reward(floor): """Grant and describe a floor-battle win: a lesser pack, or on every 5th win (5, 10, 15, ...) a better general/type-boosted pack instead. Advances the - floor. Runes can drop on any win regardless.""" + floor. Runes can drop on any win regardless. Boss floors additionally grant + a boss-specific rune drop at a much higher chance and mark the boss fought.""" collection.advance_floor() wins = collection.record_win() if wins % 5 == 0: @@ -61,6 +63,12 @@ def _battle_win_reward(floor): rune = collection.roll_battle_rune() if rune: reward.append(_rune_reward_item(rune)) + boss = bosses.boss_for_floor(floor) + if boss: + collection.mark_boss_fought(boss) + bdrop = collection.boss_rune_drop(boss) + if bdrop: + reward.append(_rune_reward_item(bdrop)) return reward @@ -255,7 +263,10 @@ def main(): floor = collection.floor_progress() enemy_names = floor_enemy_names(floor, player_type) enemy_types = roll_enemy_types(enemy_names, player_type, floor) - enemy_levels = [floor_enemy_level(floor)] * len(enemy_names) + enemy_levels = [ + bosses.boss_floor_level(floor) if bosses.is_boss(n) else floor_enemy_level(floor) + for n in enemy_names + ] from ui.picker import TeamSelect ts = TeamSelect(initial_enemies=enemy_names, difficulty=floor, enemy_types=enemy_types, no_roll=True, @@ -269,7 +280,7 @@ def main(): allies, enemies = result collection.mark_owned(allies) - collection.mark_found(enemies) + collection.mark_found([n for n in enemies if not bosses.is_boss(n)]) players = pick_team(allies, TEAM_PLAYER) enemy_units = build_floor_enemies(enemy_names, enemy_types, floor) battle = Battle(players, enemy_units) diff --git a/tests/test_battle.py b/tests/test_battle.py index 2abb199..b0eaa1a 100644 --- a/tests/test_battle.py +++ b/tests/test_battle.py @@ -155,6 +155,28 @@ class ShieldWiltDotTest(unittest.TestCase): self.assertEqual(t.hp, 100) self.assertNotIn(S_SHIELD, t.status) + def test_heal_random_ally_prefers_injured_ally(self): + flutter = Skill("Flutter", power=40, target=TARGET_ENEMY, mechanic="heal_random_ally") + daisy = make_unit("Daisy", TEAM_PLAYER, "radiant", atk=50, skills=[flutter]) + full = make_unit("Full", TEAM_PLAYER, "radiant", hp=100) + hurt = make_unit("Hurt", TEAM_PLAYER, "radiant", hp=100) + hurt.hp = 50 + enemy = make_unit("E", TEAM_ENEMY, "garden", hp=500) + b = Battle([daisy, full, hurt], [enemy]) + b.start() + b.use_skill(daisy, flutter, enemy) + self.assertEqual(hurt.hp, 90) # the injured ally got healed + self.assertEqual(full.hp, 100) # full-HP ally untouched + + def test_heal_random_ally_noop_when_all_full(self): + flutter = Skill("Flutter", power=40, target=TARGET_ENEMY, mechanic="heal_random_ally") + daisy = make_unit("Daisy", TEAM_PLAYER, "radiant", atk=50, skills=[flutter]) + enemy = make_unit("E", TEAM_ENEMY, "garden", hp=500) + b = Battle([daisy], [enemy]) + b.start() + b.use_skill(daisy, flutter, enemy) + self.assertFalse(any(isinstance(l, dict) and "recovers" in l["text"] for l in b.log)) # nothing healed + def test_wilt_ticks_over_three_turns(self): a = make_unit("A", TEAM_PLAYER, "radiant", atk=50, skills=[Skill("Hit", 10, target=TARGET_ENEMY)]) t = make_unit("T", TEAM_ENEMY, "garden", dfn=20, hp=500, spd=5) @@ -194,6 +216,45 @@ class ShieldWiltDotTest(unittest.TestCase): self.assertEqual(t.hp, 410) self.assertNotIn(S_DOT, t.status) + def test_shield_decays_after_3_turns(self): + t = make_unit("T", TEAM_ENEMY, "garden", hp=500) + b = Battle([make_unit("A", TEAM_PLAYER, "radiant")], [t]) + b.start() + b._shield(t, 30) + self.assertEqual(b._shield_total(t), 30) + b._end_turn_status(t) + self.assertEqual(b._shield_total(t), 30) # 3 -> 2 + b._end_turn_status(t) + self.assertEqual(b._shield_total(t), 30) # 2 -> 1 + b._end_turn_status(t) + self.assertEqual(b._shield_total(t), 0) # gone after the 3rd turn + self.assertNotIn(S_SHIELD, t.status) + + def test_stacked_shields_decay_independently(self): + t = make_unit("T", TEAM_ENEMY, "garden", hp=500) + b = Battle([make_unit("A", TEAM_PLAYER, "radiant")], [t]) + b.start() + b._shield(t, 30) + b._end_turn_status(t) # first: 3 -> 2 + b._shield(t, 40) # stack a new one (doesn't refresh the old) + b._end_turn_status(t) # first: 2 -> 1, second: 3 -> 2 + b._end_turn_status(t) # first expires, second: 2 -> 1 + self.assertEqual(b._shield_total(t), 40) # only the newer 40 remains + b._end_turn_status(t) # second expires too + self.assertEqual(b._shield_total(t), 0) + + def test_shield_absorption_consumes_applications_in_order(self): + t = make_unit("T", TEAM_ENEMY, "garden", hp=500) + b = Battle([make_unit("A", TEAM_PLAYER, "radiant")], [t]) + b.start() + b._shield(t, 30) + b._shield(t, 40) + b._absorb(None, t, 50) # 30 from the old shield, 20 from the new one + self.assertEqual(b._shield_total(t), 20) + b._absorb(None, t, 20) # finishes the new shield + self.assertEqual(b._shield_total(t), 0) + self.assertEqual(t.hp, 500) + class MechanicsTest(unittest.TestCase): def test_sleep_skips_until_two_hits(self): @@ -487,7 +548,7 @@ class MechanicsTest(unittest.TestCase): enemy.status["wilt"] = (30, 3) enemy.status["dot"] = [(10, 2)] enemy.status["vulnerable"] = 1 - zinnia.status["shield"] = 10 # one self effect only + zinnia.status["shield"] = [(10, 3)] # one self effect only self.assertIs(b.best_skill(zinnia), glitter) def test_zinnia_targets_most_effect_rich_enemy(self): @@ -743,5 +804,48 @@ class TowerInjectionTest(unittest.TestCase): self.assertNotEqual(base.name, inj["skill"]["name"]) +class TurnActionLimitTest(unittest.TestCase): + """A unit must act only once per turn (spam-clicking must not multi-cast).""" + + def _battle(self, skills): + a = make_unit("A", TEAM_PLAYER, "radiant", atk=50, skills=skills) + t = make_unit("T", TEAM_ENEMY, "garden", dfn=20, hp=1000) + b = Battle([a], [t]) + b.start() + return b, a, t + + def test_unit_cannot_use_two_skills_in_one_turn(self): + hit1 = Skill("Hit1", power=10, target=TARGET_ENEMY) + hit2 = Skill("Hit2", power=10, target=TARGET_ENEMY) + b, a, t = self._battle([hit1, hit2]) + self.assertTrue(b.use_skill(a, hit1, t)) + self.assertFalse(b.use_skill(a, hit2, t)) # already acted + self.assertTrue(a.acted) + + def test_same_skill_cannot_be_spammed(self): + hit = Skill("Hit", power=10, target=TARGET_ENEMY, cooldown=0) + b, a, t = self._battle([hit]) + self.assertTrue(b.use_skill(a, hit, t)) + self.assertFalse(b.use_skill(a, hit, t)) # acted flag blocks the re-cast + + def test_extra_action_skill_still_usable_after_acting(self): + hit = Skill("Hit", power=10, target=TARGET_ENEMY) + extra = Skill("Extra", power=5, target=TARGET_ENEMY, extra_action=True) + b, a, t = self._battle([hit, extra]) + self.assertTrue(b.use_skill(a, hit, t)) + self.assertTrue(b.use_skill(a, extra, t)) # extra action allowed after acting + self.assertTrue(a.acted) + + def test_no_extra_actions_after_act_limit_exhausted(self): + hit = Skill("Hit", power=10, target=TARGET_ENEMY) + extra = Skill("Extra", power=5, target=TARGET_ENEMY, extra_action=True) + extra2 = Skill("Extra2", power=5, target=TARGET_ENEMY, extra_action=True) + b, a, t = self._battle([hit, extra, extra2]) + self.assertTrue(b.use_skill(a, hit, t)) + self.assertTrue(b.use_skill(a, extra, t)) + self.assertTrue(b.use_skill(a, extra2, t)) + self.assertFalse(b.use_skill(a, hit, t)) # acted + cooldown: still blocked + + if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/tests/test_bosses.py b/tests/test_bosses.py new file mode 100644 index 0000000..7de290f --- /dev/null +++ b/tests/test_bosses.py @@ -0,0 +1,139 @@ +import atexit +import os +import pathlib +import tempfile +import unittest + +# Point the engine at a fresh empty save to keep collection-dependent tests hermetic. +import engine.collection as collection +from engine import bosses +from engine.battle import Battle +from engine.plants import make_leveled +from engine.unit import TEAM_ENEMY, TEAM_PLAYER + +_fd, _tmp_path = tempfile.mkstemp(suffix=".json") +os.close(_fd) +_TMP = pathlib.Path(_tmp_path) +_ORIG_DATA_FILE = collection._DATA_FILE +collection._DATA_FILE = _TMP + + +@atexit.register +def _restore_collection(): + collection._DATA_FILE = _ORIG_DATA_FILE + if _TMP.exists(): + _TMP.unlink() + + +class BossSchedulingTest(unittest.TestCase): + def test_boss_appears_on_multiples_of_20(self): + self.assertEqual(bosses.boss_for_floor(20), "Stones") + self.assertEqual(bosses.boss_for_floor(40), "Stones") + self.assertEqual(bosses.boss_for_floor(100), "Stones") + self.assertIsNone(bosses.boss_for_floor(19)) + self.assertIsNone(bosses.boss_for_floor(1)) + + def test_boss_stats_are_extreme(self): + u = bosses.make_boss("Stones", 20) + # very low speed, medium defense, high health, medium attack + self.assertLessEqual(u.speed, 40) + self.assertGreaterEqual(u.max_hp, 900) + self.assertGreaterEqual(u.defense, 80) + self.assertTrue(60 <= u.attack <= 200) + + +class BossMechanicTest(unittest.TestCase): + def _battle(self): + a = make_leveled("Rose", TEAM_PLAYER, 20, 1) + a.max_hp = 5000 + a.hp = 5000 + u = bosses.make_boss("Stones", 20) + b = Battle([a], [u]) + b.start() + return b, a, u + + def test_landslide_blocked_until_three_stacks(self): + b, a, u = self._battle() + b.current = u + pebble, landslide = u.skills + u.acted = False + self.assertFalse(b.use_skill(u, landslide, a)) # 0 stacks: blocked + self.assertEqual(b.valid_skill_targets(u, landslide), []) + for _ in range(3): + u.acted = False + self.assertTrue(b.use_skill(u, pebble, a)) + self.assertEqual(u.status["boss_stacks"], 3) + u.acted = False + self.assertTrue(b.use_skill(u, landslide, a)) # now available + self.assertEqual(u.status["boss_stacks"], 0) # released + + def test_boss_stacks_cap_at_three(self): + b, a, u = self._battle() + b.current = u + pebble, _ = u.skills + for _ in range(6): + u.acted = False + self.assertTrue(b.use_skill(u, pebble, a)) + self.assertEqual(u.status["boss_stacks"], 3) # never exceeds 3 + + def test_boss_ai_pebbles_then_landslides_then_repeats(self): + b, a, u = self._battle() + moves = [] + guard = 0 + while len(moves) < 7 and guard < 120 and b.winner is None: + guard += 1 + if b.current is u and not u.acted: + before = u.status.get("boss_stacks", 0) + used = b.enemy_ai(u) + after = u.status.get("boss_stacks", 0) + if used: + moves.append("Pebble" if after > before else + ("Landslide" if before >= 3 and after == 0 else "?")) + b.next_turn() + self.assertEqual(moves[:4], ["Pebble", "Pebble", "Pebble", "Landslide"]) + self.assertEqual(moves[4:], ["Pebble", "Pebble", "Pebble"]) + + def test_landslide_hits_harder_than_pebble(self): + b, a, u = self._battle() + b.current = u + pebble, landslide = u.skills + for _ in range(3): + u.acted = False + b.use_skill(u, pebble, a) + u.acted = False + pebble_dmg = b._hit_damage.get(id(a), 0) + a.hp = a.max_hp # reset before landslide + u.status["boss_stacks"] = 3 + b.use_skill(u, landslide, a) + landslide_dmg = b._hit_damage.get(id(a), 0) + self.assertGreater(landslide_dmg, pebble_dmg * 2) + + +class BossRewardTest(unittest.TestCase): + def setUp(self): + data = collection.load() + data["owned"] = ["Rose"] + data["bosses_fought"] = [] + data["runes"] = [] + collection.save(data) + + def test_mark_boss_fought(self): + self.assertEqual(collection.bosses_fought(), set()) + collection.mark_boss_fought("Stones") + self.assertEqual(collection.bosses_fought(), {"Stones"}) + + def test_boss_rune_drop_is_high_chance_and_select(self): + colors = set() + total = 0 + for _ in range(300): + r = collection.boss_rune_drop("Stones") + if r: + total += 1 + self.assertIn(r["color"], ("ruby", "amethyst")) + colors.add(r["color"]) + self.assertGreaterEqual(total, 150) # ~80% chance + self.assertEqual(colors, {"ruby", "amethyst"}) + + +if __name__ == "__main__": + unittest.main() \ No newline at end of file diff --git a/tests/test_relics.py b/tests/test_relics.py index dce12f8..ac7230a 100644 --- a/tests/test_relics.py +++ b/tests/test_relics.py @@ -103,7 +103,8 @@ class RelicApplyTest(unittest.TestCase): def test_shield_relic(self): b = _battle("iron_bark") for u in b.players: - self.assertGreaterEqual(u.status.get(S_SHIELD, 0), int(u.max_hp * 0.09)) + total = sum(amount for amount, _ in u.status.get(S_SHIELD, [])) + self.assertGreaterEqual(total, int(u.max_hp * 0.09)) def test_pct_hp_relic(self): base = make_leveled("Zinnia", TEAM_PLAYER, 1, 1) @@ -156,7 +157,8 @@ class RelicApplyTest(unittest.TestCase): def test_multiple_relics_stack(self): b = _battle("iron_bark", "morning_dew", "chilling_gust") for u in b.players: - self.assertGreaterEqual(u.status.get(S_SHIELD, 0), 1) + total = sum(amount for amount, _ in u.status.get(S_SHIELD, [])) + self.assertGreaterEqual(total, 1) self.assertEqual(u.status[S_ATTACK_UP], (10, 1)) for u in b.enemies: self.assertEqual(u.status["speed_down"], (8, 1)) diff --git a/tests/test_runes.py b/tests/test_runes.py index 65e347b..9301c0a 100644 --- a/tests/test_runes.py +++ b/tests/test_runes.py @@ -131,9 +131,9 @@ class RuneTest(unittest.TestCase): self.assertIn(r2["id"], free) self.assertNotIn(r1["id"], free) - def _ten_runes(self, data): + def _sac_runes(self, data): ids = [] - for _ in range(10): + for _ in range(runes.RUNE_SACRIFICE_COST): ids.append(collection.add_rune("sapphire", data=data, save_now=False)["id"]) return ids @@ -141,20 +141,20 @@ class RuneTest(unittest.TestCase): r = collection.add_rune("ruby") data = collection.load() data["runes"][0]["pct"] = 25 - sac = self._ten_runes(data) + sac = self._sac_runes(data) collection.save(data) err = collection.reroll_rune(r["id"], sac) self.assertEqual(err, "") new_pct = collection.load()["runes"][0]["pct"] self.assertGreaterEqual(new_pct, 26) # at least 1% better self.assertLessEqual(new_pct, 35) - self.assertEqual(len(collection.load()["runes"]), 1) # 10 consumed + self.assertEqual(len(collection.load()["runes"]), 1) # cost consumed def test_reroll_brown_caps_at_15(self): r = collection.add_rune("brown") data = collection.load() data["runes"][0]["pct"] = 5 - sac = self._ten_runes(data) + sac = self._sac_runes(data) collection.save(data) err = collection.reroll_rune(r["id"], sac) self.assertEqual(err, "") @@ -166,27 +166,27 @@ class RuneTest(unittest.TestCase): r = collection.add_rune("ruby") data = collection.load() data["runes"][0]["pct"] = 35 - sac = self._ten_runes(data) + sac = self._sac_runes(data) collection.save(data) err = collection.reroll_rune(r["id"], sac) self.assertEqual(err, "Already max roll") - self.assertEqual(len(collection.load()["runes"]), 11) # nothing consumed + self.assertEqual(len(collection.load()["runes"]), 1 + runes.RUNE_SACRIFICE_COST) # nothing consumed - def test_reroll_requires_exactly_ten(self): + def test_reroll_requires_exact_sacrifice_count(self): r = collection.add_rune("ruby") data = collection.load() data["runes"][0]["pct"] = 25 - sac = self._ten_runes(data) + sac = self._sac_runes(data) collection.save(data) - self.assertEqual(collection.reroll_rune(r["id"], sac[:9]), - "Pick exactly 10 runes to sacrifice") + self.assertEqual(collection.reroll_rune(r["id"], sac[:runes.RUNE_SACRIFICE_COST - 1]), + f"Pick exactly {runes.RUNE_SACRIFICE_COST} runes to sacrifice") def test_reroll_rejects_target_in_sacrifices(self): r = collection.add_rune("ruby") data = collection.load() data["runes"][0]["pct"] = 25 - sac = self._ten_runes(data) - sac[0] = r["id"] # 10 unique runes, but includes the upgrade target + sac = self._sac_runes(data) + sac[0] = r["id"] # unique runes, but includes the upgrade target collection.save(data) self.assertEqual(collection.reroll_rune(r["id"], sac), "Cannot sacrifice the rune being upgraded") @@ -196,7 +196,7 @@ class RuneTest(unittest.TestCase): r2 = collection.add_rune("sapphire") data = collection.load() data["runes"][0]["pct"] = 25 - sac = self._ten_runes(data) + sac = self._sac_runes(data) sac[0] = r2["id"] # sacrifice the equipped rune collection.save(data) self._evolve_to(self.plant, 1, 10, 2) @@ -338,6 +338,16 @@ class RuneTest(unittest.TestCase): self.assertEqual(len(collection.rune_inventory()), before) self.assertEqual(collection.available_coins(), 50) + def test_pearl_is_t2_crit_rune(self): + self.assertEqual(runes.tier("pearl"), 2) + self.assertEqual(runes.effect_for("pearl"), "crit") + self.assertEqual(runes.max_pct("pearl"), 40) + self.assertEqual(runes.roll_range("pearl"), "20–40%") + for _ in range(50): + self.assertGreaterEqual(runes.roll_pct("pearl"), 20) + self.assertLessEqual(runes.roll_pct("pearl"), 40) + self.assertEqual(runes.name("pearl"), "Pearl Rune") + class RuneBattleEffectTest(unittest.TestCase): def _unit(self, name="A", team=TEAM_PLAYER, ptype="radiant", atk=50, spd=5, @@ -378,7 +388,7 @@ class RuneBattleEffectTest(unittest.TestCase): b = Battle([self._unit()], [t]) b.start() b._shield(t, 100) - self.assertEqual(t.status["shield"], 130) + self.assertEqual(sum(a for a, _ in t.status["shield"]), 130) def test_yellow_rune_boosts_healing(self): heal = Skill("Mend", power=40, kind="heal", target="ally") @@ -412,6 +422,25 @@ class RuneBattleEffectTest(unittest.TestCase): b.use_skill(a, hit, t) self.assertEqual(t.status["wilt"][1], 3) # lasts 3 turns + def test_pearl_rune_raises_crit_chance(self): + a = self._unit(runes=[("crit", 0.30)]) + b = Battle([a], [self._unit("T", TEAM_ENEMY, "garden")]) + b.start() + self.assertAlmostEqual(b._crit(a), 0.30) + + def test_pearl_runes_stack_additively(self): + a = self._unit(runes=[("crit", 0.20), ("crit", 0.20)]) + b = Battle([a], [self._unit("T", TEAM_ENEMY, "garden")]) + b.start() + self.assertAlmostEqual(b._crit(a), 0.40) + + def test_pearl_rune_adds_on_top_of_base_crit(self): + a = self._unit(runes=[("crit", 0.25)]) + a.crit = 0.10 + b = Battle([a], [self._unit("T", TEAM_ENEMY, "garden")]) + b.start() + self.assertAlmostEqual(b._crit(a), 0.35) + if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/tests/test_soil.py b/tests/test_soil.py index 8df3f38..5cc9d3b 100644 --- a/tests/test_soil.py +++ b/tests/test_soil.py @@ -219,6 +219,8 @@ class AutoFarmerTest(unittest.TestCase): data["fertilizer"] = 10 data["coins"] = 100 data["auto_farmer"] = False + data["auto_planter"] = False + data["auto_planter_active"] = False collection.save(data) def _stalled_plot(self): @@ -308,6 +310,100 @@ class AutoFarmerTest(unittest.TestCase): self.assertEqual(len(state["seeds"]), 1) # seed not planted self.assertEqual(state["plots"][0]["stage"], 1) # stalled plot advanced + def test_buy_auto_planter(self): + data = collection.load() + data["coins"] = 300 + collection.save(data) + self.assertEqual(collection.buy_auto_planter(), "") + self.assertTrue(collection.auto_planter_owned()) + self.assertTrue(collection.auto_planter_active()) + self.assertEqual(collection.available_coins(), 100) + self.assertNotEqual(collection.buy_auto_planter(), "") # already owned + + def test_buy_auto_planter_requires_coins(self): + data = collection.load() + data["coins"] = 50 + collection.save(data) + self.assertNotEqual(collection.buy_auto_planter(), "") + self.assertFalse(collection.auto_planter_owned()) + + def test_toggle_auto_planter(self): + data = collection.load() + data["coins"] = 300 + collection.save(data) + collection.buy_auto_planter() + self.assertFalse(collection.toggle_auto_planter()) # turned off + self.assertFalse(collection.auto_planter_active()) + self.assertTrue(collection.toggle_auto_planter()) # back on + + def test_auto_plant_plants_seed_into_empty_plot(self): + data = collection.load() + data["coins"] = 300 + data["soil"]["seeds"] = [{"plant": "Rose"}, {"plant": "Lavender"}] + collection.save(data) + self.assertEqual(collection.buy_auto_planter(), "") + self.assertEqual(collection.auto_plant(), "") + state = collection.soil_state() + self.assertEqual(len(state["plots"]), 1) + self.assertEqual(state["plots"][0]["plant"], "Rose") # first seed planted + self.assertEqual(len(state["seeds"]), 1) + + def test_auto_plant_respects_toggle_and_requirements(self): + data = collection.load() + data["coins"] = 300 + data["soil"]["seeds"] = [{"plant": "Rose"}] + collection.save(data) + self.assertEqual(collection.auto_plant(), "No auto planter") # not owned + collection.buy_auto_planter() + collection.toggle_auto_planter() # turn off + self.assertEqual(collection.auto_plant(), "Auto planter off") + collection.toggle_auto_planter() + data = collection.load() + data["soil"]["seeds"] = [] + collection.save(data) + self.assertEqual(collection.auto_plant(), "") # nothing to plant -> idle + self.assertEqual(len(collection.soil_state()["plots"]), 0) + + def test_auto_plant_wont_overfill_plots(self): + data = collection.load() + data["coins"] = 300 + data["soil"]["seeds"] = [{"plant": "Rose"}, {"plant": "Lavender"}] + data["soil"]["plots"] = [{"plant": "Rose", "stage_started_at": 0, "stage": 0, "water": 0}] + collection.save(data) + self.assertEqual(collection.buy_auto_planter(), "") + self.assertEqual(collection.auto_plant(), "") # no free plot -> idle + self.assertEqual(len(collection.soil_state()["plots"]), 1) + + +class PackShopTest(unittest.TestCase): + def setUp(self): + data = collection.load() + data["coins"] = 500 + data["packs"] = {t: 0 for t in collection.PACK_TYPES} + collection.save(data) + + def test_buy_lesser_and_general(self): + self.assertEqual(collection.buy_pack("lesser"), "") + self.assertEqual(collection.buy_pack("general"), "") + self.assertEqual(collection.buy_pack("garden"), "") + self.assertEqual(collection.available_coins(), 500 - 50 - 100 - 100) + packs = collection.pack_counts() + self.assertEqual(packs["lesser"], 1) + self.assertEqual(packs["general"], 1) + self.assertEqual(packs["garden"], 1) + + def test_tower_pack_cannot_be_bought(self): + self.assertEqual(collection.buy_pack("tower"), "That pack can't be bought") + self.assertEqual(collection.pack_counts().get("tower", 0), 0) + self.assertEqual(collection.available_coins(), 500) + + def test_buy_pack_requires_coins(self): + data = collection.load() + data["coins"] = 30 + collection.save(data) + self.assertEqual(collection.buy_pack("lesser"), "Not enough coins") + self.assertEqual(collection.pack_counts().get("lesser", 0), 0) + if __name__ == "__main__": unittest.main() \ No newline at end of file diff --git a/ui/extract.py b/ui/extract.py index f955461..e53f824 100644 --- a/ui/extract.py +++ b/ui/extract.py @@ -27,7 +27,7 @@ class ExtractionScreen: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants — Ability Extraction") + pygame.display.set_caption("Flora — Ability Extraction") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 30) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) diff --git a/ui/main.py b/ui/main.py index 041127e..d015913 100644 --- a/ui/main.py +++ b/ui/main.py @@ -4,10 +4,11 @@ from assets import icon, load_sprite from engine import collection, runes from engine.battle import Battle from engine.dominance import estimate_dominance, resolve_instantly -from engine.plants import PASSIVES, RARITY_COLORS, RARITY_LABELS, plant_rarity +from engine.growth import EVOLVE_COST, EVOLVE_STAGE_AT_LEVEL, can_evolve +from engine.plants import PASSIVES, POOL, RARITY_COLORS, RARITY_LABELS, plant_rarity from engine.relics import RELIC_POOL from engine.skills import EFF_DOT, EFF_HOT, TARGET_ALLY, TARGET_ANY, TARGET_ENEMY -from engine.types import type_multiplier +from engine.types import TYPE_BEATS, type_multiplier from engine.unit import ROLE_NAMES, ROLE_TANK, TEAM_ENEMY, TEAM_PLAYER from ui.menu import _bracket_text, _draw_evo_badge from ui.relics_overview import RelicsOverview @@ -19,8 +20,8 @@ TYPE_COLORS = { "radiant": (245, 200, 90), "nocturnal": (150, 120, 220), "ice": (130, 200, 235), - "garden": (120, 200, 120), - "wildflower": (235, 130, 170), + "garden": (235, 130, 170), + "wildflower": (120, 200, 120), } WIN_W = 1040 WIN_H = 720 @@ -64,13 +65,13 @@ class Game: self.stage = stage self.relics = list(relics) if tower and stage: - caption = f"Plants — Tower — Floor {stage}" + caption = f"Flora — Tower — Floor {stage}" elif stage: - caption = f"Plants — Floor {stage}" + caption = f"Flora — Floor {stage}" elif tower: - caption = "Plants — Tower Battle" + caption = "Flora — Tower Battle" else: - caption = "Plants — 4v4 Turn Battle (prototype)" + caption = "Flora — 4v4 Turn Battle (prototype)" pygame.display.set_caption(caption) self.clock = pygame.time.Clock() self.battle = battle @@ -108,6 +109,12 @@ class Game: self._dt = 0.0 self.back_rect = pygame.Rect(12, 12, 90, 32) self.auto_btn = pygame.Rect(112, 12, 90, 32) + # "Back" confirmation modal + transient tank-redirect notice. + self.confirm_back = False + self.confirm_ok_rect = pygame.Rect(0, 0, 0, 0) + self.confirm_no_rect = pygame.Rect(0, 0, 0, 0) + self.tank_notice = "" + self.tank_notice_until = 0 # Auto-battle unlocks once the player has cleared floor 20 in the # normal stage battles (floor_progress counts the next unbeaten floor). self.auto_unlocked = collection.floor_progress() > 20 @@ -206,6 +213,13 @@ class Game: running = False elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: pos = to_logical(event.pos, self.scale) + if self.confirm_back: + if self.confirm_ok_rect.collidepoint(pos): + self.confirm_back = False + self.battle.winner = TEAM_ENEMY # insta-lose + elif self.confirm_no_rect.collidepoint(pos): + self.confirm_back = False + continue if self.auto_unlocked and self.auto_btn.collidepoint(pos): self.auto_battle = not self.auto_battle continue @@ -219,8 +233,11 @@ class Game: self.reward_acknowledged = True continue if self.back_rect.collidepoint(pos): - outcome = "back" - running = False + if self.battle.winner is None: + self.confirm_back = True + else: + outcome = "back" + running = False else: self._handle_click(pos) elif event.type == pygame.MOUSEMOTION: @@ -294,18 +311,27 @@ class Game: if rect.collidepoint(pos): if sk.cooldown_left > 0: return + if cur.acted and not sk.extra_action: + return # already acted this turn; only extra-action skills remain if oblivion and sk is not weakest: return if sk.target in (TARGET_ENEMY, TARGET_ALLY, TARGET_ANY): - valid = b.valid_skill_targets(cur, sk) - if len(valid) == 1: - # Only one thing it can hit (e.g. last enemy alive, or a - # tank blocking everything): use it straight away. - self.pending_skill = None - self._cast(sk, valid[0]) + if self.pending_skill is sk: + # Clicking the selected skill AGAIN casts it (even if only + # one target is available). With several valid targets the + # player still needs to click one. + valid = b.valid_skill_targets(cur, sk) + if len(valid) == 1: + self.pending_skill = None + self._cast(sk, valid[0]) + else: + self.pending_skill = sk else: - self.pending_skill = sk if self.pending_skill is not sk else None + # First click only SELECTS the skill (it must be clicked + # again, or a target clicked, to cast). + self.pending_skill = sk else: + # No target needed (self / AoE): cast right away. self.pending_skill = None self._cast(sk, None) return @@ -319,8 +345,12 @@ class Game: if self.pending_skill: target = self._resolve_target(unit, self.pending_skill) if target: + if self._was_tank_redirect(unit, self.pending_skill, target): + self._set_tank_notice() self._cast(self.pending_skill, target) - self.pending_skill = None + self.pending_skill = None + # Invalid target (e.g. clicking an enemy with an ally heal/shield + # selected): do nothing and KEEP the skill selected. return if unit.team != TEAM_PLAYER: best = next((s for s in sorted(cur.skills, key=lambda s: s.priority) @@ -328,8 +358,19 @@ class Game: if best: target = self._resolve_target(unit, best) if target: + if self._was_tank_redirect(unit, best, target): + self._set_tank_notice() self._cast(best, target) + def _was_tank_redirect(self, unit, skill, target): + """True when `unit` (a backline enemy) was redirected to a tank.""" + return (skill.target == "enemy" and unit.team != TEAM_PLAYER + and unit.alive and unit.role != "tank" and unit is not target) + + def _set_tank_notice(self): + self.tank_notice = "A tank is protecting that unit — attack the tank first!" + self.tank_notice_until = pygame.time.get_ticks() + 3000 + def _resolve_target(self, unit, skill): b = self.battle if unit in b.valid_skill_targets(b.current, skill): @@ -380,6 +421,8 @@ class Game: def _update(self, dt): b = self.battle + if self.tank_notice and pygame.time.get_ticks() >= self.tank_notice_until: + self.tank_notice = "" self._consume_events() self._advance_hit_queue(dt) if b.winner is not None: @@ -603,9 +646,9 @@ class Game: elif self.stage: title_text = f"Floor {self.stage}" elif self.tower: - title_text = "Plants — Tower Battle" + title_text = "Flora — Tower Battle" else: - title_text = "Plants — 4v4 Turn Battle" + title_text = "Flora — 4v4 Turn Battle" title = self.font.render(title_text, True, TEXT) self.screen.blit(title, title.get_rect(center=(WIN_W // 2, 24))) pygame.draw.rect(self.screen, BTN, self.back_rect, border_radius=6) @@ -636,6 +679,75 @@ class Game: self._draw_reward_popup() if self.relic_overview is not None: self.relic_overview.draw(self.mouse_pos) + if self.tank_notice and pygame.time.get_ticks() < self.tank_notice_until: + self._draw_tank_notice() + if self.confirm_back: + self._draw_confirm_back() + + def _draw_tank_notice(self): + t = self.small.render(self.tank_notice, True, (255, 210, 90)) + bg = pygame.Surface((t.get_width() + 24, t.get_height() + 10), pygame.SRCALPHA) + bg.fill((20, 24, 20, 210)) + rect = t.get_rect(center=(WIN_W // 2, 96)) + self.screen.blit(bg, (rect.x - 12, rect.y - 5)) + self.screen.blit(t, rect) + + def _draw_confirm_back(self): + overlay = pygame.Surface((WIN_W, WIN_H), pygame.SRCALPHA) + overlay.fill((0, 0, 0, 140)) + self.screen.blit(overlay, (0, 0)) + w, h = 460, 170 + panel = pygame.Rect((WIN_W - w) // 2, (WIN_H - h) // 2, w, h) + pygame.draw.rect(self.screen, (32, 38, 32), panel, border_radius=12) + pygame.draw.rect(self.screen, (150, 70, 70), panel, 2, border_radius=12) + title = self.bold.render("Leave the battle?", True, TEXT) + self.screen.blit(title, title.get_rect(center=(panel.centerx, panel.y + 30))) + msg = self.small.render("You will lose this battle.", True, MUTED) + self.screen.blit(msg, msg.get_rect(center=(panel.centerx, panel.y + 58))) + self.confirm_ok_rect = pygame.Rect(panel.centerx - 120, panel.bottom - 54, 100, 36) + self.confirm_no_rect = pygame.Rect(panel.centerx + 20, panel.bottom - 54, 100, 36) + pygame.draw.rect(self.screen, (150, 70, 70), self.confirm_ok_rect, border_radius=8) + ok = self.bold.render("Leave", True, TEXT) + self.screen.blit(ok, ok.get_rect(center=self.confirm_ok_rect.center)) + pygame.draw.rect(self.screen, BTN, self.confirm_no_rect, border_radius=8) + no = self.bold.render("Cancel", True, TEXT) + self.screen.blit(no, no.get_rect(center=self.confirm_no_rect.center)) + + def _defeat_tips(self): + """Contextual tips for the defeat screen, based on the player's state + and the units they just brought into the lost battle.""" + tips = [] + if len(collection.owned()) < len(POOL) and sum(collection.pack_counts().values()) > 0: + tips.append("Try to open packs to gain more allies!") + if collection.available_water() >= 1: + tips.append("You can use water to level up your plants and critters.") + if collection.free_runes(): + tips.append("You can use runes to improve your fighting abilities.") + used = list(self.battle.players) + enemy_types = [e.plant_type for e in self.battle.enemies] + for u in used: + prog = collection.get_progress(u.name) + if can_evolve(prog["level"], prog["stage"], prog.get("duplicates", 0)): + tips.append("Try evolving your plants for better stats.") + break + for u in used: + for etype in enemy_types: + if TYPE_BEATS.get(etype) == u.plant_type: + tips.append(f"Make sure to use the types to your advantage! " + f"{u.plant_type} is weak against {etype}.") + break + else: + continue + break + for u in used: + prog = collection.get_progress(u.name) + target = prog["stage"] + 1 + if (target in EVOLVE_STAGE_AT_LEVEL + and prog["level"] >= EVOLVE_STAGE_AT_LEVEL[target] + and prog.get("duplicates", 0) < EVOLVE_COST[target]): + tips.append("You can plant seeds from your plants to gain more of them.") + break + return tips def _draw_reward_popup(self): b = self.battle @@ -656,8 +768,11 @@ class Game: kind = it.get("kind", "") # Display scaled to match the rest of the UI (aspect preserved). img = fit_surface(img, 60 if kind == "rune" else 80) - tiles.append((img, label, img.get_width(), img.get_height() + 20, - kind == "rune")) + # Tile width must also fit the label, or a rune + pack in the + # same row overlap (the rune's label spills into the pack tile). + label_w = self.bold.size(label)[0] + tiles.append((img, label, max(img.get_width(), label_w), + img.get_height() + 20, kind == "rune")) else: tiles.append((None, label, max(90, self.bold.size(label)[0] + 20), 30, False)) @@ -698,7 +813,9 @@ class Game: if target >= max(img.get_width(), img.get_height()): continue img2 = fit_surface(img, target) - tiles[i] = (img2, t[1], img2.get_width(), img2.get_height() + 20, t[4]) + label_w = self.bold.size(t[1])[0] + tiles[i] = (img2, t[1], max(img2.get_width(), label_w), + img2.get_height() + 20, t[4]) changed = True if not changed: break @@ -706,6 +823,14 @@ class Game: panel_w = max(440, max_row_w + pad * 2) panel_h = head_h + tiles_h + 46 + # Defeat tips: contextual advice shown in the popup's text box. + tip_lines = [] + if b.winner != TEAM_PLAYER: + for tip in self._defeat_tips(): + tip_lines.extend(wrap_text(tip, self.small, panel_w - pad * 2)) + tips_h = len(tip_lines) * 20 + (14 if tip_lines else 0) + panel_h += tips_h + panel = pygame.Rect((WIN_W - panel_w) // 2, (WIN_H - panel_h) // 2, panel_w, panel_h) pygame.draw.rect(self.screen, (32, 38, 32), panel, border_radius=12) border = (150, 190, 150) if b.winner == TEAM_PLAYER else (200, 90, 90) @@ -722,7 +847,8 @@ class Game: x = panel.centerx - total // 2 for img, label, tw, th, _ in r: if img is not None: - self.screen.blit(img, (x, y)) + self.screen.blit(img, img.get_rect(center=(x + tw // 2, + y + img.get_height() // 2))) lr = self.bold.render(label, True, HINT) self.screen.blit(lr, lr.get_rect(center=(x + tw // 2, y + img.get_height() + 10))) else: @@ -732,6 +858,12 @@ class Game: self.screen.blit(t, t.get_rect(center=box.center)) x += tw + gap y += row_h[i] + 14 + if tip_lines: + ty = panel.y + head_h + tiles_h + 10 + for line in tip_lines: + t = self.small.render(line, True, (215, 220, 215)) + self.screen.blit(t, (panel.x + pad, ty)) + ty += 20 hint = self.tiny.render("Click to continue", True, (150, 155, 150)) self.screen.blit(hint, hint.get_rect(center=(panel.centerx, panel.bottom - 16))) @@ -778,6 +910,8 @@ class Game: parts.append(f"Heal {sum(a for a, _ in stacks)}/t") if "form" in unit.status: parts.append(unit.status["form"].capitalize()) + if unit.status.get("boss_stacks", 0): + parts.append(f"Power {unit.status['boss_stacks']}/3") return " | ".join(parts) def _draw_cards(self): @@ -804,10 +938,11 @@ class Game: bar_color = (80, 220, 90) if pct > 0.5 else (220, 180, 40) if pct > 0.25 else (220, 60, 60) fill = int(bar_w * pct) pygame.draw.rect(self.screen, bar_color, (hp_x, rect.y + 7, fill, 10)) - shield = unit.status.get("shield", 0) + shield = sum(amount for amount, _ in unit.status.get("shield", [])) if shield > 0 and fill > 0: + # The shield bar shows the FULL shield value, independent of the + # unit's current HP (a low-HP unit still shows its whole shield). sh_w = int(bar_w * min(1.0, shield / unit.max_hp)) - sh_w = min(sh_w, fill) if sh_w > 0: tint = pygame.Surface((sh_w, 10), pygame.SRCALPHA) tint.fill((120, 185, 240, 140)) @@ -1046,7 +1181,7 @@ class Game: if ready: oblivion_skill = min(ready, key=lambda s: s.power) for i, (sk, rect) in enumerate(self.skill_rects): - ready = sk.cooldown_left <= 0 + ready = sk.cooldown_left <= 0 and (not unit.acted or sk.extra_action) blocked = oblivion and sk is not oblivion_skill if sk is self.pending_skill: bg = (120, 120, 40) diff --git a/ui/menu.py b/ui/menu.py index 31b4b4f..42df3d9 100644 --- a/ui/menu.py +++ b/ui/menu.py @@ -4,7 +4,7 @@ import pygame from assets import icon as icon_path from assets import load_sprite -from engine import collection +from engine import bosses, collection from engine import runes from engine.growth import MAX_LEVEL, can_evolve, compute_stats, evolve_cost, xp_to_next from engine.plants import (HP_MULT, PASSIVES, POOL, RARITY_COLORS, RARITY_LABELS, @@ -34,8 +34,8 @@ TYPE_COLORS = { "radiant": (245, 200, 90), "nocturnal": (150, 120, 220), "ice": (130, 200, 235), - "garden": (120, 200, 120), - "wildflower": (235, 130, 170), + "garden": (235, 130, 170), + "wildflower": (120, 200, 120), } def _draw_star(screen, center, radius, color): import math @@ -84,7 +84,7 @@ class Menu: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants") + pygame.display.set_caption("Flora") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 36) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) @@ -118,6 +118,7 @@ class Menu: self.seed_rect = pygame.Rect(250, 352, 220, 30) self.runes_rect = pygame.Rect(480, 352, 170, 30) self.auto_farmer_rect = pygame.Rect(0, 0, 0, 0) + self.auto_planter_rect = pygame.Rect(0, 0, 0, 0) self.runes_deconstruct_rect = pygame.Rect(WIN_W - 220, 16, 110, 34) self.runes_info_rect = pygame.Rect(WIN_W - 100, 16, 84, 34) self.runes_deconstruct = False @@ -153,6 +154,11 @@ class Menu: self.redeem_rect = pygame.Rect(WIN_W - 250, 50, 234, 30) self.history_rect = pygame.Rect(WIN_W - 250, 84, 234, 26) self.history_open = False + self.shop_mode = False + self.shop_rect = pygame.Rect(WIN_W - 250, 114, 234, 28) + self.shop_btns = {} + self.shop_msg = "" + self.shop_msg_until = 0 self._layout_packs() self.diff_rects = {i: pygame.Rect(220, 130 + (i - 1) * 74, 460, 58) for i in range(1, 6)} self.floor_rects = {i: pygame.Rect(220, 130 + (i - 1) * 74, 460, 58) for i in range(1, 6)} @@ -178,8 +184,9 @@ class Menu: self.coll_sort = None self.collection_tab = "plants" self.collection_tab_btns = { - "plants": pygame.Rect(WIN_W // 2 - 170, 100, 150, 30), - "runes": pygame.Rect(WIN_W // 2 + 20, 100, 150, 30), + "plants": pygame.Rect(WIN_W // 2 - 250, 100, 150, 30), + "bosses": pygame.Rect(WIN_W // 2 - 70, 100, 150, 30), + "runes": pygame.Rect(WIN_W // 2 + 110, 100, 150, 30), } self.coll_rune_tier = 0 self.coll_rune_color = None @@ -206,27 +213,18 @@ class Menu: "level": pygame.Rect(767, 50, 56, 28), "stage": pygame.Rect(827, 50, 58, 28), } - self.convert_mode = False - self.convert_rect = pygame.Rect(WIN_W // 2 - 330, WIN_H - 56, 210, 36) self.soil_msg = None # dict describing a soil popup (harvest result) self.soil_fert_info = False self.water_info = False self.soil_notice = "" self.soil_notice_until = 0 - self.convert_pack_btns = {} - for i, pt in enumerate(REWARD_PACK_TYPES): - col = i % 3 - row = i // 3 - x = WIN_W // 2 - 165 + col * 115 - y = WIN_H // 2 - 25 + row * 52 - self.convert_pack_btns[pt] = pygame.Rect(x, y, 105, 42) self._layout_buttons() def _reinit(self): pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants") + pygame.display.set_caption("Flora") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 36) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) @@ -293,16 +291,16 @@ class Menu: "Plants": pygame.Rect(x0, y, bw, bh), "Battle": pygame.Rect(x0 + bw + gap, y, bw, bh), } - # Side buttons (square-ish): Seeds & Runes left, Soil & Collection right. + # Side buttons (square-ish): Soil & Seeds left, Runes & Collection right. # Fitted into the lower half, keeping clear of the bottom row. sq, sq_gap = 104, 16 ry = WIN_H - 72 - 2 * sq - sq_gap - 10 self.side_buttons = { - "Runes": pygame.Rect(34, ry, sq, sq), + "Soil": pygame.Rect(34, ry, sq, sq), "Seeds": pygame.Rect(34, ry + sq + sq_gap, sq, sq), } rx = WIN_W - 34 - sq - self.side_buttons["Soil"] = pygame.Rect(rx, ry, sq, sq) + self.side_buttons["Runes"] = pygame.Rect(rx, ry, sq, sq) self.side_buttons["Collection"] = pygame.Rect(rx, ry + sq + sq_gap, sq, sq) def _seed_pack_sprite(self, pt, size=110): @@ -356,6 +354,7 @@ class Menu: collection.accrue_coins() collection.accrue_fertilizer() collection.auto_farm() + collection.auto_plant() self._passive_check_at = pygame.time.get_ticks() + 1000 if self.page != self._prev_page: self.grid_scroll = 0 @@ -399,14 +398,16 @@ class Menu: if self.type_info is not None: self.type_info = None return None - if self.convert_mode: - for pt, rect in self.convert_pack_btns.items(): + if self.shop_mode: + if self.shop_msg and pygame.time.get_ticks() < self.shop_msg_until: + return None # a "bought" notice is showing; ignore clicks briefly + for pt, rect in self.shop_btns.items(): if rect.collidepoint(pos): - if collection.convert_water_to_pack(pt): - self.owned = collection.owned() - self.convert_mode = False + err = collection.buy_pack(pt) + self.shop_msg = err or f"Bought a {pt.capitalize()} pack!" + self.shop_msg_until = pygame.time.get_ticks() + 1800 return None - self.convert_mode = False + self.shop_mode = False return None if self.page == "seeds": if self.history_open: @@ -421,6 +422,9 @@ class Menu: if self.redeem_rect.collidepoint(pos): collection.redeem_tower_pack() return None + if self.shop_rect.collidepoint(pos): + self.shop_mode = True + return None for pt, (card, btn) in self.pack_rects.items(): if btn.move(0, -self.seeds_scroll).collidepoint(pos): result = collection.open_pack(pt) @@ -453,6 +457,8 @@ class Menu: if rect.collidepoint(pos): self.collection_tab = key return None + if self.collection_tab == "bosses": + return None # boss cards are informational only if self.collection_tab == "runes": if self._click_coll_rune_filter(pos): return None @@ -488,9 +494,6 @@ class Menu: self.water_mode = not self.water_mode return None if self.water_mode: - if self.convert_rect.collidepoint(pos) and collection.available_water() >= 5: - self.convert_mode = True - return None if self.water_exit_btn.collidepoint(pos): self.water_mode = False return None @@ -592,6 +595,16 @@ class Menu: "activated" if active else "deactivated") self.soil_notice_until = pygame.time.get_ticks() + 1800 return None + if self.auto_planter_rect.collidepoint(pos): + if not collection.auto_planter_owned(): + reason = collection.buy_auto_planter() + self.soil_notice = reason or "Auto planter bought!" + else: + active = collection.toggle_auto_planter() + self.soil_notice = "Auto planter " + ( + "activated" if active else "deactivated") + self.soil_notice_until = pygame.time.get_ticks() + 1800 + return None for idx, rect in self.soil_seed_rects: if rect.collidepoint(pos): collection.plant_seed(idx) @@ -727,8 +740,8 @@ class Menu: if self.type_info is not None: draw_type_popup(self.screen, WIN_W, WIN_H, self.type_info, self.bold, self.small, self.tiny) - if self.convert_mode: - self._draw_convert_pack() + if self.shop_mode: + self._draw_shop() if self.tower_info: self._draw_tower_info() if self.soil_msg: @@ -796,7 +809,7 @@ class Menu: def _draw_menu(self): self._draw_resources() - title = self.font.render("Plants", True, TEXT) + title = self.font.render("Flora", True, TEXT) self.screen.blit(title, title.get_rect(center=(WIN_W // 2, 86))) y = 130 for line in OVERVIEW: @@ -819,7 +832,7 @@ class Menu: else: t = self.bold.render(label, True, TEXT) self.screen.blit(t, t.get_rect(center=rect.center)) - # side buttons: Seeds (left), Soil & Collection (right) + # side buttons: Soil & Seeds (left), Runes & Collection (right) soil_locked = not collection.soil_unlocked() for label, rect in self.side_buttons.items(): hover = rect.collidepoint(mouse) @@ -857,8 +870,8 @@ class Menu: n = collection.SOIL_GATE_PLANTS - len(collection.owned()) hint = self.tiny.render(f"Own {collection.SOIL_GATE_PLANTS} plants to unlock Soil" f" ({n} to go)", True, (110, 115, 110)) - self.screen.blit(hint, hint.get_rect(midright=(self.side_buttons["Soil"].right, - self.side_buttons["Soil"].top - 6))) + self.screen.blit(hint, hint.get_rect(midleft=(self.side_buttons["Soil"].left, + self.side_buttons["Soil"].top - 6))) def _draw_battle_setup(self): self._draw_page("Select Floors", @@ -972,6 +985,12 @@ class Menu: pygame.draw.rect(self.screen, (150, 190, 150), self.history_rect, 1, border_radius=6) ht = self.tiny.render("History (last 10)", True, TEXT) self.screen.blit(ht, ht.get_rect(center=self.history_rect.center)) + shov = self.shop_rect.collidepoint(mouse) + pygame.draw.rect(self.screen, (90, 120, 90) if shov else BTN, + self.shop_rect, border_radius=6) + pygame.draw.rect(self.screen, (150, 190, 150), self.shop_rect, 1, border_radius=6) + sh = self.tiny.render("Pack Shop", True, TEXT) + self.screen.blit(sh, sh.get_rect(center=self.shop_rect.center)) # scrollable grid of packs, each showing its sprite at native size old_clip = self.screen.get_clip() self.screen.set_clip(self.seeds_scroll_area) @@ -1143,7 +1162,7 @@ class Menu: self.screen.blit(rp, (panel.right - 50, y)) low, high = runes.per_rune_chance(runes.PACK_DROP_CHANCE) sub = self.tiny.render( - f"{rpct:.0f}% for any rune — brown is rarer than the others", + f"{rpct:.0f}% for any rune — brown & pearl are rarer than the others", True, MUTED) self.screen.blit(sub, (panel.x + 150, y + 22)) if pt in ALL_TYPES: @@ -1152,26 +1171,54 @@ class Menu: close = self.tiny.render("Click anywhere to close", True, MUTED) self.screen.blit(close, close.get_rect(center=(panel.centerx, panel.bottom - 24))) - def _draw_convert_pack(self): + def _draw_shop(self): overlay = pygame.Surface((WIN_W, WIN_H), pygame.SRCALPHA) overlay.fill((0, 0, 0, 160)) self.screen.blit(overlay, (0, 0)) - w, h = 380, 210 + w, h = 640, 400 panel = pygame.Rect((WIN_W - w) // 2, (WIN_H - h) // 2, w, h) pygame.draw.rect(self.screen, PANEL, panel, border_radius=12) - pygame.draw.rect(self.screen, (60, 70, 60), panel, 2, border_radius=12) - title = self.bold.render("Convert 5 water → a pack of your choice", True, TEXT) - self.screen.blit(title, title.get_rect(center=(panel.centerx, panel.y + 28))) + pygame.draw.rect(self.screen, ACCENT, panel, 2, border_radius=12) + title = self.bold.render("Pack Shop", True, ACCENT) + self.screen.blit(title, title.get_rect(center=(panel.centerx, panel.y + 26))) + coins = collection.available_coins() + bal = self.small.render(f"Coins: {coins}", True, TEXT) + total_w = (16 + 4) + bal.get_width() + bx = panel.centerx - total_w // 2 + if self.coin_icon: + self.screen.blit(self.coin_icon, (bx, panel.y + 52)) + self.screen.blit(bal, (bx + 20, panel.y + 52)) + buyable = ("lesser", "general", "radiant", "nocturnal", "ice", "garden", "wildflower") + cols = 4 + cw, chh, gap = 132, 118, 12 + x0 = panel.x + 24 + y0 = panel.y + 96 + self.shop_btns = {} mouse = self.mouse_pos - for pt, rect in self.convert_pack_btns.items(): + for i, pt in enumerate(buyable): + x = x0 + (i % cols) * (cw + gap) + y = y0 + (i // cols) * (chh + gap) + rect = pygame.Rect(x, y, cw, chh) + cost = collection.PACK_COSTS[pt] hover = rect.collidepoint(mouse) - bg = (90, 120, 90) if hover else BTN - pygame.draw.rect(self.screen, bg, rect, border_radius=6) - pygame.draw.rect(self.screen, (150, 190, 150), rect, 1, border_radius=6) - tcol = TYPE_COLORS.get(pt, TEXT) - draw_type_icon(self.screen, pt, rect.center, self.tiny, tcol, 26, center=True) - hint = self.tiny.render("Click elsewhere to cancel", True, MUTED) - self.screen.blit(hint, hint.get_rect(center=(panel.centerx, panel.bottom - 18))) + afford = coins >= cost + pygame.draw.rect(self.screen, (90, 120, 90) if (hover and afford) else (BTN if afford else (45, 50, 45)), + rect, border_radius=8) + pygame.draw.rect(self.screen, (150, 190, 150) if afford else (70, 80, 70), + rect, 1, border_radius=8) + spr = self._seed_pack_sprite(pt, 48) + if spr: + self.screen.blit(spr, spr.get_rect(center=(rect.centerx, rect.y + 30))) + nm = self.tiny.render(pt.capitalize(), True, TEXT if afford else MUTED) + self.screen.blit(nm, nm.get_rect(center=(rect.centerx, rect.y + 60))) + pr = self.tiny.render(f"{cost} coins", True, HINT if afford else MUTED) + self.screen.blit(pr, pr.get_rect(center=(rect.centerx, rect.y + 86))) + self.shop_btns[pt] = rect + note = self.tiny.render("Tower packs can't be bought.", True, MUTED) + self.screen.blit(note, note.get_rect(center=(panel.centerx, panel.bottom - 18))) + if self.shop_msg and pygame.time.get_ticks() < self.shop_msg_until: + mt = self.small.render(self.shop_msg, True, DANGER if "Not enough" in self.shop_msg else (120, 220, 120)) + self.screen.blit(mt, mt.get_rect(center=(panel.centerx, panel.y + 356))) def _draw_soil(self): self._draw_page("Soil", "Retrieve seeds from plants, plant them, and grow copies.") @@ -1217,6 +1264,26 @@ class Menu: f"Buy Auto Farmer — {collection.AUTO_FARMER_COST} coins", True, TEXT if can_afford else MUTED) self.screen.blit(af_txt, af_txt.get_rect(center=self.auto_farmer_rect.center)) + ap_owned = collection.auto_planter_owned() + ap_active = collection.auto_planter_active() + self.auto_planter_rect = pygame.Rect(WIN_W - 270, 180, 250, 28) + ap_hover = self.auto_planter_rect.collidepoint(self.mouse_pos) + pygame.draw.rect(self.screen, + (90, 120, 90) if (ap_active or ap_hover) else BTN, + self.auto_planter_rect, border_radius=6) + pygame.draw.rect(self.screen, + (150, 190, 150) if ap_active else (70, 80, 70), + self.auto_planter_rect, 1, border_radius=6) + if ap_owned: + ap_txt = self.tiny.render( + "Auto Planter: active" if ap_active else "Auto Planter: off", + True, ACCENT if ap_active else MUTED) + else: + can_afford = collection.available_coins() >= collection.AUTO_PLANTER_COST + ap_txt = self.tiny.render( + f"Buy Auto Planter — {collection.AUTO_PLANTER_COST} coins", + True, TEXT if can_afford else MUTED) + self.screen.blit(ap_txt, ap_txt.get_rect(center=self.auto_planter_rect.center)) if self.soil_notice and pygame.time.get_ticks() < self.soil_notice_until: nt = self.bold.render(self.soil_notice, True, (235, 130, 130)) self.screen.blit(nt, nt.get_rect(center=(WIN_W // 2, 148))) @@ -1492,14 +1559,6 @@ class Menu: self._draw_grid(owned, reveal_all=True, level_mode=self.water_mode, data=data) if self.water_mode: water = collection.available_water() - can_convert = water >= 5 - pygame.draw.rect(self.screen, BTN_HOVER if can_convert else (45, 50, 45), - self.convert_rect, border_radius=6) - pygame.draw.rect(self.screen, (150, 190, 150) if can_convert else (70, 80, 70), - self.convert_rect, 1, border_radius=6) - ct = self.tiny.render(f"Convert 5 water → pack" + ("" if can_convert else " (need 5)"), - True, TEXT if can_convert else MUTED) - self.screen.blit(ct, ct.get_rect(center=self.convert_rect.center)) pygame.draw.rect(self.screen, BTN_HOVER, self.water_exit_btn, border_radius=6) pygame.draw.rect(self.screen, (150, 190, 150), self.water_exit_btn, 2, border_radius=6) et = self.tiny.render("Exit water mode", True, TEXT) @@ -1574,10 +1633,12 @@ class Menu: bcol = DANGER if self.runes_deconstruct_msg else ACCENT if self.runes_target is None: btxt = self.runes_deconstruct_msg or \ - "Deconstruct — pick a rune to improve, then sacrifice 10 runes" + f"Deconstruct — pick a rune to improve, then sacrifice " \ + f"{runes.RUNE_SACRIFICE_COST} runes" else: btxt = self.runes_deconstruct_msg or \ - f"Pick 10 runes to sacrifice ({len(self.runes_sacrifice)}/10) — " \ + f"Pick {runes.RUNE_SACRIFICE_COST} runes to sacrifice " \ + f"({len(self.runes_sacrifice)}/{runes.RUNE_SACRIFICE_COST}) — " \ "click the target again to change it" b = self.tiny.render(btxt, True, bcol) self.screen.blit(b, b.get_rect(center=(WIN_W // 2, 124))) @@ -1609,7 +1670,7 @@ class Menu: if ic: self.screen.blit(ic, ic.get_rect(center=(rect.centerx, rect.y + 30))) owner = collection.rune_location(rune["id"]) - max_pct = runes.BROWN_PCT_MAX if rune["color"] == "brown" else runes.PCT_MAX + max_pct = runes.max_pct(rune["color"]) is_max = rune.get("pct", 0) >= max_pct is_target = self.runes_deconstruct and self.runes_target \ and rune["id"] == self.runes_target["id"] @@ -1841,7 +1902,7 @@ class Menu: if not rune: return if self.runes_target is None: - max_pct = runes.BROWN_PCT_MAX if rune["color"] == "brown" else runes.PCT_MAX + max_pct = runes.max_pct(rune["color"]) if rune.get("pct", 0) >= max_pct: self.runes_deconstruct_msg = f"{rune['name']} is already at max roll" return @@ -1857,13 +1918,14 @@ class Menu: return if rune_id in self.runes_sacrifice: self.runes_sacrifice.remove(rune_id) - elif len(self.runes_sacrifice) >= 10: - self.runes_deconstruct_msg = "Already picked 10 runes" + elif len(self.runes_sacrifice) >= runes.RUNE_SACRIFICE_COST: + self.runes_deconstruct_msg = \ + f"Already picked {runes.RUNE_SACRIFICE_COST} runes" return else: self.runes_sacrifice.append(rune_id) self.runes_deconstruct_msg = "" - if len(self.runes_sacrifice) == 10: + if len(self.runes_sacrifice) == runes.RUNE_SACRIFICE_COST: self._open_runes_confirm() return @@ -1884,7 +1946,7 @@ class Menu: overlay = pygame.Surface((WIN_W, WIN_H), pygame.SRCALPHA) overlay.fill((0, 0, 0, 160)) self.screen.blit(overlay, (0, 0)) - w, h = 560, 400 + w, h = 560, 450 panel = pygame.Rect((WIN_W - w) // 2, (WIN_H - h) // 2, w, h) pygame.draw.rect(self.screen, PANEL, panel, border_radius=12) pygame.draw.rect(self.screen, (150, 190, 150), panel, 2, border_radius=12) @@ -1943,11 +2005,12 @@ class Menu: pygame.draw.rect(self.screen, DANGER, panel, 2, border_radius=12) rune = self.runes_confirm["rune"] name = rune["name"] - max_pct = runes.BROWN_PCT_MAX if rune["color"] == "brown" else runes.PCT_MAX + max_pct = runes.max_pct(rune["color"]) current = rune.get("pct", 0) title = self.bold.render("Reroll rune?", True, TEXT) msg = self.small.render( - f"Sacrifice 10 runes to improve {name} to {current + 1}–{max_pct}%?", + f"Sacrifice {runes.RUNE_SACRIFICE_COST} runes to improve {name} to " + f"{current + 1}–{max_pct}%?", True, TEXT) self.screen.blit(title, title.get_rect(center=(panel.centerx, panel.y + 34))) self.screen.blit(msg, msg.get_rect(center=(panel.centerx, panel.y + 60))) @@ -1979,14 +2042,73 @@ class Menu: rect, border_radius=6) pygame.draw.rect(self.screen, (150, 190, 150) if active else (70, 80, 70), rect, 1, border_radius=6) - t = self.tiny.render("Plants" if key == "plants" else "Runes", True, TEXT) + t = self.tiny.render( + "Plants" if key == "plants" else "Bosses" if key == "bosses" else "Runes", + True, TEXT) self.screen.blit(t, t.get_rect(center=rect.center)) if self.collection_tab == "runes": self._draw_collection_runes() + elif self.collection_tab == "bosses": + self._draw_collection_bosses() else: self._draw_grid(self.names, reveal_all=False, show_evo=False, reveal_owned=True, y0=144) + def _draw_collection_bosses(self): + mouse = self.mouse_pos + fought = collection.bosses_fought() + cw, ch, gap = 230, 260, 20 + cols = 3 + total = cols * cw + (cols - 1) * gap + x0 = (WIN_W - total) // 2 + y0 = 150 + self.boss_cards = [] + for i, (name, spec) in enumerate(bosses.BOSS_SPECS.items()): + x = x0 + (i % cols) * (cw + gap) + y = y0 + (i // cols) * (ch + gap) + rect = pygame.Rect(x, y, cw, ch) + self.boss_cards.append((name, rect)) + known = name in fought + pygame.draw.rect(self.screen, PANEL, rect, border_radius=8) + pygame.draw.rect(self.screen, (150, 120, 80) if known else (60, 70, 60), + rect, 1, border_radius=8) + spr = self._boss_sprite(name) + sprite_rect = pygame.Rect(rect.centerx - 60, rect.y + 12, 120, 120) + if spr: + ic = fit_surface(spr, 120) + if known: + self.screen.blit(ic, ic.get_rect(center=sprite_rect.center)) + else: + dim = ic.copy() + dim.set_alpha(70) + self.screen.blit(dim, dim.get_rect(center=sprite_rect.center)) + pygame.draw.rect(self.screen, (70, 78, 70), sprite_rect, 1) + nm = self.small.render(name if known else "???", True, TEXT if known else MUTED) + self.screen.blit(nm, nm.get_rect(center=(rect.centerx, rect.y + 150))) + if known: + atk, spd, dfn, hp = spec["stats"] + st = self.tiny.render(f"Atk {atk} Spd {spd} Def {dfn} HP {int(hp * HP_MULT)}", + True, MUTED) + self.screen.blit(st, st.get_rect(center=(rect.centerx, rect.y + 176))) + lines = wrap_text(spec["desc"], self.tiny, cw - 24) + ty = rect.y + 198 + for ln in lines[:3]: + self.screen.blit(self.tiny.render(ln, True, (170, 175, 170)), + (rect.x + 12, ty)) + ty += 16 + drops = "Drops: " + ", ".join(spec["drop_runes"]) + dr = self.tiny.render(drops, True, (235, 200, 120)) + self.screen.blit(dr, dr.get_rect(center=(rect.centerx, rect.bottom - 20))) + else: + t = self.tiny.render("Not yet fought", True, (110, 115, 110)) + self.screen.blit(t, t.get_rect(center=(rect.centerx, rect.y + 180))) + + def _boss_sprite(self, name): + key = f"boss_{name}" + if key not in self.seed_pack_sprites: + self.seed_pack_sprites[key] = load_sprite(bosses.boss_sprite(name)) + return self.seed_pack_sprites[key] + def _draw_collection_runes(self): mouse = self.mouse_pos self._draw_coll_rune_filters() @@ -2108,8 +2230,7 @@ class Menu: self.screen.blit(ic, ic.get_rect(center=(panel.centerx, panel.y + 78))) eff = self.small.render(runes.summary(color), True, TEXT) self.screen.blit(eff, eff.get_rect(center=(panel.centerx, panel.y + 122))) - dmg = self.tiny.render(runes.effect_text(color, runes.PCT_MAX if color != "brown" else runes.BROWN_PCT_MAX), - True, MUTED) + dmg = self.tiny.render(runes.effect_text(color, runes.max_pct(color)), True, MUTED) self.screen.blit(dmg, dmg.get_rect(center=(panel.centerx, panel.y + 146))) t1 = self.small.render(f"Tier {runes.tier(color)} · Max roll {runes.roll_range(color)}", True, HINT) @@ -2124,8 +2245,7 @@ class Menu: if self.coll_rune_sort_best: inv = collection.rune_inventory() best = {c: max((r.get("pct", 0) for r in inv if r["color"] == c), default=0) for c in colors} - colors.sort(key=lambda c: best[c] / (runes.BROWN_PCT_MAX if c == "brown" else runes.PCT_MAX), - reverse=True) + colors.sort(key=lambda c: best[c] / runes.max_pct(c), reverse=True) return colors def _draw_detail(self): @@ -2390,12 +2510,15 @@ class Menu: sprite_rect = pygame.Rect(rect.centerx - 44, rect.y + 12, 88, 88) if spr: ic = fit_surface(spr, 88) - self.screen.blit(ic, ic.get_rect(center=sprite_rect.center)) - if spr and not found: - dim = ic.copy() - dim.set_alpha(70) - self.screen.blit(dim, dim.get_rect(center=sprite_rect.center)) - pygame.draw.rect(self.screen, (70, 78, 70), sprite_rect, 1) + if found: + self.screen.blit(ic, ic.get_rect(center=sprite_rect.center)) + else: + # Dim only the sprite (matches the runes tab): blitting the + # full icon first then the dim copy would cancel out. + dim = ic.copy() + dim.set_alpha(70) + self.screen.blit(dim, dim.get_rect(center=sprite_rect.center)) + pygame.draw.rect(self.screen, (70, 78, 70), sprite_rect, 1) name_txt = "???" if not found else name t = self.tiny.render(name_txt, True, TEXT if found else MUTED) self.screen.blit(t, t.get_rect(center=(rect.centerx, rect.y + 110))) diff --git a/ui/picker.py b/ui/picker.py index 1991b07..9d66416 100644 --- a/ui/picker.py +++ b/ui/picker.py @@ -2,10 +2,11 @@ import pygame from assets import icon as icon_path from assets import load_sprite -from engine import collection +from engine import bosses, collection from engine.growth import compute_stats from engine.plants import HP_MULT, PASSIVES, POOL, RARITY_COLORS, RARITY_LABELS, plant_rarity from engine.roster import floor_enemy_level, roll_enemies +from engine.types import ALL_TYPES from engine.unit import ROLE_ATTACKER, ROLE_ICONS, ROLE_NAMES, ROLE_SUPPORT, ROLE_TANK from ui.menu import _bracket_text, _draw_evo_badge from ui.runes import draw_rune_chips @@ -17,8 +18,8 @@ TYPE_COLORS = { "radiant": (245, 200, 90), "nocturnal": (150, 120, 220), "ice": (130, 200, 235), - "garden": (120, 200, 120), - "wildflower": (235, 130, 170), + "garden": (235, 130, 170), + "wildflower": (120, 200, 120), } BG = (24, 30, 24) @@ -44,7 +45,7 @@ class TeamSelect: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption(header or "Plants — Tower") + pygame.display.set_caption(header or "Flora — Tower") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 30) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) @@ -68,6 +69,8 @@ class TeamSelect: self.pool_names = sorted((n for n in self.names if n in collection.owned()), key=lambda n: (n not in self.favs, n)) self.sprites = {n: self._load(n) for n in self.names} + for bname in bosses.BOSS_SPECS: + self.sprites[bname] = self._load(bosses.boss_sprite(bname)) self.rune_icons = {} self.role_icons = {} self.allies = [] @@ -82,6 +85,12 @@ class TeamSelect: self._layout_enemy_cards() self._layout_enemy_strip() self._layout_slots() + self.pool_filter = None # optional elemental type filter for the ally pool + self.pool_exclude_type = None # right-click: show everything BUT this type + self.pool_type_rects = [] + self.pool_role = None # optional role filter for the ally pool + self.pool_exclude_role = None # right-click: show everything BUT this role + self.pool_role_rects = [] self._layout_pool() self.roll_rect = pygame.Rect(WIN_W // 2 - 260, WIN_H - 60, 170, 40) self.next_rect = pygame.Rect(WIN_W // 2 + 90, WIN_H - 60, 180, 40) @@ -157,13 +166,28 @@ class TeamSelect: sl_h, gap = SLOT_H, SLOT_GAP self.ally_rects = [pygame.Rect(24, 170 + i * (sl_h + gap), SLOT_W, sl_h) for i in range(n)] + def _display_pool(self): + """The ally pool, filtered by element type and/or role when active. + Left-click filters include a type/role; right-click excludes it.""" + result = self.pool_names + if self.pool_filter is not None: + result = [n for n in result if POOL[n]["type"] == self.pool_filter] + elif self.pool_exclude_type is not None: + result = [n for n in result if POOL[n]["type"] != self.pool_exclude_type] + if self.pool_role is not None: + result = [n for n in result if POOL[n]["role"] == self.pool_role] + elif self.pool_exclude_role is not None: + result = [n for n in result if POOL[n]["role"] != self.pool_exclude_role] + return result + def _layout_pool(self): self.pool_rects = {} - cols = min(4, max(1, len(self.pool_names))) + shown = self._display_pool() + cols = min(4, max(1, len(shown))) cw, ch, gap = 170, 64, 10 x0 = 290 y0 = 170 - for i, name in enumerate(self.pool_names): + for i, name in enumerate(shown): x = x0 + (i % cols) * (cw + gap) y = y0 + (i // cols) * (ch + gap) self.pool_rects[name] = pygame.Rect(x, y, cw, ch) @@ -171,7 +195,7 @@ class TeamSelect: self.pool_area = pygame.Rect(x0 - 4, y0 - 4, cols * cw + (cols - 1) * gap + 8, WIN_H - y0 - 100) - rows = (len(self.pool_names) + cols - 1) // cols + rows = (len(shown) + cols - 1) // cols self.pool_scroll_max = max(0, rows * (ch + gap) - gap - self.pool_area.h) self.pool_scroll = getattr(self, "pool_scroll", 0) self.pool_scroll = max(0, min(self.pool_scroll, self.pool_scroll_max)) @@ -190,6 +214,10 @@ class TeamSelect: if not self.detail_open: self.pool_scroll = max(0, min(self.pool_scroll_max, self.pool_scroll - event.y * 40)) + elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3: + pos = to_logical(event.pos, self.scale) + if not self.detail_open: + self._click_right(pos) elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: pos = to_logical(event.pos, self.scale) if self.detail_open: @@ -269,12 +297,55 @@ class TeamSelect: if rect.collidepoint(pos) and i < len(self.enemies): self._open_detail(self.enemies[i], self.enemies) return None + for ptype, rect in self.pool_type_rects: + if rect.collidepoint(pos): + self.pool_filter = ptype # None = "All", else the chosen type + self.pool_exclude_type = None + self.pool_scroll = 0 + self._layout_pool() + return None + for role, rect in self.pool_role_rects: + if rect.collidepoint(pos): + self.pool_role = role # None = "All", else the chosen role + self.pool_exclude_role = None + self.pool_scroll = 0 + self._layout_pool() + return None for name, rect in self.pool_rects.items(): if rect.move(0, -self.pool_scroll).collidepoint(pos): if name in self.allies: self.allies.remove(name) # click a selected plant to unselect it else: - self._open_detail(name, self.pool_names) + self._open_detail(name, self._display_pool()) + return None + return None + + def _click_right(self, pos): + """Right-click on a filter icon EXCLUDES that type/role (everything but it).""" + if self.type_info is not None: + self.type_info = None + return None + for ptype, rect in self.pool_type_rects: + if rect.collidepoint(pos): + if ptype is None: + self.pool_filter = None + self.pool_exclude_type = None + else: + self.pool_exclude_type = ptype + self.pool_filter = None + self.pool_scroll = 0 + self._layout_pool() + return None + for role, rect in self.pool_role_rects: + if rect.collidepoint(pos): + if role is None: + self.pool_role = None + self.pool_exclude_role = None + else: + self.pool_exclude_role = role + self.pool_role = None + self.pool_scroll = 0 + self._layout_pool() return None return None @@ -334,8 +405,12 @@ class TeamSelect: return tag def _draw_role_type_tag(self, name, pos, font, center=False, ptype=None): - role_name = ROLE_NAMES.get(POOL[name]["role"], POOL[name]["role"]) - rs = font.render(role_name, True, RARITY_COLORS.get(plant_rarity(name), TEXT)) + if bosses.is_boss(name): + role_name = "Boss" + rs = font.render(role_name, True, (235, 200, 120)) + else: + role_name = ROLE_NAMES.get(POOL[name]["role"], POOL[name]["role"]) + rs = font.render(role_name, True, RARITY_COLORS.get(plant_rarity(name), TEXT)) sep = font.render(" · ", True, MUTED) ptype = ptype or collection.unit_type(name) tic = load_type_icon(ptype, 16) if ptype else None @@ -381,7 +456,7 @@ class TeamSelect: tag = self._draw_role_type_tag(name, (rect.centerx, rect.y + 178), self.small, center=True, ptype=self.enemy_types[i] if i < len(self.enemy_types) else None) self._draw_enemy_level(tag, i) - stats = POOL[name]["stats"] + stats = bosses.boss_stats(name) if bosses.is_boss(name) else POOL[name]["stats"] st = self.tiny.render(f"Atk {stats[0]} Spd {stats[1]} Def {stats[2]} HP {int(stats[3] * HP_MULT)}", True, MUTED) self.screen.blit(st, st.get_rect(center=(rect.centerx, rect.y + 216))) @@ -414,6 +489,7 @@ class TeamSelect: self._draw_enemy_strip() if self.show_slots: self._draw_slots(self.ally_rects, self.allies, "Your Allies") + self._draw_pool_filters() self._draw_pool() self._draw_tower_enemies() for i, rect in enumerate(self.preset_rects): @@ -495,6 +571,69 @@ class TeamSelect: draw_rune_chips(self.screen, self._rune_icon, rune_colors, rect.right - 40 - chip_w, rect.y + 32) + def _draw_pool_filters(self): + """Type + role filter row above the ally pool: 'All' plus one icon per + element and per role. Left-click highlights green (include only), and + right-click highlights red (exclude that type/role).""" + self.pool_type_rects = [] + self.pool_role_rects = [] + y, h = 142, 24 + INC = (120, 220, 120) + EXC = (235, 110, 110) + tl = self.tiny.render("Type:", True, MUTED) + self.screen.blit(tl, (290, y + 5)) + x = 330 + all_rect = pygame.Rect(x, y, 36, h) + active = self.pool_filter is None and self.pool_exclude_type is None + pygame.draw.rect(self.screen, (90, 120, 90) if active else (45, 50, 45), + all_rect, border_radius=4) + pygame.draw.rect(self.screen, HINT if active else (70, 80, 70), + all_rect, 1, border_radius=4) + t = self.tiny.render("All", True, TEXT if active else MUTED) + self.screen.blit(t, t.get_rect(center=all_rect.center)) + self.pool_type_rects.append((None, all_rect)) + x += 42 + for ptype in ALL_TYPES: + rect = pygame.Rect(x, y, 24, h) + inc = self.pool_filter == ptype + exc = self.pool_exclude_type == ptype + pygame.draw.rect(self.screen, (45, 50, 45), rect, border_radius=4) + border = INC if inc else EXC if exc else (70, 80, 70) + pygame.draw.rect(self.screen, border, rect, 2 if (inc or exc) else 1, + border_radius=4) + tic = load_type_icon(ptype, 22) + if tic: + self.screen.blit(tic, tic.get_rect(center=rect.center)) + self.pool_type_rects.append((ptype, rect)) + x += 28 + x += 36 # a little space between the type and role filters + rl = self.tiny.render("Role:", True, MUTED) + self.screen.blit(rl, (x, y + 5)) + x += 42 + all_role = pygame.Rect(x, y, 36, h) + active = self.pool_role is None and self.pool_exclude_role is None + pygame.draw.rect(self.screen, (90, 120, 90) if active else (45, 50, 45), + all_role, border_radius=4) + pygame.draw.rect(self.screen, HINT if active else (70, 80, 70), + all_role, 1, border_radius=4) + t = self.tiny.render("All", True, TEXT if active else MUTED) + self.screen.blit(t, t.get_rect(center=all_role.center)) + self.pool_role_rects.append((None, all_role)) + x += 42 + for role in (ROLE_ATTACKER, ROLE_SUPPORT, ROLE_TANK): + rect = pygame.Rect(x, y, 24, h) + inc = self.pool_role == role + exc = self.pool_exclude_role == role + pygame.draw.rect(self.screen, (45, 50, 45), rect, border_radius=4) + border = INC if inc else EXC if exc else (70, 80, 70) + pygame.draw.rect(self.screen, border, rect, 2 if (inc or exc) else 1, + border_radius=4) + ric = self._role_icon(role, 22) + if ric: + self.screen.blit(ric, ric.get_rect(center=rect.center)) + self.pool_role_rects.append((role, rect)) + x += 28 + def _draw_pool(self): old_clip = self.screen.get_clip() self.screen.set_clip(self.pool_area) @@ -574,7 +713,11 @@ class TeamSelect: name = self.detail_name if name is None: return - spec = POOL[name] + is_boss_unit = bosses.is_boss(name) + spec = None if is_boss_unit else POOL[name] + boss_stats_t = bosses.boss_stats(name) if is_boss_unit else None + boss_skills = bosses.make_boss(name, 20).skills if is_boss_unit else None + boss_desc = bosses.BOSS_SPECS[name]["desc"] if is_boss_unit else None shade = pygame.Surface((WIN_W, WIN_H)) shade.fill((0, 0, 0)) shade.set_alpha(120) @@ -592,8 +735,11 @@ class TeamSelect: self.screen.blit(ic, ic.get_rect(center=(self.detail_rect.x + 84, self.detail_rect.y + 100))) t = self.bold.render(name, True, TEXT) self.screen.blit(t, (self.detail_rect.x + 160, self.detail_rect.y + 34)) - rar = plant_rarity(name) - rt = self.tiny.render(RARITY_LABELS.get(rar, rar), True, RARITY_COLORS.get(rar, TEXT)) + if is_boss_unit: + rt = self.tiny.render("Boss", True, (235, 200, 120)) + else: + rar = plant_rarity(name) + rt = self.tiny.render(RARITY_LABELS.get(rar, rar), True, RARITY_COLORS.get(rar, TEXT)) self.screen.blit(rt, (self.detail_rect.x + 160 + t.get_width() + 8, self.detail_rect.y + 38)) enemy_type = None if self.detail_is_enemy: @@ -604,19 +750,34 @@ class TeamSelect: name, (self.detail_rect.x + 160, self.detail_rect.y + 62), self.small, ptype=enemy_type) - if not self.detail_is_enemy and name in collection.owned(): + if not self.detail_is_enemy and not is_boss_unit and name in collection.owned(): prog = collection.get_progress(name) lv = self.tiny.render(f"Level {prog['level']} · Stage {prog['stage']}", True, HINT) self.screen.blit(lv, (self.detail_rect.x + 160, self.detail_rect.y + 120)) atk, spd, dfn, hp = compute_stats(spec["stats"], prog["level"], prog["stage"]) else: - atk, spd, dfn, hp = spec["stats"] + atk, spd, dfn, hp = boss_stats_t if is_boss_unit else spec["stats"] st = self.small.render(f"Atk {atk} Spd {spd}", True, TEXT) self.screen.blit(st, (self.detail_rect.x + 160, self.detail_rect.y + 148)) st = self.small.render(f"Def {dfn} HP {int(hp * HP_MULT)}", True, TEXT) self.screen.blit(st, (self.detail_rect.x + 160, self.detail_rect.y + 174)) y = self.detail_rect.y + 210 + if is_boss_unit: + self.screen.blit(self.bold.render("Boss", True, HINT), (self.detail_rect.x + 24, y)) + lines = wrap_text(" " + boss_desc, self.small, self.detail_rect.w - 48) + for i, ln in enumerate(lines): + self.screen.blit(self.small.render(ln, True, TEXT), + (self.detail_rect.x + 24, y + 22 + i * 20)) + y += 26 + len(lines) * 20 + 2 + for sk in boss_skills: + bracket = _bracket_text(sk) + label = f"{sk.name} [{bracket}]" if bracket else sk.name + self.screen.blit(self.bold.render(label, True, HINT), (self.detail_rect.x + 24, y)) + d = self.small.render(" " + sk.description, True, TEXT) + self.screen.blit(d, (self.detail_rect.x + 24, y + 20)) + y += 42 + return p = spec.get("passive", "") if p: pname, pdesc = PASSIVES.get(p, (p, "")) diff --git a/ui/presets.py b/ui/presets.py index b03cfc0..ee75f62 100644 --- a/ui/presets.py +++ b/ui/presets.py @@ -18,7 +18,7 @@ class PresetScreen: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants — Team Presets") + pygame.display.set_caption("Flora — Team Presets") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 30) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) @@ -67,7 +67,7 @@ class PresetScreen: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants — Team Presets") + pygame.display.set_caption("Flora — Team Presets") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 30) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) diff --git a/ui/relic_choice.py b/ui/relic_choice.py index 6ac2f29..40b900d 100644 --- a/ui/relic_choice.py +++ b/ui/relic_choice.py @@ -22,7 +22,7 @@ class RelicChoiceScreen: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants — Blessing") + pygame.display.set_caption("Flora — Blessing") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 36) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) diff --git a/ui/runes.py b/ui/runes.py index 520aef2..adca149 100644 --- a/ui/runes.py +++ b/ui/runes.py @@ -36,7 +36,7 @@ class RuneScreen: self.plant = plant self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption(f"Plants — Runes · {plant}") + pygame.display.set_caption(f"Flora — Runes · {plant}") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 30) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) @@ -377,7 +377,7 @@ class RuneScreen: overlay = pygame.Surface((WIN_W, WIN_H), pygame.SRCALPHA) overlay.fill((0, 0, 0, 160)) self.screen.blit(overlay, (0, 0)) - w, h = 560, 400 + w, h = 560, 450 panel = pygame.Rect((WIN_W - w) // 2, (WIN_H - h) // 2, w, h) pygame.draw.rect(self.screen, PANEL, panel, border_radius=12) pygame.draw.rect(self.screen, (150, 190, 150), panel, 2, border_radius=12) diff --git a/ui/starter.py b/ui/starter.py index 4c338cf..b5e1d5b 100644 --- a/ui/starter.py +++ b/ui/starter.py @@ -25,8 +25,8 @@ TYPE_COLORS = { "radiant": (245, 200, 90), "nocturnal": (150, 120, 220), "ice": (130, 200, 235), - "garden": (120, 200, 120), - "wildflower": (235, 130, 170), + "garden": (235, 130, 170), + "wildflower": (120, 200, 120), } @@ -35,7 +35,7 @@ class StarterScreen: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants — Choose your starting pinwheel") + pygame.display.set_caption("Flora — Choose your starting pinwheel") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 30) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) diff --git a/ui/tower.py b/ui/tower.py index b9b04fd..d1c9f5a 100644 --- a/ui/tower.py +++ b/ui/tower.py @@ -21,7 +21,7 @@ class ConfirmScreen: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants — Tower") + pygame.display.set_caption("Flora — Tower") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 30) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) @@ -81,7 +81,7 @@ class TowerScreen: pygame.init() self.window, self.scale = make_window(WIN_W, WIN_H) self.screen = pygame.Surface((WIN_W, WIN_H)) - pygame.display.set_caption("Plants — Tower") + pygame.display.set_caption("Flora — Tower") self.clock = pygame.time.Clock() self.font = pygame.font.SysFont("segoeui", 36) self.bold = pygame.font.SysFont("segoeui", 20, bold=True) diff --git a/ui/typepopup.py b/ui/typepopup.py index 0ec6de9..a3b7084 100644 --- a/ui/typepopup.py +++ b/ui/typepopup.py @@ -7,8 +7,8 @@ TYPE_COLORS = { "radiant": (245, 200, 90), "nocturnal": (150, 120, 220), "ice": (130, 200, 235), - "garden": (120, 200, 120), - "wildflower": (235, 130, 170), + "garden": (235, 130, 170), + "wildflower": (120, 200, 120), } STRONG = (120, 210, 120) WEAK = (225, 130, 130)