From 6d06346210f85fb43f043913b32d41f07690ab94 Mon Sep 17 00:00:00 2001 From: LmeSzinc <37934724+LmeSzinc@users.noreply.github.com> Date: Fri, 23 Jul 2021 18:26:24 +0800 Subject: [PATCH] Add: Azur Anthem Event maps - Handle event animation after the 4th battle - Add ensure_edge_insight configuration --- .../template/TEMPLATE_SIREN_HarukaAmami.gif | Bin 0 -> 3260 bytes .../template/TEMPLATE_SIREN_HarukaAmami.gif | Bin 0 -> 3260 bytes .../template/TEMPLATE_SIREN_HarukaAmami.gif | Bin 0 -> 3260 bytes .../template/TEMPLATE_SIREN_HarukaAmami.gif | Bin 0 -> 3260 bytes campaign/event_20210722_cn/campaign_base.py | 89 ++++++++++++++++++ campaign/event_20210722_cn/sp.py | 71 ++++++++++++++ campaign/event_20210722_cn/sp1.py | 62 ++++++++++++ campaign/event_20210722_cn/sp2.py | 75 +++++++++++++++ campaign/event_20210722_cn/sp3.py | 72 ++++++++++++++ campaign/event_20210722_cn/sp4.py | 72 ++++++++++++++ module/campaign/run.py | 2 + module/config/config.py | 4 + module/map/camera.py | 6 +- module/map/utils.py | 25 +++++ module/template/assets.py | 1 + 15 files changed, 476 insertions(+), 3 deletions(-) create mode 100644 assets/cn/template/TEMPLATE_SIREN_HarukaAmami.gif create mode 100644 assets/en/template/TEMPLATE_SIREN_HarukaAmami.gif create mode 100644 assets/jp/template/TEMPLATE_SIREN_HarukaAmami.gif create mode 100644 assets/tw/template/TEMPLATE_SIREN_HarukaAmami.gif create mode 100644 campaign/event_20210722_cn/campaign_base.py create mode 100644 campaign/event_20210722_cn/sp.py create mode 100644 campaign/event_20210722_cn/sp1.py create mode 100644 campaign/event_20210722_cn/sp2.py create mode 100644 campaign/event_20210722_cn/sp3.py create mode 100644 campaign/event_20210722_cn/sp4.py diff --git a/assets/cn/template/TEMPLATE_SIREN_HarukaAmami.gif b/assets/cn/template/TEMPLATE_SIREN_HarukaAmami.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6c534c0d973741e072fcbbc109c0398646899d1 GIT binary patch literal 3260 zcmeI!`8U-2AHebVFwAhtsAMo#GecvSeF({S0H8owkcJ1obtBs9~mo8npc=6(e3m59^>(8A#clPYry1Kg4r%#_cb?W5FlgE!A zKX&Zc(W6JJtE&$mK3rK@dFarg^78Vsva-_B(gOz$?BBni&*ztvloS^i7Zw)g<>hg? zTn>kmm6gS2vokU>5Clm}OWU(&&+gs3larH^l9G1q+O=cHj>N>ogoK3c+qZAsx^>Hz zEt@xQj*gCwii(PijEsng2oDcuu~;D?A)7XB+PHCJP*BkN_3PKITNfA@xMt0ofPesh ze}7+JUmqWzRjXEcdwY9&dU|+xxVyW%xw*Nzy1KZyI6FJr+uN^LvBJ*I&eqm;*|KHU z*4CDmmKGKk=H}*RW@e_QrpCs``uh4hIyzcfS{fP}bUK|%rK+o|D=8^~f9HR+0ov>@ z-cAAjj!YjX6GJ0O-0Uo%P2q_&c)b3PD}HN3D!Qs6yGL89_Ou=RyLBW)TzsSPpGGUCZ@3q!yY~fufKyOn0S4qjh73LRA~{#Ykj$0<#gaZCw7X(4y)N9XcMyjI zK-wq-c|j^w4=A@~04fzO11ABj9Epk*OU>tjvQ_D6i(Rq@qG`qeNk;%)R*v}B)p39J z1>%Cqg0X^`^6uTc@$qrU%Bxqepe&=KqZlrjESM=zo;-Q{`0<=97%O+~-0AP{$5?@; zKv256x;i^Mp(zj)OcO{6=E#*RS1w<^3^jq2G&D4vKYt$6dwX0XJ_Ve?bbHvNb3sQn1;^gGCa^*?~ z2M6fL^5x4hM{I0tFhmRu4WS*ny1EPoW66>wnwpwW5E_jJ1))$VWHK4P=D+g~Yyi@c zJ0gA`f-lx}Xa=A+H1AiPwbEj;*fC#KJ6ev4FpqIK7HmIc!e@v>(ooZmr5a0QR~j(% zg9d$QlF}3p1SRz`d#W5cPrF%R42Ap!0qt4U!=v&P+muc;K2(U$Q82qEC>nN_TcE}a z@*FE_kziA3#r%}8aF=`~`FTf)C@PS~nT%w`2t} z0W>+DpdQ=G6tQKM@p6kmS+F1@LnA3G=bT9vKyW}vpb!D@KutW$2gv|!n*QwdamKf# z4UbGuiV67t0tOZ&Q&Us0N&YrS-n@AO@t89M1_@Rp7#o-w4<9~+K?2QyTKsK?{LBW{ zAuvLko10;NKr^uXz|4T{0l|Rb0ja31t;O2o$dMx`io*PWW?%(!@ZdpMAXt82Z18xz zef#!7Ir8)KF*&dTNl#CQ`7sAZN=gdMkDWVr!UBO>#KpxyEntDf#>Qf1#KgqF2*C;@ zEG#TEG!)7KBLo%*WCLme!vlhWwFed+KUW7dgUMuK;Q`Hn;bCQE1(O5o4HFX+BO@ay zhk=2Co}L~I4@?di9%^c8Dk>_<%F2rtEmBZW_y_*Y|LqkJjHzDQP&K|(FSa0B22gWK z6jDGF(O4*@!0@i4qEvdDtVUR10lAvpnnPOb$tTB$N-fk6ZXov6hjsDwJ$jM)`Psed zj(HNF>JvF`T=}JZev4^`m#UsCGC@|9lp+w!(&AWQ&ThYv&2`PRLxGU3Bp-QtYAC!@ zRz(U>fxRURAFgy!h9f7BK(GeHUAWBF8qxJUKZIp;cGgCLw>(RKn4{F?)e76^FsmwYK6$m7k0KV>0OFa yU?Bwn0Rn*UOhb|1k`4(lD9Th#FCp?&^|gs0uqVw<%`WMr?G!+p_fEqmvH1hBVkJia literal 0 HcmV?d00001 diff --git a/assets/en/template/TEMPLATE_SIREN_HarukaAmami.gif b/assets/en/template/TEMPLATE_SIREN_HarukaAmami.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6c534c0d973741e072fcbbc109c0398646899d1 GIT binary patch literal 3260 zcmeI!`8U-2AHebVFwAhtsAMo#GecvSeF({S0H8owkcJ1obtBs9~mo8npc=6(e3m59^>(8A#clPYry1Kg4r%#_cb?W5FlgE!A zKX&Zc(W6JJtE&$mK3rK@dFarg^78Vsva-_B(gOz$?BBni&*ztvloS^i7Zw)g<>hg? zTn>kmm6gS2vokU>5Clm}OWU(&&+gs3larH^l9G1q+O=cHj>N>ogoK3c+qZAsx^>Hz zEt@xQj*gCwii(PijEsng2oDcuu~;D?A)7XB+PHCJP*BkN_3PKITNfA@xMt0ofPesh ze}7+JUmqWzRjXEcdwY9&dU|+xxVyW%xw*Nzy1KZyI6FJr+uN^LvBJ*I&eqm;*|KHU z*4CDmmKGKk=H}*RW@e_QrpCs``uh4hIyzcfS{fP}bUK|%rK+o|D=8^~f9HR+0ov>@ z-cAAjj!YjX6GJ0O-0Uo%P2q_&c)b3PD}HN3D!Qs6yGL89_Ou=RyLBW)TzsSPpGGUCZ@3q!yY~fufKyOn0S4qjh73LRA~{#Ykj$0<#gaZCw7X(4y)N9XcMyjI zK-wq-c|j^w4=A@~04fzO11ABj9Epk*OU>tjvQ_D6i(Rq@qG`qeNk;%)R*v}B)p39J z1>%Cqg0X^`^6uTc@$qrU%Bxqepe&=KqZlrjESM=zo;-Q{`0<=97%O+~-0AP{$5?@; zKv256x;i^Mp(zj)OcO{6=E#*RS1w<^3^jq2G&D4vKYt$6dwX0XJ_Ve?bbHvNb3sQn1;^gGCa^*?~ z2M6fL^5x4hM{I0tFhmRu4WS*ny1EPoW66>wnwpwW5E_jJ1))$VWHK4P=D+g~Yyi@c zJ0gA`f-lx}Xa=A+H1AiPwbEj;*fC#KJ6ev4FpqIK7HmIc!e@v>(ooZmr5a0QR~j(% zg9d$QlF}3p1SRz`d#W5cPrF%R42Ap!0qt4U!=v&P+muc;K2(U$Q82qEC>nN_TcE}a z@*FE_kziA3#r%}8aF=`~`FTf)C@PS~nT%w`2t} z0W>+DpdQ=G6tQKM@p6kmS+F1@LnA3G=bT9vKyW}vpb!D@KutW$2gv|!n*QwdamKf# z4UbGuiV67t0tOZ&Q&Us0N&YrS-n@AO@t89M1_@Rp7#o-w4<9~+K?2QyTKsK?{LBW{ zAuvLko10;NKr^uXz|4T{0l|Rb0ja31t;O2o$dMx`io*PWW?%(!@ZdpMAXt82Z18xz zef#!7Ir8)KF*&dTNl#CQ`7sAZN=gdMkDWVr!UBO>#KpxyEntDf#>Qf1#KgqF2*C;@ zEG#TEG!)7KBLo%*WCLme!vlhWwFed+KUW7dgUMuK;Q`Hn;bCQE1(O5o4HFX+BO@ay zhk=2Co}L~I4@?di9%^c8Dk>_<%F2rtEmBZW_y_*Y|LqkJjHzDQP&K|(FSa0B22gWK z6jDGF(O4*@!0@i4qEvdDtVUR10lAvpnnPOb$tTB$N-fk6ZXov6hjsDwJ$jM)`Psed zj(HNF>JvF`T=}JZev4^`m#UsCGC@|9lp+w!(&AWQ&ThYv&2`PRLxGU3Bp-QtYAC!@ zRz(U>fxRURAFgy!h9f7BK(GeHUAWBF8qxJUKZIp;cGgCLw>(RKn4{F?)e76^FsmwYK6$m7k0KV>0OFa yU?Bwn0Rn*UOhb|1k`4(lD9Th#FCp?&^|gs0uqVw<%`WMr?G!+p_fEqmvH1hBVkJia literal 0 HcmV?d00001 diff --git a/assets/jp/template/TEMPLATE_SIREN_HarukaAmami.gif b/assets/jp/template/TEMPLATE_SIREN_HarukaAmami.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6c534c0d973741e072fcbbc109c0398646899d1 GIT binary patch literal 3260 zcmeI!`8U-2AHebVFwAhtsAMo#GecvSeF({S0H8owkcJ1obtBs9~mo8npc=6(e3m59^>(8A#clPYry1Kg4r%#_cb?W5FlgE!A zKX&Zc(W6JJtE&$mK3rK@dFarg^78Vsva-_B(gOz$?BBni&*ztvloS^i7Zw)g<>hg? zTn>kmm6gS2vokU>5Clm}OWU(&&+gs3larH^l9G1q+O=cHj>N>ogoK3c+qZAsx^>Hz zEt@xQj*gCwii(PijEsng2oDcuu~;D?A)7XB+PHCJP*BkN_3PKITNfA@xMt0ofPesh ze}7+JUmqWzRjXEcdwY9&dU|+xxVyW%xw*Nzy1KZyI6FJr+uN^LvBJ*I&eqm;*|KHU z*4CDmmKGKk=H}*RW@e_QrpCs``uh4hIyzcfS{fP}bUK|%rK+o|D=8^~f9HR+0ov>@ z-cAAjj!YjX6GJ0O-0Uo%P2q_&c)b3PD}HN3D!Qs6yGL89_Ou=RyLBW)TzsSPpGGUCZ@3q!yY~fufKyOn0S4qjh73LRA~{#Ykj$0<#gaZCw7X(4y)N9XcMyjI zK-wq-c|j^w4=A@~04fzO11ABj9Epk*OU>tjvQ_D6i(Rq@qG`qeNk;%)R*v}B)p39J z1>%Cqg0X^`^6uTc@$qrU%Bxqepe&=KqZlrjESM=zo;-Q{`0<=97%O+~-0AP{$5?@; zKv256x;i^Mp(zj)OcO{6=E#*RS1w<^3^jq2G&D4vKYt$6dwX0XJ_Ve?bbHvNb3sQn1;^gGCa^*?~ z2M6fL^5x4hM{I0tFhmRu4WS*ny1EPoW66>wnwpwW5E_jJ1))$VWHK4P=D+g~Yyi@c zJ0gA`f-lx}Xa=A+H1AiPwbEj;*fC#KJ6ev4FpqIK7HmIc!e@v>(ooZmr5a0QR~j(% zg9d$QlF}3p1SRz`d#W5cPrF%R42Ap!0qt4U!=v&P+muc;K2(U$Q82qEC>nN_TcE}a z@*FE_kziA3#r%}8aF=`~`FTf)C@PS~nT%w`2t} z0W>+DpdQ=G6tQKM@p6kmS+F1@LnA3G=bT9vKyW}vpb!D@KutW$2gv|!n*QwdamKf# z4UbGuiV67t0tOZ&Q&Us0N&YrS-n@AO@t89M1_@Rp7#o-w4<9~+K?2QyTKsK?{LBW{ zAuvLko10;NKr^uXz|4T{0l|Rb0ja31t;O2o$dMx`io*PWW?%(!@ZdpMAXt82Z18xz zef#!7Ir8)KF*&dTNl#CQ`7sAZN=gdMkDWVr!UBO>#KpxyEntDf#>Qf1#KgqF2*C;@ zEG#TEG!)7KBLo%*WCLme!vlhWwFed+KUW7dgUMuK;Q`Hn;bCQE1(O5o4HFX+BO@ay zhk=2Co}L~I4@?di9%^c8Dk>_<%F2rtEmBZW_y_*Y|LqkJjHzDQP&K|(FSa0B22gWK z6jDGF(O4*@!0@i4qEvdDtVUR10lAvpnnPOb$tTB$N-fk6ZXov6hjsDwJ$jM)`Psed zj(HNF>JvF`T=}JZev4^`m#UsCGC@|9lp+w!(&AWQ&ThYv&2`PRLxGU3Bp-QtYAC!@ zRz(U>fxRURAFgy!h9f7BK(GeHUAWBF8qxJUKZIp;cGgCLw>(RKn4{F?)e76^FsmwYK6$m7k0KV>0OFa yU?Bwn0Rn*UOhb|1k`4(lD9Th#FCp?&^|gs0uqVw<%`WMr?G!+p_fEqmvH1hBVkJia literal 0 HcmV?d00001 diff --git a/assets/tw/template/TEMPLATE_SIREN_HarukaAmami.gif b/assets/tw/template/TEMPLATE_SIREN_HarukaAmami.gif new file mode 100644 index 0000000000000000000000000000000000000000..f6c534c0d973741e072fcbbc109c0398646899d1 GIT binary patch literal 3260 zcmeI!`8U-2AHebVFwAhtsAMo#GecvSeF({S0H8owkcJ1obtBs9~mo8npc=6(e3m59^>(8A#clPYry1Kg4r%#_cb?W5FlgE!A zKX&Zc(W6JJtE&$mK3rK@dFarg^78Vsva-_B(gOz$?BBni&*ztvloS^i7Zw)g<>hg? zTn>kmm6gS2vokU>5Clm}OWU(&&+gs3larH^l9G1q+O=cHj>N>ogoK3c+qZAsx^>Hz zEt@xQj*gCwii(PijEsng2oDcuu~;D?A)7XB+PHCJP*BkN_3PKITNfA@xMt0ofPesh ze}7+JUmqWzRjXEcdwY9&dU|+xxVyW%xw*Nzy1KZyI6FJr+uN^LvBJ*I&eqm;*|KHU z*4CDmmKGKk=H}*RW@e_QrpCs``uh4hIyzcfS{fP}bUK|%rK+o|D=8^~f9HR+0ov>@ z-cAAjj!YjX6GJ0O-0Uo%P2q_&c)b3PD}HN3D!Qs6yGL89_Ou=RyLBW)TzsSPpGGUCZ@3q!yY~fufKyOn0S4qjh73LRA~{#Ykj$0<#gaZCw7X(4y)N9XcMyjI zK-wq-c|j^w4=A@~04fzO11ABj9Epk*OU>tjvQ_D6i(Rq@qG`qeNk;%)R*v}B)p39J z1>%Cqg0X^`^6uTc@$qrU%Bxqepe&=KqZlrjESM=zo;-Q{`0<=97%O+~-0AP{$5?@; zKv256x;i^Mp(zj)OcO{6=E#*RS1w<^3^jq2G&D4vKYt$6dwX0XJ_Ve?bbHvNb3sQn1;^gGCa^*?~ z2M6fL^5x4hM{I0tFhmRu4WS*ny1EPoW66>wnwpwW5E_jJ1))$VWHK4P=D+g~Yyi@c zJ0gA`f-lx}Xa=A+H1AiPwbEj;*fC#KJ6ev4FpqIK7HmIc!e@v>(ooZmr5a0QR~j(% zg9d$QlF}3p1SRz`d#W5cPrF%R42Ap!0qt4U!=v&P+muc;K2(U$Q82qEC>nN_TcE}a z@*FE_kziA3#r%}8aF=`~`FTf)C@PS~nT%w`2t} z0W>+DpdQ=G6tQKM@p6kmS+F1@LnA3G=bT9vKyW}vpb!D@KutW$2gv|!n*QwdamKf# z4UbGuiV67t0tOZ&Q&Us0N&YrS-n@AO@t89M1_@Rp7#o-w4<9~+K?2QyTKsK?{LBW{ zAuvLko10;NKr^uXz|4T{0l|Rb0ja31t;O2o$dMx`io*PWW?%(!@ZdpMAXt82Z18xz zef#!7Ir8)KF*&dTNl#CQ`7sAZN=gdMkDWVr!UBO>#KpxyEntDf#>Qf1#KgqF2*C;@ zEG#TEG!)7KBLo%*WCLme!vlhWwFed+KUW7dgUMuK;Q`Hn;bCQE1(O5o4HFX+BO@ay zhk=2Co}L~I4@?di9%^c8Dk>_<%F2rtEmBZW_y_*Y|LqkJjHzDQP&K|(FSa0B22gWK z6jDGF(O4*@!0@i4qEvdDtVUR10lAvpnnPOb$tTB$N-fk6ZXov6hjsDwJ$jM)`Psed zj(HNF>JvF`T=}JZev4^`m#UsCGC@|9lp+w!(&AWQ&ThYv&2`PRLxGU3Bp-QtYAC!@ zRz(U>fxRURAFgy!h9f7BK(GeHUAWBF8qxJUKZIp;cGgCLw>(RKn4{F?)e76^FsmwYK6$m7k0KV>0OFa yU?Bwn0Rn*UOhb|1k`4(lD9Th#FCp?&^|gs0uqVw<%`WMr?G!+p_fEqmvH1hBVkJia literal 0 HcmV?d00001 diff --git a/campaign/event_20210722_cn/campaign_base.py b/campaign/event_20210722_cn/campaign_base.py new file mode 100644 index 000000000..bb694c87e --- /dev/null +++ b/campaign/event_20210722_cn/campaign_base.py @@ -0,0 +1,89 @@ +from module.base.button import Button +from module.campaign.campaign_base import CampaignBase as CampaignBase_ +from module.exception import CampaignNameError +from module.logger import logger + +ANIMATION_PINK = Button( + area=(1186, 446, 1272, 493), color=(255, 153, 172), button=(1186, 446, 1272, 493), name='ANIMATION_PINK') +ANIMATION_ORANGE = Button( + area=(1186, 446, 1272, 493), color=(255, 177, 123), button=(1186, 446, 1272, 493), name='ANIMATION_ORANGE') +ANIMATION_BLUE = Button( + area=(1186, 446, 1272, 493), color=(176, 192, 251), button=(1186, 446, 1272, 493), name='ANIMATION_BLUE') + + +class CampaignBase(CampaignBase_): + """ + In event Azur Anthem (event_20210722_cn), The Idol Master Collaboration, maps are: + Chapter 1: SP1, SP2, SP3, SP4. + Chapter 2: VSP. + """ + + @staticmethod + def _campaign_get_chapter_index(name): + """ + Args: + name (str, int): + + Returns: + int + """ + if isinstance(name, int): + return name + else: + if name.isdigit(): + return int(name) + elif name in ['a', 'c', 'as', 'cs', 'sp']: + return 1 + elif name in ['b', 'd', 'bs', 'ds', 'ex_ex', 'ex_sp']: # Difference + return 2 + else: + raise CampaignNameError + + def campaign_set_chapter(self, name, mode='normal'): + """ + Args: + name (str): Campaign name, such as '7-2', 'd3', 'sp3'. + mode (str): 'normal' or 'hard'. + """ + chapter, _ = self._campaign_separate_name(name) + + if chapter.isdigit(): + self.ui_weigh_anchor() + self.campaign_ensure_mode('normal') + self.campaign_ensure_chapter(index=chapter) + if mode == 'hard': + self.campaign_ensure_mode('hard') + self.campaign_ensure_chapter(index=chapter) + + elif chapter in ['a', 'b', 'c', 'd', 'ex_sp', 'as', 'bs', 'cs', 'ds']: + self.ui_goto_event() + if chapter in ['a', 'b', 'as', 'bs']: + self.campaign_ensure_mode('normal') + elif chapter in ['c', 'd', 'cs', 'ds']: + self.campaign_ensure_mode('hard') + elif chapter == 'ex_sp': + # self.campaign_ensure_mode('ex') + pass # Difference + self.campaign_ensure_chapter(index=chapter) + + elif chapter == 'sp': + # self.ui_goto_sp() + self.ui_goto_event() # Difference + self.campaign_ensure_chapter(index=chapter) + + else: + logger.warning(f'Unknown campaign chapter: {name}') + + def is_event_animation(self): + """ + Animation in events after cleared an enemy. + + Returns: + bool: If animation appearing. + """ + for button in [ANIMATION_PINK, ANIMATION_ORANGE, ANIMATION_BLUE]: + if self.appear(button): + logger.info('Idol Master animation, waiting') + return True + + return False diff --git a/campaign/event_20210722_cn/sp.py b/campaign/event_20210722_cn/sp.py new file mode 100644 index 000000000..04668f7b2 --- /dev/null +++ b/campaign/event_20210722_cn/sp.py @@ -0,0 +1,71 @@ +from .campaign_base import CampaignBase +from module.map.map_base import CampaignMap +from module.map.map_grids import SelectedGrids, RoadGrids +from module.logger import logger + +MAP = CampaignMap('VSP') +MAP.shape = 'G8' +MAP.camera_data = ['D2', 'D6'] +MAP.camera_data_spawn_point = ['D6'] +MAP.map_data = """ + ++ ++ ++ MB ++ ++ ++ + ME -- -- -- -- -- ME + ++ ++ -- -- -- ++ ++ + ++ ME -- ++ -- ME ++ + ++ ++ -- ++ -- ++ ++ + ++ ++ -- __ -- ++ ++ + ME -- -- -- -- -- ME + ++ ++ SP -- SP ++ ++ +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 +""" +MAP.spawn_data = [ + {'battle': 0}, + {'battle': 1, 'enemy': 1}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, 'enemy': 2}, + {'battle': 4}, + {'battle': 5}, + {'battle': 6}, + {'battle': 7, 'boss': 1}, +] +A1, B1, C1, D1, E1, F1, G1, \ +A2, B2, C2, D2, E2, F2, G2, \ +A3, B3, C3, D3, E3, F3, G3, \ +A4, B4, C4, D4, E4, F4, G4, \ +A5, B5, C5, D5, E5, F5, G5, \ +A6, B6, C6, D6, E6, F6, G6, \ +A7, B7, C7, D7, E7, F7, G7, \ +A8, B8, C8, D8, E8, F8, G8, \ + = MAP.flatten() + + +class Config: + # ===== Start of generated config ===== + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = False + MAP_HAS_AMBUSH = False + STAR_REQUIRE_1 = 0 + STAR_REQUIRE_2 = 0 + STAR_REQUIRE_3 = 0 + # ===== End of generated config ===== + + + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + return self.battle_default() + + def battle_7(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/event_20210722_cn/sp1.py b/campaign/event_20210722_cn/sp1.py new file mode 100644 index 000000000..f50018fc1 --- /dev/null +++ b/campaign/event_20210722_cn/sp1.py @@ -0,0 +1,62 @@ +from .campaign_base import CampaignBase +from module.map.map_base import CampaignMap +from module.map.map_grids import SelectedGrids, RoadGrids +from module.logger import logger + +MAP = CampaignMap('SP1') +MAP.shape = 'H7' +MAP.camera_data = ['D2', 'D5', 'E2', 'E5'] +MAP.camera_data_spawn_point = ['E5'] +MAP.map_data = """ + -- ME -- ME ++ ME -- -- + -- ++ MB -- ME -- Me -- + ME ++ -- -- -- ++ ++ MS + -- ME -- ME -- Me ++ -- + -- Me ++ -- __ -- ME -- + -- -- -- ME MS -- -- SP + ME -- Me ++ -- -- SP ++ +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 3}, + {'battle': 1, 'enemy': 2}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, 'enemy': 1}, + {'battle': 4, 'boss': 1}, +] +A1, B1, C1, D1, E1, F1, G1, H1, \ +A2, B2, C2, D2, E2, F2, G2, H2, \ +A3, B3, C3, D3, E3, F3, G3, H3, \ +A4, B4, C4, D4, E4, F4, G4, H4, \ +A5, B5, C5, D5, E5, F5, G5, H5, \ +A6, B6, C6, D6, E6, F6, G6, H6, \ +A7, B7, C7, D7, E7, F7, G7, H7, \ + = MAP.flatten() + + +class Config: + # ===== Start of generated config ===== + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = True + MAP_HAS_AMBUSH = False + # ===== End of generated config ===== + + HOMO_EDGE_COLOR_RANGE = (0, 12) + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/event_20210722_cn/sp2.py b/campaign/event_20210722_cn/sp2.py new file mode 100644 index 000000000..294bfc8d7 --- /dev/null +++ b/campaign/event_20210722_cn/sp2.py @@ -0,0 +1,75 @@ +from .campaign_base import CampaignBase +from module.map.map_base import CampaignMap +from module.map.map_grids import SelectedGrids, RoadGrids +from module.logger import logger +from .sp1 import Config as ConfigBase + +MAP = CampaignMap('SP2') +MAP.shape = 'H8' +MAP.camera_data = ['D2', 'D6', 'E2', 'E6'] +MAP.camera_data_spawn_point = ['D2'] +MAP.map_data = """ + ++ ME -- -- ME ++ ++ ++ + ++ -- MS ME -- ME -- -- + SP -- -- -- Me -- ++ ME + SP -- Me -- __ -- -- -- + -- -- -- -- ++ Me -- MB + ++ -- ME MS ++ -- ME -- + -- Me ++ -- -- -- ++ ++ + ME -- ME -- ME ME ++ ++ +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 3, 'siren': 1}, + {'battle': 1, 'enemy': 2}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, 'enemy': 1}, + {'battle': 4, 'boss': 1}, +] +A1, B1, C1, D1, E1, F1, G1, H1, \ +A2, B2, C2, D2, E2, F2, G2, H2, \ +A3, B3, C3, D3, E3, F3, G3, H3, \ +A4, B4, C4, D4, E4, F4, G4, H4, \ +A5, B5, C5, D5, E5, F5, G5, H5, \ +A6, B6, C6, D6, E6, F6, G6, H6, \ +A7, B7, C7, D7, E7, F7, G7, H7, \ +A8, B8, C8, D8, E8, F8, G8, H8, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['HarukaAmami'] + MOVABLE_ENEMY_TURN = (2,) + MAP_HAS_SIREN = True + MAP_HAS_MOVABLE_ENEMY = True + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = True + MAP_HAS_AMBUSH = False + # ===== End of generated config ===== + + MAP_SWIPE_MULTIPLY = 1.804 + MAP_SWIPE_MULTIPLY_MINITOUCH = 1.744 + MAP_ENSURE_EDGE_INSIGHT_CORNER = 'bottom' + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_4(self): + return self.clear_boss() diff --git a/campaign/event_20210722_cn/sp3.py b/campaign/event_20210722_cn/sp3.py new file mode 100644 index 000000000..87af31ad2 --- /dev/null +++ b/campaign/event_20210722_cn/sp3.py @@ -0,0 +1,72 @@ +from .campaign_base import CampaignBase +from module.map.map_base import CampaignMap +from module.map.map_grids import SelectedGrids, RoadGrids +from module.logger import logger +from .sp1 import Config as ConfigBase + +MAP = CampaignMap('SP3') +MAP.shape = 'H8' +MAP.camera_data = ['D2', 'D6', 'E2', 'E6'] +MAP.camera_data_spawn_point = ['E2'] +MAP.map_data = """ + -- Me ME ++ ME -- ++ ++ + ++ -- -- -- -- SP SP ++ + ++ -- MS ME -- -- -- -- + ME -- -- Me __ ++ -- MS + -- ME ++ -- MS -- Me -- + ME -- ME -- ME -- ++ ME + -- MB -- -- -- Me ++ -- + ME ++ ++ ++ ME -- ME -- +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 3, 'siren': 2}, + {'battle': 1, 'enemy': 2}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, 'enemy': 1}, + {'battle': 4}, + {'battle': 5, 'boss': 1}, +] +A1, B1, C1, D1, E1, F1, G1, H1, \ +A2, B2, C2, D2, E2, F2, G2, H2, \ +A3, B3, C3, D3, E3, F3, G3, H3, \ +A4, B4, C4, D4, E4, F4, G4, H4, \ +A5, B5, C5, D5, E5, F5, G5, H5, \ +A6, B6, C6, D6, E6, F6, G6, H6, \ +A7, B7, C7, D7, E7, F7, G7, H7, \ +A8, B8, C8, D8, E8, F8, G8, H8, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['AzusaMiura', 'IoriMinase'] + MOVABLE_ENEMY_TURN = (2,) + MAP_HAS_SIREN = True + MAP_HAS_MOVABLE_ENEMY = True + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = True + MAP_HAS_AMBUSH = False + # ===== End of generated config ===== + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/campaign/event_20210722_cn/sp4.py b/campaign/event_20210722_cn/sp4.py new file mode 100644 index 000000000..1bd93081f --- /dev/null +++ b/campaign/event_20210722_cn/sp4.py @@ -0,0 +1,72 @@ +from .campaign_base import CampaignBase +from module.map.map_base import CampaignMap +from module.map.map_grids import SelectedGrids, RoadGrids +from module.logger import logger +from .sp1 import Config as ConfigBase + +MAP = CampaignMap('SP4') +MAP.shape = 'I8' +MAP.camera_data = ['D2', 'D6', 'F2', 'F6'] +MAP.camera_data_spawn_point = ['F6', 'D6'] +MAP.map_data = """ + ++ ++ ++ ME -- ME ++ ++ ++ + ME -- ++ -- MB -- ++ -- ME + ++ ME Me -- Me -- Me ME ++ + ME -- ME MS ++ MS ME -- ME + ++ ++ -- -- ++ -- -- ++ ++ + ++ ++ -- MS __ MS -- ++ ++ + ME -- Me -- ME -- Me -- ME + -- ME ++ SP -- SP ++ ME -- +""" +MAP.weight_data = """ + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 + 50 50 50 50 50 50 50 50 50 +""" +MAP.spawn_data = [ + {'battle': 0, 'enemy': 3, 'siren': 2}, + {'battle': 1, 'enemy': 2, 'siren': 1}, + {'battle': 2, 'enemy': 1}, + {'battle': 3, 'enemy': 1}, + {'battle': 4}, + {'battle': 5, 'boss': 1}, +] +A1, B1, C1, D1, E1, F1, G1, H1, I1, \ +A2, B2, C2, D2, E2, F2, G2, H2, I2, \ +A3, B3, C3, D3, E3, F3, G3, H3, I3, \ +A4, B4, C4, D4, E4, F4, G4, H4, I4, \ +A5, B5, C5, D5, E5, F5, G5, H5, I5, \ +A6, B6, C6, D6, E6, F6, G6, H6, I6, \ +A7, B7, C7, D7, E7, F7, G7, H7, I7, \ +A8, B8, C8, D8, E8, F8, G8, H8, I8, \ + = MAP.flatten() + + +class Config(ConfigBase): + # ===== Start of generated config ===== + MAP_SIREN_TEMPLATE = ['AzusaMiura', 'ChihayaKisaragi', 'IoriMinase'] + MOVABLE_ENEMY_TURN = (2,) + MAP_HAS_SIREN = True + MAP_HAS_MOVABLE_ENEMY = True + MAP_HAS_MAP_STORY = False + MAP_HAS_FLEET_STEP = True + MAP_HAS_AMBUSH = False + # ===== End of generated config ===== + + +class Campaign(CampaignBase): + MAP = MAP + + def battle_0(self): + if self.clear_siren(): + return True + + return self.battle_default() + + def battle_5(self): + return self.fleet_boss.clear_boss() diff --git a/module/campaign/run.py b/module/campaign/run.py index c8e729e53..72770ad13 100644 --- a/module/campaign/run.py +++ b/module/campaign/run.py @@ -166,6 +166,8 @@ class CampaignRun(Reward): """ if folder == 'event_20201126_cn' and name == 'vsp': name = 'sp' + if folder == 'event_20210723_cn' and name == 'vsp': + name = 'sp' return name, folder diff --git a/module/config/config.py b/module/config/config.py index 3b680fbf5..8d6331050 100644 --- a/module/config/config.py +++ b/module/config/config.py @@ -266,6 +266,10 @@ class AzurLaneConfig: # because a closing swipe will be treat as a click in game. MAP_SWIPE_DROP = 0.15 MAP_SWIPE_PREDICT = True + # Corner to ensure in ensure_edge_insight. + # Value can be 'upper-left', 'upper-right', 'bottom-left', 'bottom-right', or 'upper', 'bottom', 'left', 'right' + # Missing axis will be random, and '' for all random + MAP_ENSURE_EDGE_INSIGHT_CORNER = '' """ module.retire diff --git a/module/map/camera.py b/module/map/camera.py index 6d3865743..daace7448 100644 --- a/module/map/camera.py +++ b/module/map/camera.py @@ -6,7 +6,8 @@ from module.combat.assets import GET_ITEMS_1 from module.exception import MapDetectionError, CampaignEnd from module.handler.assets import IN_MAP, GAME_TIPS from module.logger import logger -from module.map.map_base import CampaignMap, location2node, location_ensure +from module.map.map_base import CampaignMap, location2node +from module.map.utils import location_ensure, random_direction from module.map.map_operation import MapOperation from module.map_detection.grid import Grid from module.map_detection.view import View @@ -183,8 +184,7 @@ class Camera(MapOperation): logger.info(f'Ensure edge in sight.') record = [] self._correct_camera = True - x_swipe = -swipe_limit[0] if np.random.uniform() > 0.5 else swipe_limit[0] - y_swipe = -swipe_limit[1] if np.random.uniform() > 0.5 else swipe_limit[1] + x_swipe, y_swipe = np.multiply(swipe_limit, random_direction(self.config.MAP_ENSURE_EDGE_INSIGHT_CORNER)) while 1: if len(record) == 0: diff --git a/module/map/utils.py b/module/map/utils.py index 4bc1f376d..b7353b0f5 100644 --- a/module/map/utils.py +++ b/module/map/utils.py @@ -85,6 +85,31 @@ def camera_spawn_point(camera_list, sp_list): return list(set(camera_sp)) +def random_direction(direction): + """ + Choose a random direction from string. Missing axis will be random, and '' for all random. + + Args: + direction (str): 'upper-left', 'upper-right', 'bottom-left', + 'bottom-right', or 'upper', 'bottom', 'left', 'right', etc. + + Returns: + tuple(int): Such as (-1, 1) for bottom-left + """ + direction = direction.lower() + x = 1 if np.random.uniform() > 0.5 else -1 + y = 1 if np.random.uniform() > 0.5 else -1 + if 'left' in direction: + x = -1 + elif 'right' in direction: + x = 1 + if 'upper' in direction: + y = -1 + elif 'bottom' in direction: + y = 1 + return (x, y) + + def combine(before, after, limit): after += [limit] for b in before: diff --git a/module/template/assets.py b/module/template/assets.py index 44228809d..cb6514358 100644 --- a/module/template/assets.py +++ b/module/template/assets.py @@ -70,6 +70,7 @@ TEMPLATE_SIREN_Formidable = Template(file={'cn': './assets/cn/template/TEMPLATE_ TEMPLATE_SIREN_Gloucester = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Gloucester.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Gloucester.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Gloucester.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Gloucester.gif'}) TEMPLATE_SIREN_Gneisenau = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Gneisenau.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Gneisenau.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Gneisenau.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Gneisenau.gif'}) TEMPLATE_SIREN_Hammann = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Hammann.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Hammann.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Hammann.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Hammann.gif'}) +TEMPLATE_SIREN_HarukaAmami = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_HarukaAmami.gif', 'en': './assets/en/template/TEMPLATE_SIREN_HarukaAmami.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_HarukaAmami.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_HarukaAmami.gif'}) TEMPLATE_SIREN_Hibiki = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Hibiki.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Hibiki.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Hibiki.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Hibiki.gif'}) TEMPLATE_SIREN_HipperIdol = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_HipperIdol.gif', 'en': './assets/en/template/TEMPLATE_SIREN_HipperIdol.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_HipperIdol.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_HipperIdol.gif'}) TEMPLATE_SIREN_Illustrious = Template(file={'cn': './assets/cn/template/TEMPLATE_SIREN_Illustrious.gif', 'en': './assets/en/template/TEMPLATE_SIREN_Illustrious.gif', 'jp': './assets/jp/template/TEMPLATE_SIREN_Illustrious.gif', 'tw': './assets/tw/template/TEMPLATE_SIREN_Illustrious.gif'})