From f4afb86d0ebfbc5759125451cc4f8ed7349d74e8 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Fri, 21 Jun 2024 02:24:03 +0800 Subject: [PATCH 1/5] Fix: InventoryManager.set() was using outdated items --- tasks/item/inventory.py | 36 +++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) diff --git a/tasks/item/inventory.py b/tasks/item/inventory.py index 347b893bf..db86cbc48 100644 --- a/tasks/item/inventory.py +++ b/tasks/item/inventory.py @@ -4,10 +4,9 @@ from scipy import signal from module.base.base import ModuleBase from module.base.button import ButtonWrapper -from module.base.decorator import cached_property, del_cached_property +from module.base.decorator import cached_property from module.base.timer import Timer from module.base.utils import Lines, area_center, area_offset, color_similarity_2d -from module.exception import ScriptError from module.logger import logger @@ -71,6 +70,8 @@ class InventoryManager: ERROR_LINES_TOLERANCE = (-10, 10) COINCIDENT_POINT_ENCOURAGE_DISTANCE = 1. + MAXIMUM_ITEMS = 30 + def __init__(self, main: ModuleBase, inventory: ButtonWrapper): """ max_count: expected max count of this inventory page @@ -248,7 +249,10 @@ class InventoryManager: else: self.selected = selected[0] - logger.info(f'Inventory: {len(self.items)} items, selected {self.selected}') + count = len(self.items) + logger.info(f'Inventory: {count} items, selected {self.selected}') + if count > self.MAXIMUM_ITEMS: + logger.warning('Too many inventory items detected') def get_row_first(self, row=1, first=0) -> InventoryItem | None: """ @@ -292,12 +296,9 @@ class InventoryManager: def select(self, item, skip_first_screenshot=True): logger.info(f'Inventory select {item}') if isinstance(item, InventoryItem): - pass + loca = item.loca else: - try: - item = self.items[item] - except KeyError: - raise ScriptError(f'Inventory select {item} but is not in current items') + loca = item interval = Timer(2, count=6) while 1: @@ -306,8 +307,16 @@ class InventoryManager: else: self.main.device.screenshot() + self.update() + if len(self.items) > self.MAXIMUM_ITEMS: + continue + try: + item = self.items[loca] + except KeyError: + logger.warning(f'Item {loca} is not in inventory, cannot select') + continue + # End - del_cached_property(item, 'is_selected') if item.is_selected: logger.info('Inventory item selected') break @@ -315,8 +324,7 @@ class InventoryManager: if interval.reached(): self.main.device.click(item) interval.reset() - - self.update() + continue def wait_selected(self, skip_first_screenshot=True): """ @@ -334,8 +342,10 @@ class InventoryManager: self.main.device.screenshot() self.update() - if self.selected is not None: - return True if timeout.reached(): logger.warning('Wait inventory selected timeout') return False + if len(self.items) > self.MAXIMUM_ITEMS: + continue + if self.selected is not None: + return True From af80aa3d4c6156a6cd5d5e0bd5d8ba9b08c0f387 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:31:43 +0800 Subject: [PATCH 2/5] Add: [ALAS] Switch.wait() --- module/ui/switch.py | 41 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 37 insertions(+), 4 deletions(-) diff --git a/module/ui/switch.py b/module/ui/switch.py index fd13c61c9..95304fe41 100644 --- a/module/ui/switch.py +++ b/module/ui/switch.py @@ -137,14 +137,14 @@ class Switch: current = self.get(main=main) logger.attr(self.name, current) - # Handle additional popups - if self.handle_additional(main=main): - continue - # End if current == state: return changed + # Handle additional popups + if self.handle_additional(main=main): + continue + # Warning if current == 'unknown': if warning_show_timer.reached(): @@ -165,3 +165,36 @@ class Switch: changed = True return changed + + def wait(self, main, skip_first_screenshot=True): + """ + Wait until any state activated + + Args: + main (ModuleBase): + skip_first_screenshot: + + Returns: + bool: If success + """ + timeout = Timer(2, count=6).start() + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + main.device.screenshot() + + # Detect + current = self.get(main=main) + logger.attr(self.name, current) + + # End + if current != 'unknown': + return True + if timeout.reached(): + logger.warning(f'{self.name} wait activated timeout') + return False + + # Handle additional popups + if self.handle_additional(main=main): + continue From f1d75967e7d3298f8c8ac411ab8ea8853c8d6866 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Fri, 21 Jun 2024 13:35:13 +0800 Subject: [PATCH 3/5] Opt: Login twice a day on cloud --- tasks/dungeon/state.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tasks/dungeon/state.py b/tasks/dungeon/state.py index c7af7138c..5db8b98a0 100644 --- a/tasks/dungeon/state.py +++ b/tasks/dungeon/state.py @@ -139,6 +139,8 @@ class DungeonState(UI): limit = 30 else: limit = 60 + if self.config.is_cloud_game: + limit = 120 # Double event is not yet finished, do it today as possible update = get_server_next_update(self.config.Scheduler_ServerUpdate) From ca1fb97a2777c231dad7e135e272ef8bbb873b51 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 22 Jun 2024 00:42:40 +0800 Subject: [PATCH 4/5] Fix: Enter classic rogue --- .../ui_rogue/DIVERGENT_UNIVERSE_LOADED.png | Bin 0 -> 6042 bytes .../share/dungeon/ui_rogue/LAST_TELEPORT.png | Bin 0 -> 6291 bytes .../SIMULATED_UNIVERSE_LOADED_CLASSIC.png | Bin 0 -> 7003 bytes .../SURVIVAL_INDEX_OE_LOADED.png | Bin .../SURVIVAL_INDEX_SU_LOADED.SEARCH.png | Bin .../SURVIVAL_INDEX_SU_LOADED.png | Bin dev_tools/keyword_extract.py | 5 +- tasks/dungeon/assets/assets_dungeon_ui.py | 20 --- .../dungeon/assets/assets_dungeon_ui_rogue.py | 55 ++++++++ tasks/dungeon/keywords/nav.py | 52 +++++-- tasks/dungeon/stamina.py | 3 +- tasks/dungeon/ui.py | 50 +++---- tasks/dungeon/ui_rogue.py | 131 ++++++++++++++++++ tasks/rogue/entry/entry.py | 9 +- 14 files changed, 260 insertions(+), 65 deletions(-) create mode 100644 assets/share/dungeon/ui_rogue/DIVERGENT_UNIVERSE_LOADED.png create mode 100644 assets/share/dungeon/ui_rogue/LAST_TELEPORT.png create mode 100644 assets/share/dungeon/ui_rogue/SIMULATED_UNIVERSE_LOADED_CLASSIC.png rename assets/share/dungeon/{ui => ui_rogue}/SURVIVAL_INDEX_OE_LOADED.png (100%) rename assets/share/dungeon/{ui => ui_rogue}/SURVIVAL_INDEX_SU_LOADED.SEARCH.png (100%) rename assets/share/dungeon/{ui => ui_rogue}/SURVIVAL_INDEX_SU_LOADED.png (100%) create mode 100644 tasks/dungeon/assets/assets_dungeon_ui_rogue.py create mode 100644 tasks/dungeon/ui_rogue.py diff --git a/assets/share/dungeon/ui_rogue/DIVERGENT_UNIVERSE_LOADED.png b/assets/share/dungeon/ui_rogue/DIVERGENT_UNIVERSE_LOADED.png new file mode 100644 index 0000000000000000000000000000000000000000..211b064902687b096c54829f9a5afcb4be6c361e GIT binary patch literal 6042 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 U_cwUY{4uGmsduAX-TKl00sK^kZ~y=R literal 0 HcmV?d00001 diff --git a/assets/share/dungeon/ui_rogue/LAST_TELEPORT.png b/assets/share/dungeon/ui_rogue/LAST_TELEPORT.png new file mode 100644 index 0000000000000000000000000000000000000000..c1219a4f2f230f911237f90016e56318cebd5c15 GIT binary patch literal 6291 zcmeI0`8O2q7snrKgDly1BHEO)L_)SQN|CZ9`x;}(K1d=F*|IgpKEg1RrDn(=+1Ez) zoiJI)KH0zX`F#I|?+@Q|y5~ISKIhzXo^$W(-t(M$-f#5pYcn(QGXemZb)Z@X0MJpc z)IT896sIO~hl=7DJfNmt05Ea_nvBM>gzkXd%Jr%xqFD}Xljajc)B}0 zh1mn(Ka%m#&m@t|tvX4zXEo9oS}RM1y#!+77)UFdX)fD4VEu}XU9BlRlF^8h>r^__ zurais5t

lYI{7s2&yhINI=u;;P74!RO}zq?MKZ!TlOyI`NUEct*F=}F$Y3oa=LQKENXj6ya>40ynNj$5X6$n9S zNOb~HMQWfa%+W<7s!Nl7rMGShZRrt?gHnO|j^wV?yS=iUxa1%Fej963GpA=7U}YNC zJm=XQ7-q%NQ<35vP$G?P_elWwcM0E)6mP~8=Vzzq9f&Z}R#Wbg%bL5G>gn~#qnfwW zw1Dk?4{5}5Zf=0aqlM~|Pn`?e42&27r^#J&*-?h<$BaJ$cBA2n2WrBZIr^>2LV}D; zOe+#LIruBTqE(M&r`@NbgLf#=qtSph@GMOYQBsczJA7vC=38nIOYET4xavkGiXXLv zzc`FNPneM_dm_aZwQlkTr!RJ|1zu&4pmn+}d4_%Ah0MB0${|CdA2Yzb)~mn&<;3R> zSbgv+6?HU=Nv|(Z3*Nl+mY*pBusO=fz{vn4*6qfrU8DkCsd>KusQJzNq%es`w;2L} zR`$yapVUvB{Kko?XG#AiR8!AGZB4JGcJfTUGMfhdY=|IZ4sVJ&-=lh^A==NMX!x^F zrA@O{e!Hs3Oq^nW@^Z<8hu(@evw^qfH3O}BD}=-Pv{K|Lo7f?-ZU_$|mR8IfD)%lV zPjn%Y^MP1Xt7jfHTEjWP94fwX$&>SX%oDY}_|aBTnW%%P8ttn|FUud$^ilh$RTYZx zM>S`A5xnJC%|lXhT?qV@!YUzOatjD|fBSfY=TWh?A%v?e4sVC8pS+E@W%b5{U$TYU zcFsiJC{Es1$V9=HOQ1f}nglsR9Ua2446%5{)&L8QkJmQQHPI}TSQf8juZ9>iguS}j za8@j_P_I%VfPJ^o-$tn{-sCn$a`m+E=}ZZWvn(8ziO@4FZSQ99GoF@+m(gL;aeyXZj|I{7y2zW)5qC+MMHa;S1y|;KlMuBXslWex@Q?A6*%g z5kNS;XMOK(XmVlaLJ(I%JA1NHvQctyGO_59p_k#!es~enqhdqWVhf|^`L_)#^nall z`nZex(L#n_(br154g3t^^m`syqG~MZl#<86Ptynl)#ti75p zJk{Y;ozUonBIuyb;v`oi9Dm9C^Qbyt+y!kgaufDrF3Q$6Pi02)8uOZFYtMHjxuiK% z6DogtcXqZ)jbVl`ZOgIO`_o-At!syCMh{}bKio=hx)XgZx+P^KC8&cgFj|c(Nq5lthWCviPj8=2UzkVDQr@)OcXT8A`+~8ffMbqV#-=<^ z{@wTv_Eg_go`mso7Bp5`cPS6o|18_lNh9f4L#sw(z--3v6T z&8pN{0a+2X`L$w`Dz)Ol1Hp*k69<|5H}*OX{E{&56%%&oqiSG408v?twvSW@?X#}ozNCwwqfxRo8lDfhJ zr($3CKqlFO-Sc;K7dpQ{BB!)rkvNg3d2rN38+egQhgR~ zUFpJ${${*p{x~Qe`nXSa(&1=vSDY!7I|v{DNgwyAVhHDNx;`aVck3&+c=SUazspz6 z4XW+@pRV;j?{MlUPdU_|F)=XQaE6a<#2SS4e)ynyG1OQt8J*PD;a0l!xXPBxI@!*U zzxVjoB-$T*sjX1_AVNEYxxzk&M%nJjht(!oq&uN<{d_dCB@j< zVabt!x^ch2O_nert{W4iq~)5=7yXT0@VB0CyY;Syj>qxa2vpb22an^l{q&kL;{rbf zp4hoXT5|SwhmC!#t1D-4HMkZd3{~=&Lx#AIAXn1-K6^aAz|x>T_wDRteo){q{ogs= z-^adpO(I@kw;@YV_{CnOIv>m>lxwz14xaS;Eh%QL`uWCXe^3F4mIVwmCtJGheIm*b*b# zj7nhdmZ+4fXa{>7PD4MMxi8t1J64R9OTD-5E!`lHe!kdquJ896{4;pjJPVE|H7^Tb z-6Y2aaT3+re|&dVc>EYwb;ryD;`~1z)Q%i3p4ekud{KE+W?%0*^~b8-s^_~YD~W|6 zBJ(Ke_-Dj)uXd+)zxZwOn79lP5dmg?{Dxh3;&efI0Y^`Ju+cGm$*Y(+c{sCwx5wmQ zXpLz%x~Hxbj^6Yn6{9~YwTQQf)O5pD*7FZax<{XraHQ(V7Q6`J+=1GW{w871wx!^Q z9$A$bbaWt1ezmzT(VHbp*)~OOp$7K=2#^3EBn*JvV~Sq@z~>48i&g+Ay$68D{hejg zZOX=4ucM{@$bV#cyvO~gz2J#8_X1e5q`mC&j|CHl*RuDC%qJUIrUd`cKojDBAB)bY zC#{PYCJ4m8=e_Kln@z=sR7W|@Mx?I1ig1l!F0z|y{xoW$a4p_`TVI0d61@uHc- z4QKaOi$JF;1fr|~{mc=5atAC2jL(bJx=UOT}bQ}nas?}N=zxQ7|xs!rec>NM^lP#SUlMEq9gkFL?hGE21?B>D+(pKqmxsT zg_O2T{rt$5D+)*zzlgAGKm!0dx2)K-9h4G2(zgtoQ485qEBl9PCp{>|7UE}$kSXDTQt=wRe?8v=n)37n9| z<&?UWZT+`hWzKUI5)yQ^n|iu-`2_{i=GETw1+u%v2~fMPG~$N{YKo4?8Dr=9y*UQC zK~y-#!Mz;jr@rY)TL`vVy1KdPNGd>C|D7I5v&pf?mX!p{oNP9BsRcB@ERahkdx4#X_0VENL~3 zW@ZZRS5Gv*b65riq^F_XhWBNU5a#E=)IjFejIA>|B;3 zxQTqOAomLvt%qoAs|}_-jhLW6$1z9vW_PR!fK@t-Z=lylrG1)WH$V&A`^C?5wM-s` zROt&FgLAQ9LXeBZLKA}ot>X7uPk~k*@X?_35i^Jfz!~GOA_($X!P15%{22I^7dHw4 zzp~EeF@i`MkbFtwJgssyurPdz6s2wW1~T!=g5vZIMKr;v&(a#S!L`SLca%vCyRroc zPF4}^0OxMd0#*K#opk54=`tmI>nHNe-Je$?Xg~uYp)*OV_v)$2gde;<>#Gw}0#o0d zKdD$kE_2v2%?PF@VTDd2NOam=Cjj8x>G^tiLn($dH#0eBOL8V}G-Vw+t-1-q1=fg% zHLq#u0f%lkdDwh*c7V>kh2|r=-YM?^7&Zd-#2wSCBTSk1nSc20L||_0EAywn({EMa zJIl<%vV6hnU9IGF1pMggq}xP9;MSk&;fUWVc$}h~T-cBua`4#F)w>88MIz9vNV!r; zLWeESgASrD_e{xrdMJAO)tbr6N_|0{7R(o9>}`Rzgek81An7$&;sH~f4=cdG&}-2B z%ur5nZU|hVp^acO>GcN6ffTXVyezSR!%jvTLj@qNekWR4ga&jby`Ki4<~Ps75AhJ~ zW<~&RXFk31@fO30ucz=0Y^h)QY8oK4md9@^pE%#3z@c({CipD#JD$W_XYMt~{h}}b zNXMJWnKH>y_EqWzD`|r3;nPKT$Z-pv^lv;hFPP|WwKATx6p#z&w2JyA*u@A*j-nT| zM991eet&L0{M22+rdE&lw0SCyv8D*2buo`qHzOY^@5YR@o|AsH|EfkqD*kE7UAmvN zXyq>-V7#xIGd+8}WY|rE6SJIpc+2<|gFk2CdbEC{y+FXLDC^)JDK^{JLzWL;hpAb- zG~pF);kKSNku{2zwdOOq?tL2CkZwt4JWm@Dd~%7=ER^G$^Rt*34HIn>)ejezgvz+8 z7>$`iLZ!Z46pZ_zS9ZaVYp2oIO72sPi8@|*MSx!*{esy=wv*;@i1Tc1Z)S9v1un!$ zYqDrMAx02l?+xC=dpR6ZwS^aBT-wHG7)yfj=aOP8V%TH!-t4t~pQ$({*Azab&6IT> z`97ZOj;xK+EPYOfv`TVj{@u>J^q-9R;c^-GHC-~j^(73#@=nU2Q!aF3xm5}8#j^W< zq&V0)Q0*n=y{eeTLip8^ekAoe{braa&4+CGoM3&y8q$KWx^%|r%#$-Xo{BRP$=bQc z`jV1c?@10yLzC^^vcGjRG`X^M#s73{J6D2Sf>A^k##{B`=<hxB}>OslQlD7A;J*cRqczxJ!xNg{L*<+b|d2yJGc284I6HVKcbCIK>nX0Z; z-K~0FHG=M5fcIH1V&<7P+c(+f$9gn2T{f~eAq(UIau4jfqzvP=m^02&H>_7XVyu5V zy>+PUSq+{1z)7&Lify#d?$OM?SSh>`W;ZSC3xV6>-OgI!WyWnrofIss9Hd9yH@F$6c(^FK=rUmJtPeHDp1{gs37UUY_g>yK za2=Lf+FxQ`N?AI-d~?fk>%x}HRySYASuVZ-c`tc?4=;3wx3hcA;`>RN?|F@R-{+0( zpmy&((PM@X3EU8(9V@7v7AR%1sChg^P+btpCk6zu7U zW1(%P-xbNXHdd)7Q;$2Q({NbaH%bgi!pz$YWwuw#uUDEXoIW7w(mK-kV4{}r#6k|P zXtUcjPX}*?(`NW(gw^HN2@)0SgaQWwlLHy{)A!_e2?x>J^^=%&?ls+G7BpXJW@&1l z@;)u4bE1RMC)4LJ$R3M4R()LJ1pKth2_{w)%p=aN0kRI=vA#NLCz{f8x}7oY^nK{A zWQVXe{{Uyyi*80DN1$8oj`n=VXU6ae4d?Jmn8TT5$WFki%U7iH#TV|D8F)SRqKXdS zXHa`~wNY!)d9T07k2rqz@V3J{IwPH}m#~$=mHCxVeZ#iZ){?lqPM&94emT?lt5Nag zv?ndeIpu2VOv=4PFYBV&(X20!x%n&S&> z8L~*9jaysdgNW|~o(H~_h+4$`pI3>thYLGGEYG<8Yhym@SAH!0Rq2abn-Hv5tL7Gp zFo5`oOPM089{D<~_688_2_=aK`co!I!*xf@=z0_~q&Fu=RpgnmOhR6K8^N_`{P23u<6>n@@y=c*9uxyKNmPwso|s7 zlpg&g=Ly4>8hO#t%guSTxW2xG$pv{Wk{==GK8p=@8^$iD_>{ZfzryzI*6i1d#9aR; z)B3;Pb$uWG-bqXjs@P;)L|{aEMD)`$x_qS=oZ;% zRPFs_C)2y8wRWoA=}Hi<73~UhY8z#o6m7a% z)7%Mc&t741<|zi8j${kq|U1%_Srg`l#-Pc{uM6WbOI7Tw=b z>|{2ku=K&NXMv6rTMTuJAs%0FNGSU1RGy9B0|+-J8cafU4K$(z=|v3h++5$vd;Ju z7sMA_1F=;{v;Ig^VaiV;@CC;cI0V#9YYM| z$j`?w3Wxs4y(VELS`bp(A}^nD)I<&Pr4GVY;DKJ=l%>N%{A(LV0WxLwD>A(W;~2D^ zO--N&flklqK@IqB$!TrWe5+3elim_D`>8cWjX5A=mr(3FtG4BKv`cZTrLL^3WHYeC z;=lI`%c2sS#B<|^i}>ydouLUX7D@uakWA6(-d>9vyxdX)I#?S_22zyZA*r1=GBTtX zw3d*@z~215C!yehc|cC9b!^j5+)tcfqLiOK3-A{U)CQ}9{;NJpgx$lLZF`w;7lT2H zCXpJaHkNyB4)vf>&C!RS{19Hh8%92OJfN$zHCxjM+3{8g7xAm`q!Au2K3F&@%S+&|EZ{}0}An&T5{zecN8`!bHC zMN=$)Z>9HB@c!$wnm2i1u+@qrnAP7t^=n2;i&qv)e&Om+ zWqrM3EI=}t=Ei~RK^J*YXX`gXlhM+Ld7ZB|iVgdb=KKD9N5K!aDu_Xq zdpoTTYMiR>9xz}5=vI-VZdQ*E+dGf8x7&ioqO> zvail{U5tzvWXn*H8x88k)oC5z9gLD%`Y>bOrgtv03@umG_oJ7;Xc=!&GyXK+D2B3J zM=p@&mU60AR|gH?_(Yjjo)TQnf42X6Vz(JwAz8`SBc9s-XyB(#KDKD(+nTfA+Hhpa zCI0dH>sam2=GByfXn1M|HYcaNh}8vZH9153*Jfjp;`mVpD{dANUl|e}r!V!n#U0spO@*)1II6-y0K{{|;65z~6%2A2k za~Ex7{g=1o(PJHuh>LpEYH{>swCQ!8C~>pex}c9o{hLpsVPm6#2SlaqBtI!=F@7V! zyqjB^_OFL&V%X;bh>oXwWqo+0&(?OY^6BaL(W+T0cRPpCt&B#MIhPYN7eI<#gX*|qL}gBJ%kt#O|}JRpin6g&R4 zsG&zLP$Hu35zDObJJcD2qV%dXdv$SGpD|Wsow~V*YTb>QkwwQm8W;t(d5W z9p;IsV@D-MCnc#9w1N(dl`wv*+W%`Y`vbRf1dnc>#=6yPu14rp6cO*El;TJ`3+?KC zGCFbJ{P%;)p=H@_tVk>^RTO@X?!`W>J|+as>GWs?NcndRf+Z9B=*3~ zMRT*^K+4YAUF>d~zfoj?C?VzNiQTXE`lh1_p03tt1+)7POvT>30>LyV8niNtvBJ%7 zTTEo~|m2_*Sn> o_uoFN{vYO7W;|j6;OK}B;EXDB3lSnu{}WPEP4{+@ip8`40mOc&L;wH) literal 0 HcmV?d00001 diff --git a/assets/share/dungeon/ui/SURVIVAL_INDEX_OE_LOADED.png b/assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.png similarity index 100% rename from assets/share/dungeon/ui/SURVIVAL_INDEX_OE_LOADED.png rename to assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.png diff --git a/assets/share/dungeon/ui/SURVIVAL_INDEX_SU_LOADED.SEARCH.png b/assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_SU_LOADED.SEARCH.png similarity index 100% rename from assets/share/dungeon/ui/SURVIVAL_INDEX_SU_LOADED.SEARCH.png rename to assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_SU_LOADED.SEARCH.png diff --git a/assets/share/dungeon/ui/SURVIVAL_INDEX_SU_LOADED.png b/assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_SU_LOADED.png similarity index 100% rename from assets/share/dungeon/ui/SURVIVAL_INDEX_SU_LOADED.png rename to assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_SU_LOADED.png diff --git a/dev_tools/keyword_extract.py b/dev_tools/keyword_extract.py index a53c9d89b..bae260569 100644 --- a/dev_tools/keyword_extract.py +++ b/dev_tools/keyword_extract.py @@ -554,8 +554,9 @@ class KeywordExtract: yield hash_ def generate(self): - self.load_keywords(['模拟宇宙', '拟造花萼(金)', '拟造花萼(赤)', '凝滞虚影', '侵蚀隧洞', '历战余响', - '忘却之庭', '虚构叙事']) + self.load_keywords(['饰品提取', '差分宇宙', '模拟宇宙', + '拟造花萼(金)', '拟造花萼(赤)', '凝滞虚影', '侵蚀隧洞', '历战余响', + '最近更新', '忘却之庭', '虚构叙事', '末日幻影']) self.write_keywords(keyword_class='DungeonNav', output_file='./tasks/dungeon/keywords/nav.py') self.load_keywords(['行动摘要', '生存索引', '每日实训', '模拟宇宙', '逐光捡金', '战术训练']) self.write_keywords(keyword_class='DungeonTab', output_file='./tasks/dungeon/keywords/tab.py') diff --git a/tasks/dungeon/assets/assets_dungeon_ui.py b/tasks/dungeon/assets/assets_dungeon_ui.py index 75bbfd166..ba77ca705 100644 --- a/tasks/dungeon/assets/assets_dungeon_ui.py +++ b/tasks/dungeon/assets/assets_dungeon_ui.py @@ -163,26 +163,6 @@ SURVIVAL_INDEX_CLICK = ButtonWrapper( button=(332, 94, 370, 133), ), ) -SURVIVAL_INDEX_OE_LOADED = ButtonWrapper( - name='SURVIVAL_INDEX_OE_LOADED', - share=Button( - file='./assets/share/dungeon/ui/SURVIVAL_INDEX_OE_LOADED.png', - area=(473, 207, 498, 232), - search=(453, 187, 518, 252), - color=(185, 135, 74), - button=(473, 207, 498, 232), - ), -) -SURVIVAL_INDEX_SU_LOADED = ButtonWrapper( - name='SURVIVAL_INDEX_SU_LOADED', - share=Button( - file='./assets/share/dungeon/ui/SURVIVAL_INDEX_SU_LOADED.png', - area=(451, 286, 476, 302), - search=(449, 263, 489, 356), - color=(142, 150, 197), - button=(451, 286, 476, 302), - ), -) TAB_SEARCH = ButtonWrapper( name='TAB_SEARCH', share=Button( diff --git a/tasks/dungeon/assets/assets_dungeon_ui_rogue.py b/tasks/dungeon/assets/assets_dungeon_ui_rogue.py new file mode 100644 index 000000000..6cbf332dc --- /dev/null +++ b/tasks/dungeon/assets/assets_dungeon_ui_rogue.py @@ -0,0 +1,55 @@ +from module.base.button import Button, ButtonWrapper + +# This file was auto-generated, do not modify it manually. To generate: +# ``` python -m dev_tools.button_extract ``` + +DIVERGENT_UNIVERSE_LOADED = ButtonWrapper( + name='DIVERGENT_UNIVERSE_LOADED', + share=Button( + file='./assets/share/dungeon/ui_rogue/DIVERGENT_UNIVERSE_LOADED.png', + area=(893, 608, 911, 628), + search=(873, 588, 931, 648), + color=(103, 102, 102), + button=(893, 608, 911, 628), + ), +) +LAST_TELEPORT = ButtonWrapper( + name='LAST_TELEPORT', + share=Button( + file='./assets/share/dungeon/ui_rogue/LAST_TELEPORT.png', + area=(1018, 579, 1038, 599), + search=(998, 559, 1058, 619), + color=(84, 83, 85), + button=(1018, 579, 1038, 599), + ), +) +SIMULATED_UNIVERSE_LOADED_CLASSIC = ButtonWrapper( + name='SIMULATED_UNIVERSE_LOADED_CLASSIC', + share=Button( + file='./assets/share/dungeon/ui_rogue/SIMULATED_UNIVERSE_LOADED_CLASSIC.png', + area=(549, 607, 572, 629), + search=(529, 587, 592, 649), + color=(147, 137, 157), + button=(549, 607, 572, 629), + ), +) +SURVIVAL_INDEX_OE_LOADED = ButtonWrapper( + name='SURVIVAL_INDEX_OE_LOADED', + share=Button( + file='./assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_OE_LOADED.png', + area=(473, 207, 498, 232), + search=(453, 187, 518, 252), + color=(185, 135, 74), + button=(473, 207, 498, 232), + ), +) +SURVIVAL_INDEX_SU_LOADED = ButtonWrapper( + name='SURVIVAL_INDEX_SU_LOADED', + share=Button( + file='./assets/share/dungeon/ui_rogue/SURVIVAL_INDEX_SU_LOADED.png', + area=(451, 286, 476, 302), + search=(449, 263, 489, 356), + color=(142, 150, 197), + button=(451, 286, 476, 302), + ), +) diff --git a/tasks/dungeon/keywords/nav.py b/tasks/dungeon/keywords/nav.py index 720d3cfbe..a6980244a 100644 --- a/tasks/dungeon/keywords/nav.py +++ b/tasks/dungeon/keywords/nav.py @@ -3,8 +3,26 @@ from .classes import DungeonNav # This file was auto-generated, do not modify it manually. To generate: # ``` python -m dev_tools.keyword_extract ``` -Simulated_Universe = DungeonNav( +Ornament_Extraction = DungeonNav( id=1, + name='Ornament_Extraction', + cn='饰品提取', + cht='飾品提取', + en='Ornament Extraction', + jp='オーナメント抽出', + es='Extracción de ornamentos', +) +Divergent_Universe = DungeonNav( + id=2, + name='Divergent_Universe', + cn='差分宇宙', + cht='差分宇宙', + en='Divergent Universe', + jp='階差宇宙', + es='Universo Diferenciado', +) +Simulated_Universe = DungeonNav( + id=3, name='Simulated_Universe', cn='模拟宇宙', cht='模擬宇宙', @@ -13,7 +31,7 @@ Simulated_Universe = DungeonNav( es='Universo Simulado', ) Calyx_Golden = DungeonNav( - id=2, + id=4, name='Calyx_Golden', cn='拟造花萼(金)', cht='擬造花萼(金)', @@ -22,7 +40,7 @@ Calyx_Golden = DungeonNav( es='Cáliz (oro)', ) Calyx_Crimson = DungeonNav( - id=3, + id=5, name='Calyx_Crimson', cn='拟造花萼(赤)', cht='擬造花萼(赤)', @@ -31,7 +49,7 @@ Calyx_Crimson = DungeonNav( es='Cáliz (carmesí)', ) Stagnant_Shadow = DungeonNav( - id=4, + id=6, name='Stagnant_Shadow', cn='凝滞虚影', cht='凝滯虛影', @@ -40,7 +58,7 @@ Stagnant_Shadow = DungeonNav( es='Sombra paralizada', ) Cavern_of_Corrosion = DungeonNav( - id=5, + id=7, name='Cavern_of_Corrosion', cn='侵蚀隧洞', cht='侵蝕隧洞', @@ -49,7 +67,7 @@ Cavern_of_Corrosion = DungeonNav( es='Caverna de la corrosión', ) Echo_of_War = DungeonNav( - id=6, + id=8, name='Echo_of_War', cn='历战余响', cht='歷戰餘響', @@ -57,8 +75,17 @@ Echo_of_War = DungeonNav( jp='歴戦余韻', es='Ecos de la guerra', ) +Latest_Update = DungeonNav( + id=9, + name='Latest_Update', + cn='最近更新', + cht='最近更新', + en='Latest Update', + jp='最近更新', + es='Actualización reciente', +) Forgotten_Hall = DungeonNav( - id=7, + id=10, name='Forgotten_Hall', cn='忘却之庭', cht='忘卻之庭', @@ -67,7 +94,7 @@ Forgotten_Hall = DungeonNav( es='Salón olvidado', ) Pure_Fiction = DungeonNav( - id=8, + id=11, name='Pure_Fiction', cn='虚构叙事', cht='虛構敘事', @@ -75,3 +102,12 @@ Pure_Fiction = DungeonNav( jp='虚構叙事', es='Pura ficción', ) +Apocalyptic_Shadow = DungeonNav( + id=12, + name='Apocalyptic_Shadow', + cn='末日幻影', + cht='末日幻影', + en='Apocalyptic Shadow', + jp='末日の幻影', + es='Espejismo apocalíptico', +) diff --git a/tasks/dungeon/stamina.py b/tasks/dungeon/stamina.py index ac9390289..6f28729b3 100644 --- a/tasks/dungeon/stamina.py +++ b/tasks/dungeon/stamina.py @@ -4,6 +4,7 @@ from module.logger import logger from module.ocr.ocr import Digit from tasks.base.page import page_guide from tasks.dungeon.assets.assets_dungeon_stamina import * +from tasks.dungeon.keywords import KEYWORDS_DUNGEON_TAB from tasks.dungeon.ui import DungeonUI @@ -138,7 +139,7 @@ class DungeonStamina(DungeonUI): """ logger.hr('Immersifier store', level=2) logger.info(f'Max store: {max_store}') - self.dungeon_goto_rogue() + self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index) self.dungeon_update_stamina() before = self.config.stored.Immersifier.value diff --git a/tasks/dungeon/ui.py b/tasks/dungeon/ui.py index 5faecc52d..ce61a8309 100644 --- a/tasks/dungeon/ui.py +++ b/tasks/dungeon/ui.py @@ -17,6 +17,7 @@ from tasks.base.page import page_guide from tasks.combat.assets.assets_combat_interact import DUNGEON_COMBAT_INTERACT, DUNGEON_COMBAT_INTERACT_TEXT from tasks.combat.assets.assets_combat_prepare import COMBAT_PREPARE from tasks.dungeon.assets.assets_dungeon_ui import * +from tasks.dungeon.assets.assets_dungeon_ui_rogue import * from tasks.dungeon.keywords import ( DungeonList, DungeonNav, @@ -337,6 +338,17 @@ class DungeonUI(DungeonState): logger.info('Treasures lightward loaded (event locked)') return True + def _dungeon_list_button_has_content(self): + # Check if having any content + # List background: 254, guild border: 225 + r, g, b = cv2.split(self.image_crop(LIST_LOADED_CHECK, copy=False)) + minimum = cv2.min(cv2.min(r, g), b) + minimum = inrange(minimum, lower=0, upper=180) + if minimum.size > 100: + return True + else: + return False + def _dungeon_wait_until_dungeon_list_loaded(self, skip_first_screenshot=True): timeout = Timer(1, count=3).start() while 1: @@ -350,14 +362,9 @@ class DungeonUI(DungeonState): logger.warning('Wait until dungeon list loaded timeout') return False - # Check if having any content - # List background: 254, guild border: 225 - r, g, b = cv2.split(self.image_crop(LIST_LOADED_CHECK, copy=False)) - minimum = cv2.min(cv2.min(r, g), b) - minimum = inrange(minimum, lower=0, upper=180) - if minimum.size > 100: + if self._dungeon_list_button_has_content(): logger.info('Dungeon list loaded') - break + return True def _dungeon_wait_until_echo_or_war_stabled(self, skip_first_screenshot=True): """ @@ -431,12 +438,13 @@ class DungeonUI(DungeonState): break # Check if it's at the first page. - if button := DUNGEON_NAV_LIST.keyword2button(KEYWORDS_DUNGEON_NAV.Simulated_Universe, show_warning=False): + if DUNGEON_NAV_LIST.keyword2button(KEYWORDS_DUNGEON_NAV.Simulated_Universe, show_warning=False): # Going to use a faster method to navigate but can only start from list top logger.info('DUNGEON_NAV_LIST at top') # Update points if possible - if DUNGEON_NAV_LIST.is_row_selected(button, main=self): - self.dungeon_update_simuni() + # 2.3, No longer weekly points after Divergent Universe unlocked + # if DUNGEON_NAV_LIST.is_row_selected(button, main=self): + # self.dungeon_update_simuni() # Treasures lightward is always at top elif DUNGEON_NAV_LIST.keyword2button(KEYWORDS_DUNGEON_NAV.Forgotten_Hall, show_warning=False) \ or DUNGEON_NAV_LIST.keyword2button(KEYWORDS_DUNGEON_NAV.Pure_Fiction, show_warning=False): @@ -450,6 +458,8 @@ class DungeonUI(DungeonState): # Check the first page if nav in [ KEYWORDS_DUNGEON_NAV.Simulated_Universe, + KEYWORDS_DUNGEON_NAV.Divergent_Universe, + KEYWORDS_DUNGEON_NAV.Ornament_Extraction, KEYWORDS_DUNGEON_NAV.Calyx_Golden, KEYWORDS_DUNGEON_NAV.Calyx_Crimson, KEYWORDS_DUNGEON_NAV.Stagnant_Shadow, @@ -698,26 +708,6 @@ class DungeonUI(DungeonState): logger.attr('DungeonInteract', None) return None - def dungeon_goto_rogue(self): - """ - Goto Simulated Universe page but not pressing the TELEPORT button - - Pages: - in: Any - out: page_guide, Survival_Index, Simulated_Universe - - Examples: - self = DungeonUI('src') - self.device.screenshot() - self.dungeon_goto_rogue() - self._rogue_teleport() - """ - self.dungeon_tab_goto(KEYWORDS_DUNGEON_TAB.Survival_Index) - if self.appear(SURVIVAL_INDEX_SU_LOADED): - logger.info('Already at nav Simulated_Universe') - else: - self._dungeon_nav_goto(KEYWORDS_DUNGEON_NAV.Simulated_Universe) - def dungeon_goto(self, dungeon: DungeonList): """ Returns: diff --git a/tasks/dungeon/ui_rogue.py b/tasks/dungeon/ui_rogue.py new file mode 100644 index 000000000..1d2304115 --- /dev/null +++ b/tasks/dungeon/ui_rogue.py @@ -0,0 +1,131 @@ +from module.base.timer import Timer +from module.base.utils import random_rectangle_vector +from module.logger import logger +from tasks.base.page import page_guide +from tasks.dungeon.assets.assets_dungeon_ui import * +from tasks.dungeon.assets.assets_dungeon_ui_rogue import * +from tasks.dungeon.keywords import KEYWORDS_DUNGEON_NAV, KEYWORDS_DUNGEON_TAB +from tasks.dungeon.ui import DungeonUI, SWITCH_DUNGEON_TAB +from tasks.forgotten_hall.assets.assets_forgotten_hall_ui import TELEPORT + + +class DungeonRogueUI(DungeonUI): + def dungeon_goto_rogue(self): + """ + Goto Simulated Universe page but not pressing the TELEPORT button + + Pages: + in: Any + out: page_guide, Survival_Index, Simulated_Universe + + Examples: + self = DungeonUI('src') + self.device.screenshot() + self.dungeon_goto_rogue() + self._rogue_teleport() + """ + logger.hr('Dungeon tab goto', level=2) + ui_switched = self.ui_ensure(page_guide) + SWITCH_DUNGEON_TAB.wait(main=self) + + if ( + self.appear(SIMULATED_UNIVERSE_CLICK) + or self.appear(SIMULATED_UNIVERSE_CHECK) + or self.appear(SURVIVAL_INDEX_OE_LOADED) + ): + logger.info('Having rogue tab') + state = KEYWORDS_DUNGEON_TAB.Simulated_Universe + # Switch tab + tab_switched = SWITCH_DUNGEON_TAB.set(state, main=self) + if ui_switched or tab_switched: + logger.info(f'Tab goto {state}, wait until loaded') + self._dungeon_wait_until_rogue_loaded() + # Switch nav + self._dungeon_nav_goto(KEYWORDS_DUNGEON_NAV.Simulated_Universe) + # No idea how to wait list loaded + # List is not able to swipe without fully loaded + self.wait_until_stable(LIST_LOADED_CHECK) + # Swipe + self._dungeon_rogue_swipe_down() + else: + logger.info('No rogue tab') + state = KEYWORDS_DUNGEON_TAB.Survival_Index + # Switch tab + tab_switched = SWITCH_DUNGEON_TAB.set(state, main=self) + if ui_switched or tab_switched: + logger.info(f'Tab goto {state}, wait until loaded') + self._dungeon_wait_survival_index_loaded() + # Switch nav + if self.appear(SURVIVAL_INDEX_SU_LOADED): + logger.info('Already at nav Simulated_Universe') + else: + self._dungeon_nav_goto(KEYWORDS_DUNGEON_NAV.Simulated_Universe) + + def _dungeon_wait_until_rogue_loaded(self, skip_first_screenshot=True): + """ + Returns: + bool: True if wait success, False if wait timeout. + + Pages: + in: page_guide, Simulated_Universe + """ + timeout = Timer(2, count=4).start() + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + if timeout.reached(): + logger.warning('Wait rogue tab loaded timeout') + return False + if self.appear(DIVERGENT_UNIVERSE_LOADED): + logger.info('Rogue tab loaded, DIVERGENT_UNIVERSE_LOADED') + return True + # No LAST_TELEPORT, may hit teleport button of old screenshots from Ornament Extraction + # if self.appear(LAST_TELEPORT): + # logger.info('Rogue tab loaded, LAST_TELEPORT') + # return True + + def _dungeon_rogue_swipe_down(self, skip_first_screenshot=True): + """ + Swipe down to find teleport button of classic rogue + Note that this method will change SIMULATED_UNIVERSE_LOADED_CLASSIC.search, original value should have a backup + """ + # Already having classic rogue entry insight + SIMULATED_UNIVERSE_LOADED_CLASSIC.load_search(OCR_DUNGEON_LIST.button) + if self.appear(SIMULATED_UNIVERSE_LOADED_CLASSIC): + buttons = TELEPORT.match_multi_template(self.device.image) + y = SIMULATED_UNIVERSE_LOADED_CLASSIC.button[1] + for button in buttons: + # And having a teleport button below + if button.button[1] > y: + logger.info('Classic rogue teleport already in sight') + return True + + logger.info('Dungeon rogue swipe down') + interval = Timer(2, count=4) + while 1: + if skip_first_screenshot: + skip_first_screenshot = False + else: + self.device.screenshot() + + # End + if self.appear(SIMULATED_UNIVERSE_LOADED_CLASSIC): + if self.appear(LAST_TELEPORT): + logger.info('Classic rogue teleport at end') + return True + + # Swipe + if interval.reached(): + p1, p2 = random_rectangle_vector( + (0, -450), box=OCR_DUNGEON_LIST.button, random_range=(-20, -20, 20, 20), padding=5) + self.device.swipe(p1, p2) + interval.reset() + + +if __name__ == '__main__': + self = DungeonRogueUI('src') + self.device.screenshot() + self.dungeon_goto_rogue() diff --git a/tasks/rogue/entry/entry.py b/tasks/rogue/entry/entry.py index 2360c787e..225510b49 100644 --- a/tasks/rogue/entry/entry.py +++ b/tasks/rogue/entry/entry.py @@ -15,7 +15,7 @@ from tasks.base.page import page_guide, page_item, page_main, page_rogue from tasks.dungeon.keywords import DungeonList from tasks.dungeon.keywords.dungeon import Simulated_Universe_World_1 from tasks.dungeon.state import OcrSimUniPoint -from tasks.dungeon.ui import DungeonUI +from tasks.dungeon.ui_rogue import DungeonRogueUI from tasks.forgotten_hall.assets.assets_forgotten_hall_ui import TELEPORT from tasks.rogue.assets.assets_rogue_entry import ( LEVEL_CONFIRM, @@ -103,7 +103,7 @@ class OcrRogueWorld(Ocr): return 0 -class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonUI): +class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonRogueUI): def _rogue_world_wait(self, skip_first_screenshot=True): """ Wait is_page_rogue_main() fully loaded @@ -308,7 +308,7 @@ class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonUI): def _rogue_teleport(self, skip_first_screenshot=True): """ Pages: - in: page_guide, Survival_Index, Simulated_Universe + in: page_guide, Simulated_Universe, Simulated_Universe out: page_rogue, is_page_rogue_main() """ logger.info('Rogue teleport') @@ -333,7 +333,8 @@ class RogueEntry(RouteBase, RogueRewardHandler, RoguePathHandler, DungeonUI): if self.appear(page_guide.check_button, interval=2): buttons = TELEPORT.match_multi_template(self.device.image) if len(buttons): - buttons = sorted(buttons, key=lambda x: x.area[1]) + # 2.3, classic rogue is always at bottom + buttons = sorted(buttons, key=lambda x: x.area[1], reverse=True) self.device.click(buttons[0]) continue From b4f75165b1d8c6c1c2d05f999b528fa4328fa358 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Sat, 22 Jun 2024 00:56:58 +0800 Subject: [PATCH 5/5] Fix: Consider Ornament_Extraction as dungeon nav top --- tasks/dungeon/ui.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tasks/dungeon/ui.py b/tasks/dungeon/ui.py index ce61a8309..f1a4d3279 100644 --- a/tasks/dungeon/ui.py +++ b/tasks/dungeon/ui.py @@ -438,7 +438,8 @@ class DungeonUI(DungeonState): break # Check if it's at the first page. - if DUNGEON_NAV_LIST.keyword2button(KEYWORDS_DUNGEON_NAV.Simulated_Universe, show_warning=False): + if DUNGEON_NAV_LIST.keyword2button(KEYWORDS_DUNGEON_NAV.Simulated_Universe, show_warning=False) \ + or DUNGEON_NAV_LIST.keyword2button(KEYWORDS_DUNGEON_NAV.Ornament_Extraction, show_warning=False): # Going to use a faster method to navigate but can only start from list top logger.info('DUNGEON_NAV_LIST at top') # Update points if possible