From 13cdb9c3ac4a6133f8bc9c32bf20dcc22f38e553 Mon Sep 17 00:00:00 2001 From: Kevin Quito Date: Tue, 5 Oct 2021 00:30:27 -0700 Subject: [PATCH] v4.3.3 --- msl-bot/bin/_src/globals/Const.au3 | 21 +- msl-bot/bin/_src/globals/Default.au3 | 4 + msl-bot/bin/_src/globals/Handles.au3 | 4 - msl-bot/bin/_src/globals/Numbers.au3 | 4 +- msl-bot/bin/_src/gui/Config.au3 | 11 +- msl-bot/bin/_src/gui/Design.au3 | 129 +++++ msl-bot/bin/_src/gui/Handler.au3 | 511 +++++++++++++----- msl-bot/bin/_src/gui/Menu.au3 | 30 +- msl-bot/bin/_src/gui/Script.au3 | 48 +- msl-bot/bin/_src/handlers/ADB.au3 | 19 +- msl-bot/bin/_src/handlers/Capture.au3 | 5 +- msl-bot/bin/_src/handlers/Control.au3 | 57 +- msl-bot/bin/_src/handlers/Emulator.au3 | 51 +- msl-bot/bin/_src/handlers/Location.au3 | 24 +- msl-bot/bin/_src/handlers/OtherFunctions.au3 | 68 ++- msl-bot/bin/_src/handlers/Pixel.au3 | 101 +++- msl-bot/bin/_src/handlers/Script.au3 | 62 +-- msl-bot/bin/_src/handlers/System.au3 | 40 +- msl-bot/bin/_src/imports.au3 | 1 + msl-bot/bin/_src/scripts/Farm_Golem.au3 | 8 +- msl-bot/bin/_src/scripts/Farm_Guardian.au3 | 5 +- msl-bot/bin/_src/scripts/sub/catch.au3 | 24 +- msl-bot/bin/_src/scripts/sub/doExpedition.au3 | 103 ++++ msl-bot/bin/_src/scripts/sub/doHourly.au3 | 33 +- msl-bot/bin/_src/scripts/sub/enterBattle.au3 | 16 + msl-bot/bin/_src/scripts/sub/enterStage.au3 | 5 - msl-bot/bin/_src/scripts/sub/handlers.au3 | 10 +- msl-bot/bin/_src/scripts/sub/helper.au3 | 402 +++++++++++--- msl-bot/bin/_src/scripts/sub/navigate.au3 | 75 ++- .../images/expedition/expedition-complete.bmp | Bin 0 -> 7734 bytes .../expedition/expedition-complete2.bmp | Bin 0 -> 8022 bytes .../expedition/expedition-complete3.bmp | Bin 0 -> 8374 bytes .../expedition/expedition-complete4.bmp | Bin 0 -> 9126 bytes .../bin/images/expedition/expedition-end.bmp | Bin 0 -> 2706 bytes .../bin/images/expedition/expedition-end2.bmp | Bin 0 -> 2486 bytes .../bin/images/expedition/expedition-end3.bmp | Bin 0 -> 2014 bytes .../images/expedition/expedition-explore.bmp | Bin 0 -> 4614 bytes .../images/expedition/expedition-explore2.bmp | Bin 0 -> 5246 bytes .../images/expedition/expedition-explore3.bmp | Bin 0 -> 5622 bytes .../images/expedition/expedition-explored.bmp | Bin 0 -> 3794 bytes .../expedition/expedition-explored2.bmp | Bin 0 -> 3474 bytes .../expedition/expedition-explored3.bmp | Bin 0 -> 3702 bytes .../expedition/expedition-explored4.bmp | Bin 0 -> 3654 bytes .../expedition/expedition-exploring.bmp | Bin 0 -> 8902 bytes .../expedition/expedition-exploring2.bmp | Bin 0 -> 8478 bytes .../expedition/expedition-exploring3.bmp | Bin 0 -> 9414 bytes .../expedition/expedition-exploring4.bmp | Bin 0 -> 9450 bytes .../images/expedition/expedition-unknown.bmp | Bin 0 -> 2838 bytes .../images/expedition/expedition-unknown2.bmp | Bin 0 -> 738 bytes .../images/expedition/expedition-unknown3.bmp | Bin 0 -> 390 bytes .../images/expedition/expedition-unknown4.bmp | Bin 0 -> 882 bytes msl-bot/bin/images/gem/gem-defense2.bmp | Bin 0 -> 3726 bytes msl-bot/bin/images/gem/gem-hp2.bmp | Bin 0 -> 1286 bytes .../images/level/level-guardian-dungeons.bmp | Bin 2634 -> 4526 bytes msl-bot/bin/images/misc/misc-google-open2.bmp | Bin 0 -> 3274 bytes .../bin/images/misc/misc-guardian-left.bmp | Bin 954 -> 954 bytes .../bin/images/misc/misc-guardian-right.bmp | Bin 954 -> 954 bytes msl-bot/bin/local/custom.txt | 41 +- msl-bot/bin/local/data/locations.txt | 13 +- msl-bot/bin/local/data/pixels.txt | 17 +- msl-bot/bin/local/data/points.txt | 4 +- msl-bot/bin/local/gem_filter.txt | 76 +++ msl-bot/bin/local/original/locations-map.txt | 26 +- msl-bot/bin/local/original/locations.txt | 22 +- msl-bot/bin/local/original/pixels.txt | 8 +- msl-bot/bin/local/original/points.txt | 2 - msl-bot/msl-bot.au3 | 8 +- .../profiles/gem_filters/premade_5star_4sub | 8 + .../profiles/gem_filters/premade_6star_2sub | 6 + .../profiles/gem_filters/premade_6star_dragon | 7 + .../profiles/gem_filters/premade_6star_healer | 6 + .../profiles/gem_filters/premade_6star_pvp | 6 + .../gem_filters/premade_6star_standard | 6 + 73 files changed, 1692 insertions(+), 435 deletions(-) create mode 100644 msl-bot/bin/_src/scripts/sub/doExpedition.au3 create mode 100644 msl-bot/bin/images/expedition/expedition-complete.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-complete2.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-complete3.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-complete4.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-end.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-end2.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-end3.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-explore.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-explore2.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-explore3.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-explored.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-explored2.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-explored3.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-explored4.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-exploring.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-exploring2.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-exploring3.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-exploring4.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-unknown.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-unknown2.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-unknown3.bmp create mode 100644 msl-bot/bin/images/expedition/expedition-unknown4.bmp create mode 100644 msl-bot/bin/images/gem/gem-defense2.bmp create mode 100644 msl-bot/bin/images/gem/gem-hp2.bmp create mode 100644 msl-bot/bin/images/misc/misc-google-open2.bmp create mode 100644 msl-bot/bin/local/gem_filter.txt create mode 100644 msl-bot/profiles/gem_filters/premade_5star_4sub create mode 100644 msl-bot/profiles/gem_filters/premade_6star_2sub create mode 100644 msl-bot/profiles/gem_filters/premade_6star_dragon create mode 100644 msl-bot/profiles/gem_filters/premade_6star_healer create mode 100644 msl-bot/profiles/gem_filters/premade_6star_pvp create mode 100644 msl-bot/profiles/gem_filters/premade_6star_standard diff --git a/msl-bot/bin/_src/globals/Const.au3 b/msl-bot/bin/_src/globals/Const.au3 index fb4ab505..d6236dc6 100644 --- a/msl-bot/bin/_src/globals/Const.au3 +++ b/msl-bot/bin/_src/globals/Const.au3 @@ -37,6 +37,7 @@ Global Const $g_sLocalOriginalFolder = $g_sLocalFolder & "original\" Global Const $g_sLocalDataFolder = $g_sLocalFolder & "data\" Global Const $g_sProfileFolder = @ScriptDir & "\profiles\" Global Const $g_sRemoteUrl = "https://raw.githubusercontent.com/GkevinOD/msl-bot/version-check/data/" +Global Const $g_sFilterFolder = $g_sProfileFolder & "gem_filters\" Global Const $g_sScriptListFile = @ScriptDir & "\bin\local\scriptlist.txt" @@ -54,6 +55,12 @@ Global Const $g_sAirshipTrees = "airship-trees.txt" Global Const $g_sScripts = "free_scripts_4.2.0.txt" Global Const $g_sPackageName = "com.ftt.msleague_gl" +Global Const $g_sPackageActivity = "kr.co.smartstudy.tamagorpg.TamagoMainActivity" + +Global Const $g_aGem_Grade = ["6", "5", "4", "3", "2", "1", "any"] +Global Const $g_aGem_Shape = ["square", "triangle", "diamond", "any"] +Global Const $g_aGem_Type = ["leech", "siphon", "pugilist", "ruin", "intuition", "conviction", "protection", "valor", "vitality", "tenacity", "fortitude", "healing", "ferocity", "life", "any"] +Global Const $g_aGem_Stat = ["hp", "attack", "defense", "recovery", "critrate", "critdmg", "resist", "any"] Global Const $g_aGemRanks = ["LEECH,SIPHON,PUGILIST", "RUIN", "INTUITION", "CONVICTION,PROTECTION,VALOR,VITALITY,TENACITY,FORTITUDE,HEALING,FEROCITY", "LIFE"] Global Const $g_aGemGrade6Price = [[39600,37799,36000,34199], [24750,23624,22500,21374], [19800,18899,18000,17099]] @@ -73,8 +80,8 @@ Global Const $g_aGem_pixelTypes = [ _ "PUGILIST:414,219,0xDDA456|415,223,0xE9AE5A|419,223,0xDCA456|431,229,0xA17341|434,229,0xDFA657|438,219,0xD29C52", _ "SIPHON:418,219,0xDDA356|420,225,0xD69D54|422,224,0xD69D54|430,224,0xDCA356|446,224,0xE2A858", _ "RUIN:323,224,0xE8AE5A|411,223,0xEAAF5B|435,225,0xDCA456/363,223,0xE8AE5A|403,223,0xEFB45C|411,223,0xEAAF5B", _ - "FEROCITY:352,223,0xE4AA58|400,223,0xEBB05B|446,224,0xE5AB59", _ "FORTITUDE:348,223,0xE8AE5A|396,223,0xEBB05B|446,224,0xF0B45D", _ + "FEROCITY:352,223,0xE4AA58|400,223,0xEBB05B|446,224,0xE5AB59", _ "HEALING:354,224,0xE0A757|402,223,0xF0B45C|444,225,0xDFA657", _ "VALOR:360,224,0xE8AE5A|391,224,0xECB15B|436,225,0xECB15B", _ "INTUITION:351,223,0xDDA556|390,222,0xF4B75E|399,223,0xDAA255", _ @@ -108,6 +115,18 @@ Global Const $g_aVillagePos = [ _ "150,430,0x7F4863|34,334,0xD298D5|635,182,0xDB82C9/790,350,0x00FFFF|4,381,0xC1C1AF|331,163,0x02FFFF/661,62,0x44575E|573,398,0x565D46|357,360,0x444D3F", _ "221,87,0x44687A|41,395,0x00FFFF|476,163,0x01FFFF/221,87,0x424B44|41,395,0x00FFFF|476,163,0x00FFFF/104,451,0x44332E|784,401,0xC0C0AF|507,75,0x0885C7/104,451,0x44332E|784,401,0xC4C4B2|507,75,0x1079A7/272,374,0x444B44|755,457,0x4A4A39|8,194,0x2F3D46/272,374,0x444B44|755,457,0x0F0D0A|8,194,0x2D2D29"] +; 0,1,2: Normal | 3,4: Windsinger | 5,6: Albatross | 7,8: Hanamura +Global Const $g_aExpeditionPos = [ _ ; Use getVillagePos() function + "231,246", _ ; Index = 0 + "-1", _ ; Index = 1 + "327,185", _ ; Index = 2 + "-1", _ ; Needed. Index = 3 + "-1", _ ; Needed. Index = 4 + "-1", _ ; Needed. Index = 5 + "-1", _ ; Needed. Index = 6 + "299,254", _ ; Index = 7 + "463,315"] ; Index = 8 + Global Const $g_aVillageTrees = [ _ "296,115|486,67|683,107|685,289", _ "182,390|194,122|577,81|627,186", _ diff --git a/msl-bot/bin/_src/globals/Default.au3 b/msl-bot/bin/_src/globals/Default.au3 index 05d528fb..ddb692f2 100644 --- a/msl-bot/bin/_src/globals/Default.au3 +++ b/msl-bot/bin/_src/globals/Default.au3 @@ -4,6 +4,7 @@ Global $Default_Config_Profile_Name = "Default" Global $Default_Config_Scheduled_Restart = "Game:3H" Global $Default_Config_Location_Stuck_Timeout = "10 Minutes" Global $Default_Config_Screen_Frozen_Check = "60 Seconds" +Global $Default_Config_ADB_Game_Check = "30 Seconds" Global $Default_Config_Another_Device_Timeout = "Immediately" Global $Default_Config_Maintenance_Timeout = "5 Minutes" Global $Default_Config_Save_Logs = "Enabled" @@ -23,6 +24,7 @@ Global $Default_Config_Back_Mode = "ADB" Global $Default_ADB_Device = "~AUTO" Global $Default_ADB_PC_Shared = "~AUTO" Global $Default_ADB_Android_Shared = "~AUTO" +Global $Default_ADB_Restart_Game = "Enabled" Global $Default_Delay_Script_Loop = "200" Global $Default_Delay_Swipe_Delay = "700" @@ -38,7 +40,9 @@ Global $Default_General_Max_Exotic_Chips = "20" Global $Default_Hourly_Hourly_Script = "Enabled" Global $Default_Hourly_Collect_Hiddens = "Enabled" +Global $Default_Hourly_Collect_Inbox = "Enabled" Global $Default_Hourly_Click_Nezz = "Disabled" +Global $Default_Hourly_Expedition = "Enabled" Global $Default_Guardian_Guardian_Script = "Enabled" Global $Default_Guardian_Guardian_Mode = "Both" diff --git a/msl-bot/bin/_src/globals/Handles.au3 b/msl-bot/bin/_src/globals/Handles.au3 index d8149c70..9dcbdb37 100644 --- a/msl-bot/bin/_src/globals/Handles.au3 +++ b/msl-bot/bin/_src/globals/Handles.au3 @@ -31,9 +31,6 @@ Global $g_idScheduleAdd_Cancel = Null Global $g_idScheduleAdd_Preset = Null Global $g_iScheduleType = Null -Global $g_hMessageBox = Null -Global $g_idEditMessage = Null - Global $g_hCurrentEdit = Null ;UI Handles @@ -101,7 +98,6 @@ Global $g_hBtn_CaptureRegion = Null ;Timer Handles Global $g_hTimerLocation = Null ;Global timer for location. Used for antiStuck Global $g_hGetLocationCoolDown = TimerInit() ;Cooldown for getLocation function -Global $g_hTimerScheduledRestart = Null ;Global timer for schedules restart. Global $g_hGameCheckCD = TimerInit() diff --git a/msl-bot/bin/_src/globals/Numbers.au3 b/msl-bot/bin/_src/globals/Numbers.au3 index ff6adc25..6da7bcd6 100644 --- a/msl-bot/bin/_src/globals/Numbers.au3 +++ b/msl-bot/bin/_src/globals/Numbers.au3 @@ -26,4 +26,6 @@ Global $g_aGemsToSell = Null Global $g_iLocationIndex = -1 ;Location map index -Global $g_aStatsCD = TimerInit() ;Cooldown timer handle for updating stats listview \ No newline at end of file +Global $g_aStatsCD = TimerInit() ;Cooldown timer handle for updating stats listview + +Global $g_bCaptureQuest = False \ No newline at end of file diff --git a/msl-bot/bin/_src/gui/Config.au3 b/msl-bot/bin/_src/gui/Config.au3 index 5ec7d1b8..8bd3893c 100644 --- a/msl-bot/bin/_src/gui/Config.au3 +++ b/msl-bot/bin/_src/gui/Config.au3 @@ -98,14 +98,15 @@ EndFunc ;Helper Functions---------------------------------------------------------------------- +Global Const $CONFIG_NEVER = -1, $CONFIG_IMMEDIATELY = 0 Func Config_Parse($sValue) Switch $sValue Case "Enabled", "Disabled" Return $sValue == "Enabled" Case "Never" - Return -1 + Return $CONFIG_NEVER Case "Immediately" - Return 0 + Return $CONFIG_IMMEDIATELY Case Else If StringInStr($sValue, "Hours") Then $sValue = Int(StringMid($sValue, 1, StringLen($sValue) - StringLen(" Hours"))) @@ -121,9 +122,11 @@ EndFunc Func Config_CreateGlobals($aSetting, $sName) For $i = 0 To UBound($aSetting)-1 - If $aSetting[$i][1] == "~DEFAULT" Then ContinueLoop - + If $aSetting[$i][1] == "~DEFAULT" Then + Assign($sName & "_" & $aSetting[$i][0], Config_Parse(Eval("Default_" & $sName & "_" & $aSetting[$i][0])), $ASSIGN_FORCEGLOBAL) + Else If StringLeft($sName, 1) == "_" Then $sName = StringMid($sName, 2) Assign($sName & "_" & $aSetting[$i][0], Config_Parse($aSetting[$i][1]), $ASSIGN_FORCEGLOBAL) + EndIf Next EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/gui/Design.au3 b/msl-bot/bin/_src/gui/Design.au3 index 9685b6c0..755a5b66 100644 --- a/msl-bot/bin/_src/gui/Design.au3 +++ b/msl-bot/bin/_src/gui/Design.au3 @@ -39,6 +39,8 @@ Func CreateGUI() GUICtrlCreateMenuItem("", $Menu_General) Global $M_General_Debug_Input = GUICtrlCreateMenuItem("Debug Input...", $Menu_General) Global $M_General_Compatibility_Test = GUICtrlCreateMenuItem("Compatibility Test...", $Menu_General) + GUICtrlCreateMenuItem("", $Menu_General) + Global $M_General_Toggle_Hidden = GUICtrlCreateMenuItem("Toggle Hidden", $Menu_General) Global $Menu_ADB = GUICtrlCreateMenu("ADB", $Menu_Debug) Global $M_ADB_Run_Command = GUICtrlCreateMenuItem("Run Command...", $Menu_ADB) @@ -52,6 +54,9 @@ Func CreateGUI() Global $M_Location_Set_Location = GUICtrlCreateMenuItem("Set Location...", $Menu_Location) Global $M_Location_Test_Location = GUICtrlCreateMenuItem("Test Location", $Menu_Location) + Global $Menu_Gem = GUICtrlCreateMenu("Gem") + Global $M_Gem_Gem_Window = GUICtrlCreateMenuItem("Gem Window...", $Menu_Gem) + Global $Menu_Pixel = GUICtrlCreateMenu("Pixel", $Menu_Debug) Global $M_Pixel_Check_Pixel = GUICtrlCreateMenuItem("Check Pixel...", $Menu_Pixel) Global $M_Pixel_Set_Pixel = GUICtrlCreateMenuItem("Set Pixel...", $Menu_Pixel) @@ -59,8 +64,13 @@ Func CreateGUI() Global $Menu_Scripts = GUICtrlCreateMenu("Scripts") Global $M_Scripts_Hourly = GUICtrlCreateMenuItem("Hourly", $Menu_Scripts) + Global $M_Scripts_Expedition = GUICtrlCreateMenuItem("Expedition", $Menu_Scripts) Global $M_Scripts_Collect_Quest = GUICtrlCreateMenuItem("Collect Quest", $Menu_Scripts) + Global $M_Scripts_Collect_Inbox = GUICtrlCreateMenuItem("Collect Inbox", $Menu_Scripts) Global $M_Scripts_Guardian_Dungeon = GUICtrlCreateMenuItem("Guardian Dungeon", $Menu_Scripts) + GUICtrlCreateMenuItem("", $Menu_Scripts) + Global $M_Scripts_Titans_Fast = GUICtrlCreateMenuItem("Toggle Titans Fast", $Menu_Scripts) + Global $Menu_Capture = GUICtrlCreateMenu("Capture") Global $M_Capture_Full_Screenshot = GUICtrlCreateMenuItem("Full Screenshot", $Menu_Capture) @@ -418,3 +428,122 @@ Func UpdatePicture($aCursor = $g_aPoint_UpdatePicture_Cache) Return $aResult EndIf EndFunc + +Global $g_hCompatibilityTest = Null +Func ScriptTest_CreateGui($sMessage, ByRef $hBitmap) + If $g_hCompatibilityTest <> Null Then Return SetError(1, 0, False) + $g_hCompatibilityTest = GUICreate("MSL-Bot Compatibility Test", 823, 367, -1, -1, -1, -1, $g_hParent) + Global $g_idCompatibilityTest_editMain = GUICtrlCreateEdit($sMessage, 10, 10, 296, 307, $WS_VSCROLL, -1) + Global $g_idCompatibilityTest_picMain = GUICtrlCreatePic("", 309, 10, 507, 350, -1, -1) + Global $g_idCompatibilityTest_btnClose = GUICtrlCreateButton("Close", 260, 330, 46, 30, -1, -1) + Global $g_idCompatibilityTest_btnCopyText = GUICtrlCreateButton("Copy Text", 10, 330, 80, 30, -1, -1) + Global $g_idCompatibilityTest_btnCopyImage = GUICtrlCreateButton("Copy as Image", 96, 330, 160, 30, -1, -1) + + GUISetState(@SW_SHOW, $g_hCompatibilityTest) + + Local $tagSize = _WinAPI_GetBitmapDimension($hBitmap) + Local $aImageSize = [DllStructGetData($tagSize, 'X'), DllStructGetData($tagSize, 'Y')] + If $aImageSize[0] = 0 Or $aImageSize[1] = 0 Then Return SetError(2, 0, False) + + Local $hAdjusted = _WinAPI_AdjustBitmap($hBitmap, 507, 350) + + _WinAPI_DeleteObject(GUICtrlSendMsg($g_idCompatibilityTest_picMain, $STM_SETIMAGE, $IMAGE_BITMAP, $hAdjusted)) + _WinAPI_DeleteObject($hAdjusted) + + Return $g_hCompatibilityTest +EndFunc + +Global $g_hGemWindow = Null +Global $g_aGemWindow_GemsFound[0] +Global $g_iGemWindow_GemsFound = 0 +Func GemWindow_CreateGui() + If $g_hGemWindow <> Null Then Return SetError(1, 0, False) + $g_hGemWindow = GUICreate("Gem Window", 327, 286, -1, -1, -1, -1, $g_hParent) + Global $g_idGemWindow_tabMain = GUICtrlCreateTab(3, 1, 322, 282) + GUICtrlSetResizing(-1, $GUI_DOCKAUTO+$GUI_DOCKWIDTH+$GUI_DOCKHEIGHT) + Global $g_idGemWindow_pageFilter = GUICtrlCreateTabItem("Filter") + Global $g_idGemWindow_lblAction = GUICtrlCreateLabel("Action:", 16, 33, 37, 17) + Global $g_idGemWindow_cmbAction = GUICtrlCreateCombo("", 56, 31, 185, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL)) + GUICtrlSetData(-1, "Create...|Remove...|Save...|Help...", "Create...") + Global $g_idGemWindow_btnGo = GUICtrlCreateButton("Go", 244, 29, 71, 25) + Global $g_idGemWindow_lblCurrent = GUICtrlCreateLabel("Current Filter:", 16, 64, 66, 17) + + ;Combo items from files in gem_filters + Global $g_idGemWindow_cmbFilter = GUICtrlCreateCombo("", 84, 62, 230, 25, BitOR($CBS_DROPDOWNLIST,$CBS_AUTOHSCROLL)) + Local $aFiles = _FileListToArray($g_sFilterFolder) + If isArray($aFiles) = True And $aFiles[0] > 0 Then + GUICtrlSetData(-1, _ArrayToString($aFiles, "|", 1), $aFiles[1]) + EndIf + + ;Set edit to file contents if it exists + Local $sCurrent = GUICtrlRead(-1) + Global $g_idGemWindow_editFilter = GUICtrlCreateEdit("", 10, 88, 306, 188, BitOR($ES_AUTOHSCROLL, $ES_WANTRETURN, $WS_HSCROLL)) + If $sCurrent <> "" Then + Local $sContent = FileRead($g_sFilterFolder & $sCurrent) + If @error Then GUICtrlSetData(-1, "Error: Could not load filter.") + If @error = 0 Then GUICtrlSetData(-1, $sContent) + EndIf + + GUICtrlSetFont(-1, 12, 400, 0, "MS Reference Sans Serif") + Global $g_idGemWindow_pageGemsFound = GUICtrlCreateTabItem("Gems Found") + Global $g_idGemWindow_btnNext = GUICtrlCreateButton("Next", 190, 250, 100, 25) + Global $g_idGemWindow_btnPrevious = GUICtrlCreateButton("Previous", 37, 250, 100, 25) + Global $g_idGemWindow_lblGemsFilter = GUICtrlCreateLabel("Filter:", 15, 36, 29, 17) + Global $g_idGemWindow_inpFilter = GUICtrlCreateInput("Does not work yet", 44, 34, 190, 21) + GUICtrlSetState(-1, $GUI_DISABLE) + Global $g_idGemWindow_btnFilter = GUICtrlCreateButton("Filter", 237, 32, 75, 25) + GUICtrlSetState(-1, $GUI_DISABLE) + Global $g_idGemWindow_editGem = GUICtrlCreateEdit("", 11, 59, 304, 186, BitOR($ES_READONLY,$ES_WANTRETURN)) + GUICtrlSetData(-1, StringFormat("Gem #: 0/0\r\nStatus: N/A\r\nGrade: N/A\r\nShape: N/A\r\nStat: N/A\r\nSub1: N/A\r\nSub2: N/A\r\nSub3: N/A\r\nSub4: N/A")) + GUICtrlSetFont(-1, 11, 400, 0, "MS Reference Sans Serif") + + GUISetState(@SW_SHOW) + + Return $g_hGemWindow +EndFunc + +; [[handle, close_event_function]] +Global $g_hListEditor[0][2] +; [[listview, btn_moveup, btn_down, btn_remove, btn_add, combo]] +Global $g_hListEditor_Controls[0][6] +Func ListEditor_CreateGui($aCurrent, $aDefault, $sFunction) + Local $aWinPos = WinGetPos($g_hParent) + Local $x = -1, $y = -1 + If isArray($aWinPos) = True Then + $x = $aWinPos[0]+(($aWinPos[2]-150)/2) + $y = $aWinPos[1]+(($aWinPos[3]-150)/2) + EndIf + Local $hListEditor = GUICreate("Edit List", 150, 182, $x, $y, -1, $WS_EX_TOPMOST, $g_hParent) + + Local $idListEditor_listMain = GUICtrlCreateListView("", 2, 2, 146, 100, $LVS_SINGLESEL+$LVS_REPORT+$LVS_NOSORTHEADER+$WS_BORDER, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT+$LVS_EX_GRIDLINES) + _GUICtrlListView_AddColumn($idListEditor_listMain, "-Included Values-", 125, 2) + ControlDisable("", "", HWnd(_GUICtrlListView_GetHeader($idListEditor_listMain))) ;Prevents changing column size + + Local $idlistEditor_btnMoveUp = GUICtrlCreateButton("Move up", 2, 104, 72) + Local $idlistEditor_btnMoveDown = GUICtrlCreateButton("Move down", 75, 104, 72) + Local $idlistEditor_btnRemove = GUICtrlCreateButton("Remove", 2, 129, 145) + Local $idlistEditor_btnAdd = GUICtrlCreateButton("Add", 2, 154, 42) + + Local $idlistEdit_cmbMain = GUICtrlCreateCombo("", 46, 155, 100, -1, $CBS_DROPDOWNLIST) + _GUICtrlComboBox_SetItemHeight($idlistEdit_cmbMain, 17) + + ;Set values for listview and combo + For $i = 0 To UBound($aCurrent)-1 + If ($aCurrent[$i] <> "") Then _GUICtrlListView_AddItem($idListEditor_listMain, $aCurrent[$i]) + + ;Removing existing values from default to add those non exisiting in a combo later. + For $j = UBound($aDefault)-1 To 0 Step -1 + If ($aDefault[$j] = $aCurrent[$i]) Then _ArrayDelete($aDefault, $j) + Next + Next + + If isArray($aDefault) Then GUICtrlSetData($idlistEdit_cmbMain, _ArrayToString($aDefault)) + _GUICtrlComboBox_SetCurSel($idlistEdit_cmbMain, 0) + + GUISetState(@SW_SHOW, $hListEditor) + + _WinAPI_SetFocus($hListEditor) + _ArrayAdd($g_hListEditor, _ArrayToString(CreateArr($hListEditor, $sFunction))) + _ArrayAdd($g_hListEditor_Controls, _ArrayToString(CreateArr($idListEditor_listMain, $idlistEditor_btnMoveUp, $idlistEditor_btnMoveDown, $idlistEditor_btnRemove, $idlistEditor_btnAdd, $idlistEdit_cmbMain))) + Return $hListEditor +EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/gui/Handler.au3 b/msl-bot/bin/_src/gui/Handler.au3 index a357ec05..9e5ed520 100644 --- a/msl-bot/bin/_src/gui/Handler.au3 +++ b/msl-bot/bin/_src/gui/Handler.au3 @@ -440,7 +440,7 @@ Func GUI_HANDLE_MESSAGE($iCode) Case $g_idPromptsWindow_Help If $g_hPromptsWindow_HelpWindow <> Null Then GUIDelete($g_hPromptsWindow_HelpWindow) Local $aWinPos = WinGetPos($g_hPromptsWindow) - $g_hPromptsWindow_HelpWindow = CreateMessageBox("Schedule Add Help", $g_sPromptsWindow_Help, $aWinPos[0]+$aWinPos[2], $aWinPos[1]+(($aWinPos[3]-300)/2)) + $g_hPromptsWindow_HelpWindow = CreateMessageBox("Schedule Add Help", $g_sPromptsWindow_Help, 300, 300, $aWinPos[0]+$aWinPos[2], $aWinPos[1]+(($aWinPos[3]-300)/2), $g_hPromptsWindow) EndSwitch Case $g_hMessageBox Switch $iCode[0] @@ -504,9 +504,214 @@ Func GUI_HANDLE_MESSAGE($iCode) _ProcessLines($aExpressions) EndIf EndSwitch + Case $g_hGemWindow + Switch $iCode[0] + Case $GUI_EVENT_CLOSE + GUIDelete($g_hGemWindow) + $g_hGemWindow = Null + Case $g_idGemWindow_btnGo ;Action button + Switch GUICtrlRead($g_idGemWindow_cmbAction) + Case "Create..." + Local $sInput = InputBox("Gem Window - Create", "Enter new filter name:", "New Filter") + If $sInput <> "" And @error = 0 Then + If FileExists($g_sFilterFolder & $sInput) = True Then + MsgBox($MB_ICONWARNING+$MB_OK, "Gem Window - Create", "Filter already exists.") + GUI_HANDLE_MESSAGE($iCode) + Else + Local $hFile = FileOpen($g_sFilterFolder & $sInput, $FO_CREATEPATH+$FO_OVERWRITE) + If $hFile <> -1 Then + Local $iResult = FileWrite($hFile, StringFormat("grade:6\r\nshape:any\r\ntype:ruin,valor\r\nstat:any%\r\nsub1:critrate%\r\nsub2:any%\r\nsub3:any\r\nsub4:any")) + If $iResult = 1 Then + GUICtrlSetData($g_idGemWindow_cmbFilter, $sInput, $sInput) + GUI_HANDLE_MESSAGE(CreateArr($g_idGemWindow_cmbFilter, $g_hGemWindow)) + MsgBox($MB_ICONINFORMATION+$MB_OK, "Gem Window - Create", "Created new filter: " & $sInput & ".") + Else + MsgBox($MB_ICONERROR+$MB_OK, "Gem Window - Create", "Could not create filter file.") + EndIf + FileClose($hFile) + Else + MsgBox($MB_ICONERROR+$MB_OK, "Gem Window - Create", "Could not create filter file.") + EndIf + EndIf + EndIf + Case "Remove..." + Local $sCurrent = GUICtrlRead($g_idGemWindow_cmbFilter) + If FileExists($g_sFilterFolder & $sCurrent) = True And $sCurrent <> "" Then + Local $iResponse = MsgBox($MB_ICONWARNING+$MB_YESNO, "Gem Window - Remove", "Are you sure you want to delete: " & $sCurrent) + If $iResponse = $IDYES Then + If FileDelete($g_sFilterFolder & $sCurrent) = 0 Then + MsgBox($MB_ICONERROR, "Gem Window - Remove", "Could not remove filter.") + Else + _GUICtrlComboBox_DeleteString($g_idGemWindow_cmbFilter, _GUICtrlComboBox_GetCurSel($g_idGemWindow_cmbFilter)) + _GUICtrlComboBox_SetCurSel($g_idGemWindow_cmbFilter, -1) + GUICtrlSetData($g_idGemWindow_editFilter, "") + EndIf + EndIf + Else + MsgBox($MB_ICONWARNING+$MB_OK, "Gem Window - Remove", "A filter has not been selected.") + EndIf + Case "Save..." + Local $sCurrent = GUICtrlRead($g_idGemWindow_cmbFilter) + If FileExists($g_sFilterFolder & $sCurrent) = True And $sCurrent <> "" Then + If $sCurrent == "" Or FileExists($g_sFilterFolder & $sCurrent) = False Then + MsgBox($MB_ICONERROR+$MB_OK, "Gem Window - Save", "Could not save filter.") + Else + Local $sContent = GUICtrlRead($g_idGemWindow_editFilter) + Local $bValid = _GemWindow_isValid($sContent) + If $bValid = True Then + Local $hFile = FileOpen($g_sFilterFolder & $sCurrent, $FO_CREATEPATH+$FO_OVERWRITE) + If $hFile <> -1 Then + Local $iResult = FileWrite($hFile, $sContent) + If $iResult = 1 Then + MsgBox($MB_ICONINFORMATION+$MB_OK, "Gem Window - Save", "Filter has been saved: " & $sCurrent) + Else + MsgBox($MB_ICONERROR+$MB_OK, "Gem Window - Save", "Could not write to file.") + EndIf + FileClose($hFile) + Else + MsgBox($MB_ICONERROR+$MB_OK, "Gem Window - Save", "Could not safe filter.") + EndIf + Else + Local $iError = @error + Local $iExtended = @extended + + Local $sError = _GUICtrlEdit_GetLine($g_idGemWindow_editFilter, $iExtended-1) + MsgBox($MB_ICONERROR+$MB_OK, "Gem Window - Save", $sError & @CRLF & @CRLF & "Error in line " & $iExtended & ": '" & $_GemWindow_isValid_ErrorString[$iError] & "'") + EndIf + EndIf + Else + MsgBox($MB_ICONWARNING+$MB_OK, "Gem Window - Save", "A filter has not been selected.") + EndIf + Case "Help..." + Local $iFind = _MessageBox_FindTitle("Gem Window - Help") + If $iFind = -1 Then + Local $sHelp = FileRead($g_sLocalFolder & "gem_filter.txt") + If @error Then + MsgBox($MB_ICONERROR+$MB_OK, "Gem Window - Help", "Could not open help file.") + Else + CreateMessageBox("Gem Window - Help", $sHelp, 400, 600, -1, -1, $iCode[1]) + EndIf + Else + WinActivate($g_hMessageBox[$iFind]) + EndIf + Case Else + MsgBox($MB_ICONERROR+$MB_OK, "Gem Window - Action", "Invalid action.") + EndSwitch + Case $g_idGemWindow_cmbFilter ;Change current filter + Local $sContent = FileRead($g_sFilterFolder & GUICtrlRead($g_idGemWindow_cmbFilter)) + If @error Then GUICtrlSetData($g_idGemWindow_editFilter, "Error: Could not load filter.") + If @error = 0 Then GUICtrlSetData($g_idGemWindow_editFilter, $sContent) + Case $g_idGemWindow_tabMain + If GUICtrlRead($g_idGemWindow_tabMain) = 1 Then ;2nd Tab + _GemWindow_UpdateFound($g_iGemWindow_GemsFound) + EndIf + Case $g_idGemWindow_btnNext + $g_iGemWindow_GemsFound += 1 + If $g_iGemWindow_GemsFound >= UBound($g_aGemWindow_GemsFound) Then + $g_iGemWindow_GemsFound = 0 + EndIf + _GemWindow_UpdateFound($g_iGemWindow_GemsFound) + Case $g_idGemWindow_btnPrevious + $g_iGemWindow_GemsFound -= 1 + If $g_iGemWindow_GemsFound < 0 Then + $g_iGemWindow_GemsFound = UBound($g_aGemWindow_GemsFound)-1 + EndIf + _GemWindow_UpdateFound($g_iGemWindow_GemsFound) + EndSwitch + Case Else + #Region MessageBox + For $i = UBound($g_hMessageBox)-1 To 0 Step -1 + Local $hMessageBox = $g_hMessageBox[$i] + If $iCode[1] = $hMessageBox Then + If $iCode[0] = $GUI_EVENT_CLOSE Then + GUIDelete($hMessageBox) + _ArrayDelete($g_hMessageBox, $i) + EndIf + Return True + EndIf + Next + #EndRegion + + #Region ListEditor + If UBound($g_hListEditor) <> UBound($g_hListEditor_Controls) Then + MsgBox($MB_ICONERROR+$MB_OK, "ListEditor", "Something went wrong with the List Editor GUI.", 10) + Return SetError(1, 0, False) + EndIf + + For $i = UBound($g_hListEditor)-1 To 0 Step -1 + Local $hListEditor = $g_hListEditor[$i][0] + If $iCode[1] = $hListEditor Then + Local $idListEditor_listMain = $g_hListEditor_Controls[$i][0] + Local $idListEditor_cmbMain = $g_hListEditor_Controls[$i][5] + + Switch $iCode[0] + Case $GUI_EVENT_CLOSE + Local $aItems[0] + Local $iSize = _GUICtrlListView_GetItemCount($idListEditor_listMain) + For $x = 0 To $iSize-1 + _ArrayAdd($aItems, _GUICtrlListView_GetItemText($idListEditor_listMain, $x)) + Next + Call($g_hListEditor[$i][1], (UBound($aItems) > 0)?($aItems):("")) + + GUIDelete($hListEditor) + _ArrayDelete($g_hListEditor, $i) + _ArrayDelete($g_hListEditor_Controls, $i) + Case $g_hListEditor_Controls[$i][1] ;Button Move Up + Local $aData = _GUICtrlListView_GetSelectedIndices($idListEditor_listMain, True) + If ($aData[0] > 0) Then + If ($aData[1] > 0) Then + Local $sTemp = _GUICtrlListView_GetItemText($idListEditor_listMain, $aData[1]-1) + _GUICtrlListView_SetItemText($idListEditor_listMain, $aData[1]-1, _GUICtrlListView_GetItemText($idListEditor_listMain, $aData[1])) + _GUICtrlListView_SetItemText($idListEditor_listMain, $aData[1], $sTemp) + + _GUICtrlListView_SetItemSelected($idListEditor_listMain, $aData[1]-1, True, True) + _WinAPI_SetFocus(GUICtrlGetHandle($idListEditor_listMain)) + Else + _GUICtrlListView_SetItemSelected($idListEditor_listMain, $aData[1], True, True) + _WinAPI_SetFocus(GUICtrlGetHandle($idListEditor_listMain)) + EndIf + EndIf + Case $g_hListEditor_Controls[$i][2] ;Button Move Down + Local $aData = _GUICtrlListView_GetSelectedIndices($idListEditor_listMain, True) + If ($aData[0] > 0) Then + If ($aData[1] < _GUICtrlListView_GetItemCount($idListEditor_listMain) - 1) Then + Local $sTemp = _GUICtrlListView_GetItemText($idListEditor_listMain, $aData[1]+1) + _GUICtrlListView_SetItemText($idListEditor_listMain, $aData[1]+1, _GUICtrlListView_GetItemText($idListEditor_listMain, $aData[1])) + _GUICtrlListView_SetItemText($idListEditor_listMain, $aData[1], $sTemp) + + _GUICtrlListView_SetItemSelected($idListEditor_listMain, $aData[1]+1, True, True) + _WinAPI_SetFocus(GUICtrlGetHandle($idListEditor_listMain)) + Else + _GUICtrlListView_SetItemSelected($idListEditor_listMain, $aData[1], True, True) + _WinAPI_SetFocus(GUICtrlGetHandle($idListEditor_listMain)) + EndIf + EndIf + Case $g_hListEditor_Controls[$i][3] ;Button Remove + Local $aData = _GUICtrlListView_GetSelectedIndices($idListEditor_listMain, True) + If ($aData[0] > 0) Then + Local $sSelected = _GUICtrlListView_GetItemText($idListEditor_listMain, $aData[1]) + GUICtrlSetData($idListEditor_cmbMain, $sSelected, $sSelected) + _GUICtrlListView_DeleteItemsSelected($idListEditor_listMain) + _GUICtrlListView_SetItemSelected($idListEditor_listMain, $aData[1], True, True) + EndIf + Case $g_hListEditor_Controls[$i][4] ;Button Add + Local $sText = GUICtrlRead($idListEditor_cmbMain) + If ($sText <> "") Then + _GUICtrlListView_AddItem($idListEditor_listMain, $sText) + + _GUICtrlComboBox_DeleteString($idListEditor_cmbMain, _GUICtrlComboBox_GetCurSel($idListEditor_cmbMain)) + _GUICtrlComboBox_SetCurSel($idListEditor_cmbMain, 0) + EndIf + EndSwitch + + Return True + EndIf + Next + #EndRegion EndSwitch If $g_aComboMenu <> Null Then handleCombo($iCode[0], $g_hLV_ScriptConfig) + Return True EndFunc Func WM_COMMAND($hWnd, $iMsg, $wParam, $lParam) @@ -600,7 +805,23 @@ Func WM_NOTIFY($hWnd, $iMsg, $wParam, $lParam) ;Shows edit in the position. createEdit($g_hEditConfig, $g_iEditConfig, $g_hLV_ScriptConfig) Case "list" - createListEditor($g_hParent, $g_hLV_ScriptConfig, $iIndex) + Local $aCurrent = StringSplit(_GUICtrlListView_GetItemText($g_hLV_ScriptConfig, $iIndex, 1), ",", $STR_NOCOUNT) + Local $aDefault = StringSplit(_GUICtrlListView_GetItemText($g_hLV_ScriptConfig, $iIndex, 4), ",", $STR_NOCOUNT) + + $g_iListEditor_Index = $iIndex + GUISetState(@SW_DISABLE, $g_hParent) + ListEditor_CreateGui($aCurrent, $aDefault, "_ListEditor_Config_Close") + Case "listfunction" + Local $aCurrent = StringSplit(_GUICtrlListView_GetItemText($g_hLV_ScriptConfig, $iIndex, 1), ",", $STR_NOCOUNT) + Local $sFunction = _GUICtrlListView_GetItemText($g_hLV_ScriptConfig, $iIndex, 4) + Local $aDefault = Call($sFunction) + If @error = 0xDEAD And @extended = 0xBEEF Then + MsgBox($MB_ICONERROR+$MB_OK, "MSL Bot Config Error", "Function not found: " & $sFunction) + Else + $g_iListEditor_Index = $iIndex + GUISetState(@SW_DISABLE, $g_hParent) + ListEditor_CreateGui($aCurrent, $aDefault, "_ListEditor_Config_Close") + EndIf Case "setting" Local $sText = _GUICtrlListView_GetItemText($g_hLV_ScriptConfig, $iIndex, 1) Local $iScriptIndex = _GUICtrlComboBox_FindString($g_hCmb_Scripts, $sText) @@ -758,15 +979,35 @@ Func GeneratePromptsWindow(ByRef $hParent, $sTitle, $aPrompts, $aPreset, $sHelp EndFunc ;Returns message handle -Func CreateMessageBox($sTitle, $sMessage, $iX = -1, $iY = -1) - $g_hMessageBox = GUICreate($sTitle, 300, 300, $iX, $iY, $WS_SIZEBOX+$WS_MINIMIZEBOX+$WS_MAXIMIZEBOX) - GUISetFont(8.5, 0, 0, "Lucida Console", $g_hMessageBox) - $g_idEditMessage = GUICtrlCreateEdit($sMessage, 0, 0, 300, 275, $ES_READONLY+$WS_VSCROLL) +Global $g_hMessageBox[0] +Func CreateMessageBox($sTitle, $sMessage, $iWidth = 300, $iHeight = 300, $iX = -1, $iY = -1, $hParent = 0) + If $hParent <> 0 Then + Local $aWinPos = WinGetPos($hParent) + If isArray($aWinPos) = True Then + If $iX = -1 Then $iX = $aWinPos[0] + $aWinPos[2] + If $iY = -1 Then $iY = $aWinPos[1] + Int(($aWinPos[3] - $iHeight) / 2) + EndIf + EndIf + + Local $hMessageBox = GUICreate($sTitle, $iWidth, $iHeight, $iX, $iY, $WS_SIZEBOX+$WS_MINIMIZEBOX+$WS_MAXIMIZEBOX, -1, $hParent) + GUISetFont(8.5, 0, 0, "Lucida Console", $hMessageBox) + Global $g_idEditMessage = GUICtrlCreateEdit($sMessage, 0, 0, $iWidth, $iHeight-25, $ES_READONLY+$WS_VSCROLL) GUICtrlSetResizing($g_idEditMessage, $GUI_DOCKBORDERS) - GUISetState(@SW_SHOW, $g_hMessageBox) + GUISetState(@SW_SHOW, $hMessageBox) _GUICtrlEdit_SetSel($g_idEditMessage, 0, 0) - Return $g_hMessageBox + + _ArrayAdd($g_hMessageBox, $hMessageBox) + Return $hMessageBox +EndFunc + +Func _MessageBox_FindTitle($sTitle) + For $i = 0 To UBound($g_hMessageBox)-1 + If WinGetTitle($g_hMessageBox[$i]) == $sTitle Then + Return $i + EndIf + Next + Return -1 EndFunc ;Handles the combo config contextmenu @@ -843,170 +1084,152 @@ Func _endEdit() HotKeySet("{ENTER}") EndFunc -Func createListEditor($g_hParent, $hListView, $iIndex) - Opt("GUIOnEventMode", 1) - ; [gui handle, listview inside gui, combo handle, combo values, parent handle, listview handle, item index] - Local $aCurrent = StringSplit(_GUICtrlListView_GetItemText($hListView, $iIndex, 1), ",", $STR_NOCOUNT) - Local $aDefault = StringSplit(_GUICtrlListView_GetItemText($hListView, $iIndex, 4), ",", $STR_NOCOUNT) - - Local $t_aListEditor[7] ;Holds the array items from comment above. - Local $t_aPos = WinGetPos($g_hParent) - $t_aListEditor[0] = GUICreate("Edit List", 150, 182, $t_aPos[0]+(($t_aPos[2]-150)/2), $t_aPos[1]+(($t_aPos[3]-150)/2), -1, $WS_EX_TOPMOST, $g_hParent) - $t_aListEditor[1] = GUICtrlCreateListView("", 2, 2, 146, 100, $LVS_SINGLESEL+$LVS_REPORT+$LVS_NOSORTHEADER+$WS_BORDER) - Local $t_hListView = GUICtrlGetHandle($t_aListEditor[1]) - - _GUICtrlListView_SetExtendedListViewStyle($t_hListView, $LVS_EX_DOUBLEBUFFER+$LVS_EX_FULLROWSELECT+$LVS_EX_GRIDLINES) - _GUICtrlListView_AddColumn($t_hListView, "-Included Values-", 125, 2) - ControlDisable("", "", HWnd(_GUICtrlListView_GetHeader($t_hListView))) ;Prevents changing column size - - ;adding current items. - For $i = 0 To UBound($aCurrent, $UBOUND_ROWS)-1 - If ($aCurrent[$i] <> "") Then _GUICtrlListView_AddItem($t_hListView, $aCurrent[$i]) - - ;Removing existing values from default to add those non exisiting in a combo later. - For $j = 0 To UBound($aDefault, $UBOUND_ROWS)-1 - If ($aDefault[$j] = $aCurrent[$i]) Then $aDefault[$j] = Null - Next - Next - - $t_aListEditor[4] = $g_hParent - $t_aListEditor[5] = $hListView - $t_aListEditor[6] = $iIndex - - GUICtrlCreateButton("Move up", 2, 104, 72) - GUICtrlSetOnEvent(-1, "ListEditor_btnMoveUp") - GUICtrlCreateButton("Move down", 75, 104, 72) - GUICtrlSetOnEvent(-1, "ListEditor_btnMoveDown") +; Show a menu in a given GUI window which belongs to a given GUI ctrl +Func ShowMenu($hWnd, $idContext) + Local $aPos, $x, $y + Local $hMenu = GUICtrlGetHandle($idContext) - GUICtrlCreateButton("Remove", 2, 129, 145) - GUICtrlSetOnEvent(-1, "ListEditor_btnRemove") + $aPos = MouseGetPos() - GUICtrlCreateButton("Add", 2, 154, 42) - GUICtrlSetOnEvent(-1, "ListEditor_btnAdd") + $x = $aPos[0] + $y = $aPos[1] - $t_aListEditor[2] = GUICtrlCreateCombo("", 46, 155, 100, -1, $CBS_DROPDOWNLIST) - _GUICtrlComboBox_SetItemHeight(GUICtrlGetHandle($t_aListEditor[2]), 17) + TrackPopupMenu($hWnd, $hMenu, $x, $y) +EndFunc ;==>ShowMenu - Local $sComboItems = "" ;stores excluded items in combo item format. - For $i = 0 To UBound($aDefault, $UBOUND_ROWS)-1 - If ($aDefault[$i] <> Null) Then $sComboItems &= "|" & $aDefault[$i] +; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) +Func TrackPopupMenu($hWnd, $hMenu, $x, $y) + DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) +EndFunc ;==>TrackPopupMenu + +;Other Helper Functions =============================================== + +; Check if data is valid for use. +Global Const $_GemWindow_isValid_ErrorString = _ + ["No error.", _ + "Invalid format.", _ + "Duplicate data type.", _ + "Empty value.", _ + "Other values being used when 'any' is used in 'grade'.", _ + "Other values being used when 'any' is used in 'shape'.", _ + "Other values being used when 'any' is used in 'type'.", _ + "Invalid data type.", _ + "Invalid value.", _ + "Duplicate values."] +Func _GemWindow_isValid($sFilter) + Local $aData = StringSplit($sFilter, @CRLF, $STR_NOCOUNT) + If isArray($aData) = False Then $aData = CreateArr($aData) + + ;Remove empty entries + For $i = UBound($aData)-1 To 0 Step -1 + If $aData[$i] == "" Then _ArrayDelete($aData, $i) Next - $sComboItems = StringMid($sComboItems, 2) - GUICtrlSetData($t_aListEditor[2], $sComboItems) - If ($sComboItems <> "") Then _GUICtrlComboBox_SetCurSel(GUICtrlGetHandle($t_aListEditor[2]), 0) - $t_aListEditor[3] = $sComboItems + For $i = 0 To UBound($aData)-1 + Local $sData = $aData[$i] + $sData = StringStripWS($sData, $STR_STRIPALL) + $sData = StringLower($sData) - $g_aListEditor = $t_aListEditor - GUISetOnEvent($GUI_EVENT_CLOSE, "ListEditor_Close", $g_aListEditor[0]) + ;Check data types + Local $aType = StringSplit($sData, ":", $STR_NOCOUNT) + If isArray($aType) = False Or UBound($aType) <> 2 Then Return SetError(1, $i+1, False) ;Not valid type - GUISetState(@SW_SHOW, $g_aListEditor[0]) - GUISetState(@SW_DISABLE, $g_aListEditor[4]) + Local $aDuplicate = _ArrayFindAll($aData, $sData) + If isArray($aDuplicate) = True And UBound($aDuplicate) <> 1 Then Return SetError(2, $i+1, False) ;Duplicates types - _WinAPI_SetFocus($g_aListEditor[0]) -EndFunc + ;Check values + If $aType[1] == "" Then Return SetError(3, 0, False) ;Empty value -;Moves selected item up index -Func ListEditor_btnMoveUp() - Local $aData = _GUICtrlListView_GetSelectedIndices($g_aListEditor[1], True) - If ($aData[0] > 0) Then - If ($aData[1] > 0) Then - Local $sTemp = _GUICtrlListView_GetItemText($g_aListEditor[1], $aData[1]-1) - _GUICtrlListView_SetItemText($g_aListEditor[1], $aData[1]-1, _GUICtrlListView_GetItemText($g_aListEditor[1], $aData[1])) - _GUICtrlListView_SetItemText($g_aListEditor[1], $aData[1], $sTemp) + Local $aValues = StringSplit($aType[1], ",", $STR_NOCOUNT) + If isArray($aValues) = False Then $aValues = CreateArr($aType[1]) - _GUICtrlListView_SetItemSelected($g_aListEditor[1], $aData[1]-1, True, True) - _WinAPI_SetFocus(GUICtrlGetHandle($g_aLIstEditor[1])) - Else - _GUICtrlListView_SetItemSelected($g_aListEditor[1], $aData[1], True, True) - _WinAPI_SetFocus(GUICtrlGetHandle($g_aLIstEditor[1])) - EndIf + For $sValue In $aValues + Local $aFind = Null + Switch $aType[0] + Case "grade" + If $sValue = "any" And UBound($aValues) > 1 Then Return SetError(4, $i+1, False) ;Used any already + $aFind = _ArrayFindAll($g_aGem_Grade, $sValue) + Case "shape" + If $sValue = "any" And UBound($aValues) > 1 Then Return SetError(5, $i+1, False) ;Used any already + $aFind = _ArrayFindAll($g_aGem_Shape, $sValue) + Case "type" + If $sValue = "any" And UBound($aValues) > 1 Then Return SetError(6, $i+1, False) ;Used any already + $aFind = _ArrayFindAll($g_aGem_Type, $sValue) + Case "stat", "sub1", "sub2", "sub3", "sub4" + If StringRight($sValue, 1) == "%" Or StringRight($sValue, 1) == "+" Then + $sValue = StringMid($sValue, 1, StringLen($sValue) - 1) EndIf -EndFunc + $aFind = _ArrayFindAll($g_aGem_Stat, $sValue) + Case Else + Return SetError(7, $i+1, False) + EndSwitch -;Moves selected item down in index -Func ListEditor_btnMoveDown() - Local $aData = _GUICtrlListView_GetSelectedIndices($g_aListEditor[1], True) - If ($aData[0] > 0) Then - If ($aData[1] < _GUICtrlListView_GetItemCount($g_aListEditor[1]) - 1) Then - Local $sTemp = _GUICtrlListView_GetItemText($g_aListEditor[1], $aData[1]+1) - _GUICtrlListView_SetItemText($g_aListEditor[1], $aData[1]+1, _GUICtrlListView_GetItemText($g_aListEditor[1], $aData[1])) - _GUICtrlListView_SetItemText($g_aListEditor[1], $aData[1], $sTemp) + If isArray($aFind) = False Then Return SetError(8, $i+1, False) ;Not valid value + + $aDuplicate = _ArrayFindAll($aValues, $sValue) + If isArray($aDuplicate) = True And UBound($aDuplicate) <> 1 Then Return SetError(9, $i+1, False) ;Duplicates values + Next + Next - _GUICtrlListView_SetItemSelected($g_aListEditor[1], $aData[1]+1, True, True) - _WinAPI_SetFocus(GUICtrlGetHandle($g_aListEditor[1])) - Else - _GUICtrlListView_SetItemSelected($g_aListEditor[1], $aData[1], True, True) - _WinAPI_SetFocus(GUICtrlGetHandle($g_aLIstEditor[1])) - EndIf - EndIf + Return True EndFunc -;Removes item selected from listview and adds to combobox -Func ListEditor_btnRemove() - Local $aData = _GUICtrlListView_GetSelectedIndices($g_aListEditor[1], True) - If ($aData[0] > 0) Then - $g_aListEditor[3] &= "|" & _GUICtrlListView_GetItemText($g_aListEditor[1], $aData[1]) +;Config List Editor +Global $g_iListEditor_Index = -1 +Func _ListEditor_Config_Close($aData = "") + If $g_iListEditor_Index = -1 Then + MsgBox($MB_ICONERROR+$MB_OK, "ListEditor Config", "Could not save config.") + Return SetError(1, 0, False) + EndIf - If (StringMid($g_aListEditor[3], 1, 1) == "|") Then $g_aListEditor[3] = StringMid($g_aListEditor[3], 2) + Local $sData = "" + If isArray($aData) = True And UBound($aData) > 0 Then $sData = _ArrayToString($aData, ",") + _GUICtrlListView_SetItemText($g_hLV_ScriptConfig, $g_iListEditor_Index, $sData, 1) + GUISetState(@SW_ENABLE, $g_hParent) - GUICtrlSetData($g_aListEditor[2], "") - GUICtrlSetData($g_aListEditor[2], $g_aListEditor[3]) + _GUICtrlListView_SetItemSelected($g_hLV_ScriptConfig, $g_iListEditor_Index, True, True) + _WinAPI_SetFocus($g_hLV_ScriptConfig) - _GUICtrlListView_DeleteItemsSelected($g_aListEditor[1]) - _GUICtrlComboBox_SetCurSel(GUICtrlGetHandle($g_aListEditor[2]), 0) - EndIf + Config_Save() + Return True EndFunc -;Adds item from combobox to listview -Func ListEditor_btnAdd() - Local $sText = GUICtrlRead($g_aListEditor[2]) - If ($sText <> "") Then - _GUICtrlListView_AddItem($g_aListEditor[1], $sText) - - $g_aListEditor[3] = StringReplace(StringReplace($g_aListEditor[3], $sText, ""), "||", "|") - GUICtrlSetData($g_aListEditor[2], "") - GUICtrlSetData($g_aListEditor[2], $g_aListEditor[3]) - _GUICtrlComboBox_SetCurSel(GUICtrlGetHandle($g_aListEditor[2]), 0) - EndIf +;Return list for current available filters +Func _Gem_Filter() + Local $aFilters = _FileListToArray($g_sFilterFolder) + If isArray($aFilters) = False Then Return SetError(1, 0, False) + _ArrayDelete($aFilters, 0) ; Remove count + _ArrayAdd($aFilters, "_Filter") + If isArray($aFilters) = False Then $aFilters = CreateArr() + Return $aFilters EndFunc -;Destroys Window and saves data into listview item -Func ListEditor_Close() - Opt("GUIOnEventMode", 0) - ; Saves changed settings to the listview. - Local $sNew = ""; - Local $iSize = _GUICtrlListView_GetItemCount($g_aListEditor[1]) - For $i = 0 To $iSize-1 - $sNew &= "," & _GUICtrlListView_GetItemText($g_aListEditor[1], $i) - Next - $sNew = StringMid($sNew, 2) - - _GUICtrlListView_SetItemText($g_aListEditor[5], $g_aListEditor[6], $sNew, 1) +Func _GemWindow_AddFound($aGemData, $sStatus) + Local $aGem = parseGem($aGemData) + If @error Then Return SetError(1, @error, False) - _WinAPI_DestroyWindow($g_aListEditor[0]) - GUISetState(@SW_ENABLE, $g_aListEditor[4]) + _ArrayInsert($aGem, 0, $sStatus) + _ArrayAdd($g_aGemWindow_GemsFound, $aGem, 0, "|", @CRLF, $ARRAYFILL_FORCE_SINGLEITEM) - _GUICtrlListView_SetItemSelected($g_aListEditor[5], $g_aListEditor[6], True, True) - _WinAPI_SetFocus($g_aListEditor[5]) - - Config_Save() + If $g_hGemWindow <> Null And GUICtrlRead($g_idGemWindow_tabMain) = 1 Then + _GemWindow_UpdateFound($g_iGemWindow_GemsFound) + EndIf EndFunc -; Show a menu in a given GUI window which belongs to a given GUI ctrl -Func ShowMenu($hWnd, $idContext) - Local $aPos, $x, $y - Local $hMenu = GUICtrlGetHandle($idContext) +Func _GemWindow_UpdateFound($iIndex) + If isDeclared("g_idGemWindow_editGem") = False Then Return SetError(1, 0, False) - $aPos = MouseGetPos() + Local $iSize = UBound($g_aGemWindow_GemsFound) + If $iIndex < 0 Or $iIndex >= $iSize Then Return SetError(2, 0, False) - $x = $aPos[0] - $y = $aPos[1] + Local $aTexts[9] = ["Status", "Grade", "Shape", "Type", "Stat", "Sub1", "Sub2", "Sub3", "Sub4"] + Local $aGem = $g_aGemWindow_GemsFound[$iIndex] - TrackPopupMenu($hWnd, $hMenu, $x, $y) -EndFunc ;==>ShowMenu + Local $sFinal = "Gem #: " & $iIndex+1 & "/" & $iSize + For $i = 0 To UBound($aGem)-1 + $sFinal &= @CRLF & $aTexts[$i] & ": " & (($aGem[$i] <> "")?($aGem[$i]):("N/A")) + Next -; Show at the given coordinates (x, y) the popup menu (hMenu) which belongs to a given GUI window (hWnd) -Func TrackPopupMenu($hWnd, $hMenu, $x, $y) - DllCall("user32.dll", "int", "TrackPopupMenuEx", "hwnd", $hMenu, "int", 0, "int", $x, "int", $y, "hwnd", $hWnd, "ptr", 0) -EndFunc ;==>TrackPopupMenu \ No newline at end of file + GUICtrlSetData($g_idGemWindow_editGem, $sFinal) + Return True +EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/gui/Menu.au3 b/msl-bot/bin/_src/gui/Menu.au3 index ce1d5f85..a14738ba 100644 --- a/msl-bot/bin/_src/gui/Menu.au3 +++ b/msl-bot/bin/_src/gui/Menu.au3 @@ -188,6 +188,15 @@ Func HandleMenu($iCode) $g_sScript = "doHourly" Start() EndIf + Case $M_Scripts_Expedition + If $g_bRunning > 0 Then + If MsgBox($MB_ICONWARNING+$MB_YESNO, "Expedition", "Script is currently running, would you like to continue?", 30) = $IDYES Then + doExpedition() + EndIf + Else + $g_sScript = "doExpedition" + Start() + EndIf Case $M_Scripts_Collect_Quest If $g_bRunning > 0 Then If MsgBox($MB_ICONWARNING+$MB_YESNO, "Collect Quest", "Script is currently running, would you like to continue?", 30) = $IDYES Then @@ -197,15 +206,26 @@ Func HandleMenu($iCode) $g_sScript = "collectQuest" Start() EndIf - Case $M_Scripts_Guardian_Dungeon + Case $M_Scripts_Collect_Inbox If $g_bRunning > 0 Then - If MsgBox($MB_ICONWARNING+$MB_YESNO, "Guardian Dungeon", "Script is currently running, would you like to continue?", 30) = $IDYES Then - _Schedule_Guardian() + If MsgBox($MB_ICONWARNING+$MB_YESNO, "Collect Inbox", "Script is currently running, would you like to continue?", 30) = $IDYES Then + Collect_Inbox() EndIf Else - $g_sScript = "_Schedule_Guardian" + $g_sScript = "Collect_Inbox" Start() EndIf + Case $M_Scripts_Titans_Fast + If $g_bRunning > 0 Then + If $g_bTitansFast Or MsgBox($MB_ICONWARNING+$MB_YESNO, "Titans_Fast", "Script is currently running, would you like to continue?", 30) = $IDYES Then + Titans_Fast() + EndIf + Else + $g_sScript = "Titans_Fast" + Start() + EndIf + Case $M_General_Toggle_Hidden + Toggle_Hidden() Case $M_Capture_Full_Screenshot If FileExists(@ScriptDir & "\screenshots\" & $Config_Profile_Name) = 0 Then DirCreate(@ScriptDir & "\screenshots\" & $Config_Profile_Name) Local $sName = StringRegExpReplace(_NowCalc() , "(\/|\s|\:)", "") @@ -227,6 +247,8 @@ Func HandleMenu($iCode) Else MsgBox($MB_ICONWARNING, "Open Screenshot Folder", "The screenshot folder does not exist.") EndIf + Case $M_Gem_Gem_Window + GemWindow_CreateGui() Case $Dummy_Test_Function TestFunction() EndSwitch diff --git a/msl-bot/bin/_src/gui/Script.au3 b/msl-bot/bin/_src/gui/Script.au3 index 48655a52..55a3e498 100644 --- a/msl-bot/bin/_src/gui/Script.au3 +++ b/msl-bot/bin/_src/gui/Script.au3 @@ -45,6 +45,7 @@ Func Script_ChangeProfile($sName) Script_ChangeConfig() EndFunc + Func Script_SetConfigByFile($sName, $sPath = $g_sProfileFolder & "\" & $Config_Profile_Name & "\") Local $iIndex = Script_IndexByName($sName) If $iIndex = -1 Then Return -1 @@ -54,25 +55,22 @@ Func Script_SetConfigByFile($sName, $sPath = $g_sProfileFolder & "\" & $Config_P Local $sAssign = $sName If StringLeft($sAssign, 1) == "_" Then $sAssign = StringMid($sAssign, 2) + Local $aSaveConfigs[0] For $i = 0 To UBound($aConfig2D)-1 If isArray(Script_DataByName($sName)) = False Then - Log_Add("Could not find data for: " & $sName, $LOG_ERROR) + MsgBox($MB_ICONWARNING+$MB_OK, "Set Config Error", "Could not find data for: " & $sName) ContinueLoop EndIf Local $aConfig_SettingList = (Script_DataByName($sName)[$CONFIG_SETTINGLIST]) - If isArray($aConfig_SettingList) = False Or UBound($aConfig_SettingList) <= $i Then - Log_Add("Could not set config: " & $sName, $LOG_ERROR) - ContinueLoop + Local $sValue = "", $sType = "combo", $sData = "" + If Not(isArray($aConfig_SettingList) = False Or UBound($aConfig_SettingList) <= $i) Then + $sType = ($aConfig_SettingList[$i])[$SETTING_TYPE] + $sData = ($aConfig_SettingList[$i])[$SETTING_DATA] + $sValue = $aConfig2D[$i][1] EndIf - Local $sType = ($aConfig_SettingList[$i])[$SETTING_TYPE] - Local $sData = ($aConfig_SettingList[$i])[$SETTING_DATA] - - Local $sValue = $aConfig2D[$i][1] - If ($sType <> "text" And $sType <> "list" And $sType <> "setting") And _ - (StringInStr($sData, $sValue) = False Or $sValue == "") Then - + If ($sType == "combo") And (StringInStr($sData, $sValue) = False Or $sValue == "") Then $sValue = Eval("Default_" & $sAssign & "_" & $aConfig2D[$i][0]) EndIf @@ -126,15 +124,19 @@ Func Script_SetData($sPath, $sCachePath = "") Local $sData ;Contains unparsed data If FileExists($sPath) Then $sData = FileRead($sPath) - Else - $sData = BinaryToString(InetRead($sPath, $INET_FORCERELOAD)) - If $sCachePath <> "" Then - Local $hFile = FileOpen($sCachePath, $FO_OVERWRITE+$FO_CREATEPATH) - FileWrite($hFile, $sData) - FileClose($hFile) + If @error Then + MsgBox($MB_ICONERROR+$MB_OK, "Settings", "Could not read file: " & $sPath) + Return SetError(1, 0, False) EndIf + Else + MsgBox($MB_ICONERROR+$MB_OK, "Settings", "File does not exist: " & $sPath) + Return SetError(2, 0, False) + EndIf + + If ($sData == "") Then + MsgBox($MB_ICONERROR+$MB_OK, "Settings", "Could not read any data.") + Return SetError(3, 0, False) EndIf - If ($sData == "") Then Return -1 Local $c = StringSplit($sData, "", $STR_NOCOUNT) @@ -161,7 +163,7 @@ Func Script_SetData($sPath, $sCachePath = "") Switch $cur_sField Case "description" $t_aScript[1] = _Script_GetNextString($c, $i) - Case "text", "combo", "setting", "list" + Case "text", "combo", "setting", "list", "listfunction" $t_aConfig[3] = $cur_sField While $c[$i] <> "]" _Script_NextValidChar($c, $i) @@ -176,8 +178,8 @@ Func Script_SetData($sPath, $sCachePath = "") Case "data" $t_aConfig[4] = _Script_GetNextString($c, $i) Case Else - MsgBox(0, "", "Unknown field: " & $sField) - Return -1 + MsgBox($MB_ICONERROR+$MB_OK, "Settings", "Unknown field: " & $sField) + Return SetError(4, 0, False) EndSwitch WEnd @@ -185,6 +187,9 @@ Func Script_SetData($sPath, $sCachePath = "") ReDim $t_aConfigs[UBound($t_aConfigs)+1] $t_aConfigs[UBound($t_aConfigs)-1] = $t_aConfig EndIf + Case Else + MsgBox($MB_ICONERROR+$MB_OK, "Settings", "Unknown type: " & $cur_sField) + Return SetError(5, 0, False) EndSwitch Case "]" $t_aScript[2] = $t_aConfigs @@ -203,6 +208,7 @@ Func Script_SetData($sPath, $sCachePath = "") Next $g_aScripts = $t_aScripts + Return True EndFunc diff --git a/msl-bot/bin/_src/handlers/ADB.au3 b/msl-bot/bin/_src/handlers/ADB.au3 index ab8c0fb9..692f5298 100644 --- a/msl-bot/bin/_src/handlers/ADB.au3 +++ b/msl-bot/bin/_src/handlers/ADB.au3 @@ -6,12 +6,11 @@ Global $g_iADBInputDevice = "" ;Run CMD session to send ADB command. ;Output will be retrieved after command has been executed. -Func ADB_Command($sCommand, $iTimeout = $Delay_ADB_Timeout, $sDevice = "~AUTO") +Func ADB_Command($sCommand, $iTimeout = $Delay_ADB_Timeout, $sDevice = $ADB_Device) Log_Level_Add("ADB_Command") Log_Add("ADB command: " & $sCommand, $LOG_DEBUG) If $Config_Emulator_Path <> "" Then - ;MsgBox(0, "", $Config_Emulator_Path & "\" & $sConsole_Command & '"' & $sCommand & '"') Local $iPID = -1 Local $sResult ;Holds ADB output @@ -19,7 +18,7 @@ Func ADB_Command($sCommand, $iTimeout = $Delay_ADB_Timeout, $sDevice = "~AUTO") If $sDevice == "~AUTO" Then $iPID = Run($Config_Emulator_Path & "\" & $Config_Console_ADB & '"' & $sCommand & '"', "", @SW_HIDE, $STDERR_MERGED) Else - $iPID = Run($Config_Emulator_Path & "\adb.exe -s " & $ADB_Device & '"' & $sCommand & '"', "", @SW_HIDE, $STDERR_MERGED) + $iPID = Run($Config_Emulator_Path & "\adb.exe -s " & $sDevice & '"' & $sCommand & '"', "", @SW_HIDE, $STDERR_MERGED) EndIf Local $hTimer = TimerInit() @@ -39,8 +38,8 @@ Func ADB_Command($sCommand, $iTimeout = $Delay_ADB_Timeout, $sDevice = "~AUTO") ProcessClose($iPID) If ($sResult <> "") Then Log_Add("ADB output: " & $sResult, $LOG_DEBUG) - Log_Level_Remove() - Return $sResult + Log_Level_Remove() + Return (($sResult=="")?(True):($sResult)) EndFunc ;==>ADB_Command ;Send ESC through ADB. @@ -98,10 +97,16 @@ EndFunc ;==>ADB_isWorking Func ADB_isGameRunning($sPackageName = $g_sPackageName) If $g_bADBWorking = 0 Then Return SetError(1, 0, False) + Local $bRunning = True ;Default true if adb command fails. + $g_bLogEnabled = False - Local $bRunning = (StringInStr(ADB_Command("shell ps"), $sPackageName) > 0) + Local $sResult = ADB_Command("shell dumpsys window windows") $g_bLogEnabled = True + If StringInStr($sResult, "mCurrentFocus") = True Then + $bRunning = StringRegExp($sResult, "mCurrentFocus.*" & $sPackageName) + EndIf + If (Not($bRunning)) Then Log_Add("Is game running: " & $bRunning, $LOG_DEBUG) Return $bRunning -EndFunc +EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/handlers/Capture.au3 b/msl-bot/bin/_src/handlers/Capture.au3 index cd7891a7..2abf3e6b 100644 --- a/msl-bot/bin/_src/handlers/Capture.au3 +++ b/msl-bot/bin/_src/handlers/Capture.au3 @@ -55,12 +55,13 @@ Func getBitmapHandles(ByRef $hBitmap, $iBackgroundMode = $Config_Capture_Mode, $ Switch $iBackgroundMode Case $BKGD_WINAPI - Local $hDC_Capture = _WinAPI_GetWindowDC($hControl) + Local $hDC_Capture = _WinAPI_GetDC($hControl) Local $hMemDC = _WinAPI_CreateCompatibleDC($hDC_Capture) $hBitmap = _WinAPI_CreateCompatibleBitmap($hDC_Capture, $EMULATOR_WIDTH, $EMULATOR_HEIGHT) Local $hObjectOld = _WinAPI_SelectObject($hMemDC, $hBitmap) - DllCall("user32.dll", "int", "PrintWindow", "hwnd", $hControl, "handle", $hMemDC, "int", 0) + _WinAPI_PrintWindow($g_hWindow, $hMemDC, True) + _WinAPI_SelectObject($hMemDC, $hBitmap) _WinAPI_BitBlt($hMemDC, 0, 0, $EMULATOR_WIDTH, $EMULATOR_HEIGHT, $hDC_Capture, 0, 0, 0x00CC0020) diff --git a/msl-bot/bin/_src/handlers/Control.au3 b/msl-bot/bin/_src/handlers/Control.au3 index 5f879793..d9b17257 100644 --- a/msl-bot/bin/_src/handlers/Control.au3 +++ b/msl-bot/bin/_src/handlers/Control.au3 @@ -83,10 +83,9 @@ Func clickPoint($vPoint, $iAmount = 1, $iInterval = 0, $iMouseMode = $Config_Mou ;Fixing format to [x, y] While True - If isArray($vPoint) = 0 Then + If isArray($vPoint) = False Then If ($vPoint == "" Or $vPoint = -1) Then - Log_Add("Invalid points: " & $vPoint, $LOG_ERROR) - $g_sErrorMessage = "clickPoint() => Invalid points." + Log_Add("Invalid points (1): " & $vPoint, $LOG_ERROR) ExitLoop EndIf @@ -95,8 +94,7 @@ Func clickPoint($vPoint, $iAmount = 1, $iInterval = 0, $iMouseMode = $Config_Mou $aPoint[1] = StringStripWS($t_aPoint[1], $STR_STRIPLEADING + $STR_STRIPTRAILING) Else If (UBound($vPoint) < 2) Then - Log_Add("Invalid points: " & _ArrayToString($vPoint), $LOG_ERROR) - $g_sErrorMessage = "clickPoint() => Invalid points." + Log_Add("Invalid points (2): " & _ArrayToString($vPoint), $LOG_ERROR) ExitLoop EndIf @@ -134,7 +132,6 @@ Func clickPoint($vPoint, $iAmount = 1, $iInterval = 0, $iMouseMode = $Config_Mou ADB_Command("shell input tap " & $aPoint[0] & " " & $aPoint[1]) Case Else Log_Add("Invalid mouse mode: " & $iMouseMode, $LOG_ERROR) - $g_sErrorMessage = "clickPoint() => Invalid mouse mode: " & $iMouseMode ExitLoop(2) EndSwitch @@ -316,4 +313,52 @@ Func SendBack($iCount = 1, $iSpeed = 50, $iMode = $Config_Back_Mode) Sleep($iSpeed) WEnd Log_Level_Remove() +EndFunc + +Func waitUntil($sFunction, $aParameters, $sResult, $iSeconds, $iInterval = 50, $sExecute = "") + If isArray($aParameters) = False Or UBound($aParameters) = 0 Then + $aParameters = CreateArr("CallArgArray") + Else + _ArrayInsert($aParameters, 0, "CallArgArray") + EndIf + + If $sExecute <> "" Then Execute($sExecute) + Local $sCallResult = Call($sFunction, $aParameters) + If (@error = 0xDEAD And @extended = 0xBEEF) Then Return SetError(1, 0, False) + + Local $hTimer = TimerInit() + While ($sCallResult <> $sResult) + If $sExecute <> "" Then Execute($sExecute) + If TimerDiff($hTimer) > $iSeconds*1000 Then ExitLoop + If _Sleep($iInterval, True) Then ExitLoop + + $sCallResult = Call($sFunction, $aParameters) + If (@error = 0xDEAD And @extended = 0xBEEF) Then Return SetError(2, 0, False) + WEnd + + Return ($sCallResult = $sResult) +EndFunc + +Func waitWhile($sFunction, $aParameters, $sResult, $iSeconds, $iInterval = 50, $sExecute = "") + If isArray($aParameters) = False Or UBound($aParameters) = 0 Then + $aParameters = CreateArr("CallArgArray") + Else + _ArrayInsert($aParameters, 0, "CallArgArray") + EndIf + + If $sExecute <> "" Then Execute($sExecute) + Local $sCallResult = Call($sFunction, $aParameters) + If (@error = 0xDEAD And @extended = 0xBEEF) Then Return SetError(1, 0, False) + + Local $hTimer = TimerInit() + While ($sCallResult = $sResult) + If $sExecute <> "" Then Execute($sExecute) + If TimerDiff($hTimer) > $iSeconds*1000 Then ExitLoop + If _Sleep($iInterval, True) Then ExitLoop + + $sCallResult = Call($sFunction, $aParameters) + If (@error = 0xDEAD And @extended = 0xBEEF) Then Return SetError(2, 0, False) + WEnd + + Return ($sCallResult <> $sResult) EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/handlers/Emulator.au3 b/msl-bot/bin/_src/handlers/Emulator.au3 index 66f1f7ef..0cbb5b36 100644 --- a/msl-bot/bin/_src/handlers/Emulator.au3 +++ b/msl-bot/bin/_src/handlers/Emulator.au3 @@ -32,6 +32,7 @@ Func Emulator_Restart($iAttempt = 1, $sPackageName = $g_sPackageName) Log_Level_Add("Emulator Restart") Log_Add("Restarting emulator process.") $g_bRestarting = True + Local $aSavePos = WinGetPos($g_hWindow) Local $bOutput = 0 While $iAttempt >= 1 @@ -77,6 +78,7 @@ Func Emulator_Restart($iAttempt = 1, $sPackageName = $g_sPackageName) Do $g_bLogEnabled = True ResetHandles() + If $g_hWindow <> 0 Then WinMove($g_hWindow, "", $aSavePos[0], $aSavePos[1]) _Emulator_Console_RunApp($Config_Emulator_Title, $sPackageName) If ($g_hWindow <> 0 And $g_hControl <> 0) And getLocation() == "tap-to-start" Then @@ -93,7 +95,7 @@ Func Emulator_Restart($iAttempt = 1, $sPackageName = $g_sPackageName) ScriptTest_Handles() If ADB_isWorking() > 0 Then Log_Add("Successfully connected to ADB Server.") - If ADB_isGameRunning() = 0 Then + If ADB_isGameRunning() = False Then $bOutput = Emulator_RestartGame($iAttempt, $sPackageName) ExitLoop EndIf @@ -105,7 +107,11 @@ Func Emulator_Restart($iAttempt = 1, $sPackageName = $g_sPackageName) EndIf ResetHandles() + If $g_hWindow <> 0 Then WinMove($g_hWindow, "", $aSavePos[0], $aSavePos[1]) + $bOutput = navigate("village", True, 5) + If @extended = 1 Then ExitLoop ;app-maintenance or app-update + $iAttempt -= 1 WEnd @@ -115,26 +121,55 @@ Func Emulator_Restart($iAttempt = 1, $sPackageName = $g_sPackageName) Return $bOutput EndFunc -Func Emulator_RestartGame($iAttempt = 1, $sPackageName = $g_sPackageName) +Func Emulator_RestartGame($iAttempt = 1, $sPackageName = $g_sPackageName, $bUseADB = $ADB_ADB_Restart_Game, $sActivity = $g_sPackageActivity) Log_Level_Add("Emulator_RestartGame") Log_Add("Restarting game.") $g_bRestarting = True $bOutput = False + Local $bScheduleBusy = $g_bScheduleBusy + $g_bScheduleBusy = True + Local $iCounter = 1 While $iAttempt > 0 + Status("Restarting game attempt #" & $iCounter, $LOG_INFORMATION) + $iCounter += 1 + $g_hTimerLocation = Null ;Prevent AntiStuck restart If $bOutput > 0 Or _Sleep(500) Then ExitLoop - - If _Emulator_Console_KillApp($Config_Emulator_Title, $sPackageName) = -1 Then ExitLoop - If _Sleep(2000) Then ExitLoop - If _Emulator_Console_RunApp($Config_Emulator_Title, $sPackageName) = -1 Then ExitLoop + If $bUseADB = False Then + ;Use emulator console to restart game. + If _Emulator_Console_KillApp($Config_Emulator_Title, $sPackageName) = -1 Then ExitLoop + If _Sleep(2000) Then ExitLoop + If _Emulator_Console_RunApp($Config_Emulator_Title, $sPackageName) = -1 Then ExitLoop + Else + ;Use adb to restart game. + If ADB_Command("shell am force-stop " & $sPackageName) = False Then ExitLoop + If _Sleep(2000) Then ExitLoop + If ADB_Command("shell am start -n " & $sPackageName & "/" & $sActivity) = False Then ExitLoop + EndIf + If _Sleep(10000) Then ExitLoop ResetHandles() - $bOutput = navigate("village", True, 5) + clickPoint(getPointArg("tap")) ; Closes app crash window + + Status("Waiting for game to load.") + Local $sWait = waitLocation("tap-to-start,app-maintenance,app-update", 240, 5000, False, True) ;4 minutes wait + If $sWait <> "$game_not_running" Then + $bOutput = ($sWait == "tap-to-start") + If $bOutput = True Then + ExitLoop + Else + If $sWait == "app-update" Or $sWait == "app-maintenance" Then + ExitLoop ;app-maintenance or app-update + EndIf + EndIf + EndIf + $iAttempt -= 1 WEnd - + $g_bScheduleBusy = $bScheduleBusy $g_bRestarting = False + Log_Add("Restart game result: " & $bOutput, $LOG_DEBUG) Log_Level_Remove() Return $bOutput diff --git a/msl-bot/bin/_src/handlers/Location.au3 b/msl-bot/bin/_src/handlers/Location.au3 index 8617c8c4..3efc7b7d 100644 --- a/msl-bot/bin/_src/handlers/Location.au3 +++ b/msl-bot/bin/_src/handlers/Location.au3 @@ -58,9 +58,9 @@ Func getLocation($bUpdate = True, $bSkipImage = False) ;Image locations, consumes lots of power If TimerDiff($g_hTimer_ImageLocation) > 5000 Then $g_hTimer_ImageLocation = TimerInit() - If $bSkipImage <= 0 And $g_iLocationIndex = -1 Then + If $bSkipImage = False And $g_iLocationIndex = -1 Then ;$g_aImageLocation = [[NAME, 'x,y,w,h,"image"|x,y,w,h,"image"|...'], [...]] - If isArray($g_aImageLocations) > 0 Then + If isArray($g_aImageLocations) = True Then For $i = 0 To UBound($g_aImageLocations)-1 If UBound($g_aImageLocations, 2) <> 2 Then ExitLoop @@ -68,12 +68,12 @@ Func getLocation($bUpdate = True, $bSkipImage = False) Local $aLocationData_Set = StringSplit($g_aImageLocations[$i][1], "|", 2) For $sLocationData In $aLocationData_Set Local $aLocationData = StringSplit($sLocationData, ",", 2) - If isArray($aLocationData) <= 0 And UBound($aLocationData) <> 5 Then ExitLoop + If isArray($aLocationData) = False And UBound($aLocationData) <> 5 Then ExitLoop Local $sImage = StringReplace($aLocationData[4], '"', "") Local $aImage = findImage($sImage, 90, 0, $aLocationData[0], $aLocationData[1], $aLocationData[2], $aLocationData[3], False, True) - If isArray($aImage) > 0 Then + If isArray($aImage) Then $g_sLocation = $sLocation $Location = $sLocation & " (" & getTimeString(TimerDiff($g_hTimerLocation)/1000) & ")" Return $g_sLocation @@ -103,11 +103,18 @@ EndFunc $bReturnBool: If false, returns the location string found. Returns: String or Boolean depending on $bReturnBool #ce -Func waitLocation($vLocations, $iSeconds, $iDelay = 200, $bReturnBool = True) +Func waitLocation($vLocations, $iSeconds, $iDelay = 200, $bReturnBool = True, $bCheckGame = False) Local $bOutput = ($bReturnBool? False : "") Log_Level_Add("waitLocation()") Local $iTimerInit = TimerInit() While TimerDiff($iTimerInit) < $iSeconds*1000 + If $bCheckGame Then + If ADB_isGameRunning() = False Then + $bOutput = "$game_not_running" + ExitLoop + EndIf + EndIf + $bOutput = isLocation($vLocations, $bReturnBool) If ($bOutput) Then ExitLoop @@ -190,13 +197,16 @@ Func setLocation($sLocation, $aData = Null, $bUpdate = True) Else ;Creates local version of the location. This location will be prioritized versus the remote location. Local $sPixelSet = $aLocation - If (StringInStr($sPixelSet, "/")) Then $sPixelSet = StringSplit($sPixelSet, "/", $STR_NOCOUNT)[0] + If (StringInStr($sPixelSet, "/")) Then + $sPixelSet = StringSplit($sPixelSet, "/", $STR_NOCOUNT) + $sPixelSet = $sPixelSet[UBound($sPixelSet) - 1] ;Latest entry + EndIf Local $aPixels = StringSplit($sPixelSet, "|", $STR_NOCOUNT) ReDim $aPoints[UBound($aPixels)][2] For $i = 0 To UBound($aPixels)-1 Local $aPixel = StringSplit($aPixels[$i], ",", $STR_NOCOUNT) - If UBound($aPixel) <> 2 Then Return -1 + If UBound($aPixel) < 2 Then Return SetError(1, 0, False) $aPoints[$i][0] = Int($aPixel[0]) $aPoints[$i][1] = Int($aPixel[1]) diff --git a/msl-bot/bin/_src/handlers/OtherFunctions.au3 b/msl-bot/bin/_src/handlers/OtherFunctions.au3 index 47b19c30..af31b5f7 100644 --- a/msl-bot/bin/_src/handlers/OtherFunctions.au3 +++ b/msl-bot/bin/_src/handlers/OtherFunctions.au3 @@ -30,8 +30,7 @@ Func GetWorkingDirectory($sFullPath) EndFunc Func TestFunction() - CaptureRegion() - ScriptTest_CreateGui("TEST RIGHT NOW", $g_hBitmap) + _ArrayDisplay(rankLocations(10)) EndFunc Func ClipSave_Bitmap() @@ -61,8 +60,45 @@ Func ClipPut_Bitmap(ByRef $hBitmap) Return $bResult EndFunc +Func Compare_Locations($sLocation, $bUpdate = True) + $g_aLocations = getArgsFromFile($g_sLocalOriginalFolder & $g_sLocations) + mergeArgFromTo(getArgsFromFile($g_sLocalDataFolder & $g_sLocations), $g_aLocations) + + Local $sData = "" + For $i = 0 To UBound($g_aLocations)-1 + If $g_aLocations[$i][0] == $sLocation Then + $sData = $g_aLocations[$i][1] + EndIf + Next + If $sData == "" Then + MsgBox(0, "", "FAILED") + Return -1 + EndIf + + Local $aRaw = StringSplit($sData, "/", $STR_NOCOUNT) + Local $sCurrent = "" + + If $bUpdate = True Then CaptureRegion() + For $i = 0 To UBound($aRaw)-1 + $sCurrent &= @CRLF & @CRLF + Local $aSubSet = StringSplit($aRaw[$i], "|", $STR_NOCOUNT) + For $x = 0 To UBound($aSubSet)-1 + Local $aPixel = StringSplit($aSubSet[$x], ",", $STR_NOCOUNT) + $sCurrent &= "|" & $aPixel[0] & "," & $aPixel[1] & "," & compareColors(getColor($aPixel[0], $aPixel[1]), $aPixel[2]) + Next + Next + MsgBox(0, "", $sCurrent) + Return 1 +EndFunc + ;Handles only titan active attack. +Global $g_bTitansFast = False Func Titans_Fast() + Log_Level_Add("Titans_Fast") + Log_Add("Titans Fast has started.", $LOG_INFORMATION) + + $g_bTitansFast = Not($g_bTitansFast) + Local $iColorSP = 0x37BECF Local $iColorNOSP = 0xC0F18 Local $aPoint = CreateArr(545, 42) @@ -71,8 +107,9 @@ Func Titans_Fast() $g_bAntiStuck = False Local $bScheduleBusy = $g_bScheduleBusy - $g_bScheduleBusy = False - While Not(_Sleep(100, True)) + $g_bScheduleBusy = True + While $g_bTitansFast + If _Sleep(100, True) Then ExitLoop CaptureRegion() If isPixel(CreateArr($aPoint[0], $aPoint[1], $iColorSP), 20) = True Then @@ -84,4 +121,27 @@ Func Titans_Fast() WEnd $g_bAntiStuck = $bAntiStuck_Temp $g_bScheduleBusy = $bScheduleBusy + + Log_Add("Titans Fast has stopped.", $LOG_INFORMATION) + Log_Level_Remove() +EndFunc + +Global $g_hHidden = False +Global $g_aHiddenSavePos = Null +Func Toggle_Hidden() + If $g_hWindow = 0 Then Return SetError(1, 0, False) + If $g_hHidden = False Then + MsgBox($MB_ICONINFORMATION+$MB_OK, "Toggle hidden warning", "Hiding the window might not render the game. Check Vision tab to see if the game still renders.") + + $g_aHiddenSavePos = WinGetPos($g_hWindow) + WinMove($g_hWindow, "", -10000, -10000) + Else + WinMove($g_hWindow, 0, $g_aHiddenSavePos[0], $g_aHiddenSavePos[1]) + EndIf + $g_hHidden = Not($g_hHidden) +EndFunc + +Func LoadImage($sImage) + _WinAPI_DeleteObject($g_hBitmap) + $g_hBitmap = _WinAPI_LoadImage(0, @ScriptDir & "\" & $sImage, $IMAGE_BITMAP, 0, 0, $LR_LOADFROMFILE) EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/handlers/Pixel.au3 b/msl-bot/bin/_src/handlers/Pixel.au3 index 28ca4d84..bb85b106 100644 --- a/msl-bot/bin/_src/handlers/Pixel.au3 +++ b/msl-bot/bin/_src/handlers/Pixel.au3 @@ -84,7 +84,7 @@ Func isPixel($vArg, $iVariation = 5, $aMap = $g_aMap) For $i = 0 To UBound($t_aPixelOrSet)-1 $aPixels = splitPixelString($t_aPixelOrSet[$i]) Local $bCompared = comparePixels($aPixels, $iVariation, $aMap) - If $bCompared > 0 Then Return True + If $bCompared > 0 Then Return SetExtended($i, True) Next Return False Else @@ -243,4 +243,103 @@ Func setPixel($sPixels, $aData = Null, $bUpdate = True) mergeArgFromTo(getArgsFromFile($g_sLocalDataFolder & $g_sPixels), $g_aPixels, "/") Return $bOutput +EndFunc + +Func rankLocations($iThreshold = 14) + CaptureRegion() + Local $iLocationSize = UBound($g_aLocations) + Local $aRank[$iLocationSize][3] + For $i = 0 To $iLocationSize - 1 + $aRank[$i][0] = -1 + $aRank[$i][2] = -1 + Next + + For $i = 0 To $iLocationSize - 1 + Local $sName = $g_aLocations[$i][0] + $aRank[$i][1] = $sName + + Local $sData = "/" & $g_aLocations[$i][1] + Local $aPixelSet = StringSplit($sData, "/", $STR_NOCOUNT) + Local $iPixelNum = 0 + For $y = 1 To UBound($aPixelSet) - 1 + Local $iVariation = 0 + Local $iVariation2 = 0 + + Local $sPixelData = $aPixelSet[$y] + Local $aPixels = StringSplit($sPixelData, "|", $STR_NOCOUNT) + Local $iPixelsSize = UBound($aPixels) + For $z = 0 To $iPixelsSize - 1 + $iPixelNum = $iPixelNum + 1 + + Local $sPixel = $aPixels[$z] + Local $aPixel = StringSplit($sPixel, ",", $STR_NOCOUNT) + + Local $iX = $aPixel[0] + Local $iY = $aPixel[1] + Local $iColor = Int($aPixel[2]) + Local $aRGB = _ColorGetRGB($iColor) + + Local $iColor2 = Int(getColor($iX, $iY)) + Local $aRGB2 = _ColorGetRGB($iColor2) + + ;Sum all variations + Local $iRedDifference = Abs($aRGB[0] - $aRGB2[0]) + Local $iGreenDifference = Abs($aRGB[0] - $aRGB2[0]) + Local $iBlueDifference = Abs($aRGB[0] - $aRGB2[0]) + Local $iMax = _Max($iRedDifference, _Max($iGreenDifference, $iBlueDifference)) + Local $iSum = $iRedDifference + $iGreenDifference + $iBlueDifference + Local $iAverage = $iSum / 3 + + If $iAverage <= $iThreshold Then + $iVariation2 = $iVariation + 1 + Abs($iMax - $iThreshold) / _Max($iMax, $iThreshold) + Else + $iVariation2 += Abs($iMax - $iThreshold) / _Max($iMax, $iThreshold) + EndIf + + If $iMax <= $iThreshold Then + $iVariation = $iVariation + 1 + Abs($iMax - $iThreshold) / _Max($iMax, $iThreshold) + Else + $iVariation += Abs($iMax - $iThreshold) / _Max($iMax, $iThreshold) + EndIf + Next + $iVariation = $iVariation / $iPixelsSize + $iVariation2 = $iVariation2 / $iPixelsSize + + If $iVariation > $aRank[$i][0] Or $aRank[$i][0] = -1 Then + $aRank[$i][0] = $iVariation + EndIf + + If $iVariation2 > $aRank[$i][2] Or $aRank[$i][2] = -1 Then + $aRank[$i][2] = $iVariation2 + EndIf + Next + Next + + _ArraySort($aRank, True) + Return $aRank +EndFunc + +Func newLocation($iThreshold = 0.97) + Local $sLocation = "unknown" + + Local $aRank = rankLocations() + $sLocation = $aRank[0][1] + + If $aRank[0][1] == "battle-auto" Then + If $aRank[1][1] == "battle" And $aRank[1][0] >= 0.97 Then + $sLocation = "battle" + EndIf + EndIf + + If $aRank[0][0] < $iThreshold Then + $sLocation = "unknown" + EndIf + + Return $sLocation +EndFunc + +Func testNewLocation() + While (_Sleep(50) = False) + Log_Add(newLocation(), $LOG_INFORMATION) + WEnd EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/handlers/Script.au3 b/msl-bot/bin/_src/handlers/Script.au3 index e6291024..f73165e8 100644 --- a/msl-bot/bin/_src/handlers/Script.au3 +++ b/msl-bot/bin/_src/handlers/Script.au3 @@ -86,35 +86,52 @@ Func Start_Schedule() If StringLeft($g_sScript, 4) == "Farm" Or StringLeft($g_sScript, 6) == "Attack" Then Local $aStructure = "" Local $aAction = "" - If $Hourly_Hourly_Script > 0 Then + If $Hourly_Hourly_Script = True Then $aStructure = CreateArr(CreateArr("*", "*", "*", "00", "*")) $aAction = CreateArr("doHourly()") Schedule_Add("_Hourly", $aAction, $SCHEDULE_TYPE_DATE, "*", $aStructure, $SCHEDULE_FLAG_RunSafe, 60, True, False) EndIf - If $General_Collect_Quests > 0 Then - $aStructure = CreateArr(CreateArr(CreateArr('$g_sLocation = "battle-end"', 'isPixel(getPixelArg("battle-end-quest"), 10, CaptureRegion())')), True) - $aAction = CreateArr("collectQuest()") - Schedule_Add("_Quest", $aAction, $SCHEDULE_TYPE_CONDITION, "*", $aStructure, $SCHEDULE_FLAG_RunSafe, 5, True, False) - EndIf - - If $Guardian_Guardian_Script > 0 Then + If $Guardian_Guardian_Script = True Then $aStructure = CreateArr(TimerInit(), $Guardian_Check_Intervals*60) $aAction = CreateArr('_Schedule_Guardian()') Schedule_Add("_Guardian", $aAction, $SCHEDULE_TYPE_TIMER, "*", $aStructure, $SCHEDULE_FLAG_RunSafe, 0, True, False) EndIf + + ;Scheduled Restart + If $Config_Scheduled_Restart <> $CONFIG_NEVER Then + Local $aRestart = StringSplit($Config_Scheduled_Restart, ":", $STR_NOCOUNT) + If isArray($aRestart) = True And UBound($aRestart) = 2 Then + $aRestart[1] = StringReplace($aRestart[1], "H", "") + $aStructure = CreateArr(TimerInit(), $aRestart[1]*60*60) + If $aRestart[0] == "Game" Then $aAction = CreateArr('Emulator_RestartGame(2)') + If $aRestart[0] == "Emulator" Then $aAction = CreateArr('Emulator_Restart(2)') + Schedule_Add("_Restart", $aAction, $SCHEDULE_TYPE_TIMER, "*", $aStructure, $SCHEDULE_FLAG_RunImmediately, 0, True, False) + EndIf + EndIf + + ;App maintenance and and app update + $aStructure = CreateArr(CreateArr(CreateArr('$g_sLocation == "app-maintenance"')), True) + $aAction = CreateArr('appMaintenance()') + Schedule_Add("_Maintenance", $aAction, $SCHEDULE_TYPE_CONDITION, "*", $aStructure, $SCHEDULE_FLAG_RunImmediately, 0, True, False) + + $aStructure = CreateArr(CreateArr(CreateArr('$g_sLocation == "app-update"')), True) + $aAction = CreateArr('appUpdate()') + Schedule_Add("_Update", $aAction, $SCHEDULE_TYPE_CONDITION, "*", $aStructure, $SCHEDULE_FLAG_RunImmediately, 0, True, False) EndIf EndFunc Func _Schedule_Stop() Schedule_RemoveByName("_Hourly") - Schedule_RemoveByName("_Quest") Schedule_RemoveByName("_Guardian") + Schedule_RemoveByName("_Restart") + Schedule_RemoveByName("_Maintenance") + Schedule_RemoveByName("_Update") EndFunc Func _Schedule_Guardian() Local $aValues = Stats_Values_GetSpecific(Stats_GetValues($g_aStats), CreateArr("Guardians", "Astrogems_Used")) - Local $aParam = CreateArr($Guardian_Guardian_Mode, IsDeclared($g_sScript & "_Refill")?Eval($g_sScript & "_Refill"):0, 0, $Guardian_Target_Boss) + Local $aParam = CreateArr($Guardian_Guardian_Mode, IsDeclared($g_sScript & "_Refill")?Eval($g_sScript & "_Refill"):0, $CONFIG_NEVER, $Guardian_Target_Boss) _RunScript("Farm_Guardian", $aParam, $aValues) navigate("map") @@ -129,6 +146,7 @@ Func Stop() $g_hScriptTimer = Null $g_sScript = "" $g_bAntiStuck = False + $g_bTitansFast = False ;Removing Schedules _Schedule_Stop() @@ -323,30 +341,6 @@ Func ScriptTest() Return "COMPLETE" EndFunc -Global $g_hCompatibilityTest = Null -Func ScriptTest_CreateGui($sMessage, ByRef $hBitmap) - If $g_hCompatibilityTest <> Null Then Return SetError(1, 0, False) - $g_hCompatibilityTest = GUICreate("MSL-Bot Compatibility Test", 823, 367, -1, -1, -1, -1, $g_hParent) - Global $g_idCompatibilityTest_editMain = GUICtrlCreateEdit($sMessage, 10, 10, 296, 307, $WS_VSCROLL, -1) - Global $g_idCompatibilityTest_picMain = GUICtrlCreatePic("", 309, 10, 507, 350, -1, -1) - Global $g_idCompatibilityTest_btnClose = GUICtrlCreateButton("Close", 260, 330, 46, 30, -1, -1) - Global $g_idCompatibilityTest_btnCopyText = GUICtrlCreateButton("Copy Text", 10, 330, 80, 30, -1, -1) - Global $g_idCompatibilityTest_btnCopyImage = GUICtrlCreateButton("Copy as Image", 96, 330, 160, 30, -1, -1) - - GUISetState(@SW_SHOW, $g_hCompatibilityTest) - - Local $tagSize = _WinAPI_GetBitmapDimension($hBitmap) - Local $aImageSize = [DllStructGetData($tagSize, 'X'), DllStructGetData($tagSize, 'Y')] - If $aImageSize[0] = 0 Or $aImageSize[1] = 0 Then Return SetError(2, 0, False) - - Local $hAdjusted = _WinAPI_AdjustBitmap($hBitmap, 507, 350) - - _WinAPI_DeleteObject(GUICtrlSendMsg($g_idCompatibilityTest_picMain, $STM_SETIMAGE, $IMAGE_BITMAP, $hAdjusted)) - _WinAPI_DeleteObject($hAdjusted) - - Return $g_hCompatibilityTest -EndFunc - Func ScriptTest_Handles() Log_Level_Add("Checking Handles") Log_Add("Window Title: " & $Config_Emulator_Title, $LOG_DEBUG) diff --git a/msl-bot/bin/_src/handlers/System.au3 b/msl-bot/bin/_src/handlers/System.au3 index 6e5b8821..23123e18 100644 --- a/msl-bot/bin/_src/handlers/System.au3 +++ b/msl-bot/bin/_src/handlers/System.au3 @@ -33,17 +33,18 @@ Func _Sleep($iDuration = 0, $bPrecise = False) $g_hTimerLocation = Null Return True EndIf - If $bPrecise = False Then Sleep(50) + If $bPrecise = False Then Sleep(5) Until (TimerDiff($hTimer) > $iDuration) Return False EndFunc Func _AntiStuck() - If $g_bAntiStuck = 0 Then Return True + If $g_bAntiStuck = False Or $g_bRestarting = True Then Return True Log_Level_Add("_AntiStuck") Local $bOutput = False - - If $Config_Screen_Frozen_Check > 0 Then + + $g_bAntiStuck = False + If $Config_Screen_Frozen_Check <> $CONFIG_NEVER Then If Mod(Int(TimerDiff($g_hScriptTimer)/1000)+1, $Config_Screen_Frozen_Check) = 0 And TimerDiff($g_hGameCheckCD) > 2000 Then $g_hGameCheckCD = TimerInit() If _AntiStuck_Frozen() = True Then @@ -54,20 +55,8 @@ Func _AntiStuck() EndIf EndIf EndIf - - ;If Mod(Int(TimerDiff($g_hScriptTimer)/1000)+1, 30) = 0 And TimerDiff($g_hGameCheckCD) > 2000 Then - ; $g_hGameCheckCD = TimerInit() - ; If ADB_isWorking() > 0 And ADB_IsGameRunning() <= 0 Then - ; Log_Add("AntiStuck: Game is not running. Restarting Game.", $LOG_ERROR); - - ; $bOutput =_AntiStuck_Restart() - ; If $bOutput <= 0 Then Stop() - ; EndIf - - ;EndIf - ;AntiStuck sequence - If $Config_Location_Stuck_Timeout > 0 Then + If $Config_Location_Stuck_Timeout <> $CONFIG_NEVER Then If $g_hTimerLocation <> Null Then If TimerDiff($g_hTimerLocation) > (60000 * $Config_Location_Stuck_Timeout) Then $g_hTimerLocation = Null @@ -81,6 +70,17 @@ Func _AntiStuck() EndIf EndIf + IF $Config_ADB_Game_Check <> $CONFIG_NEVER And $g_sLocation == "unknown" Then + If Mod(Int(TimerDiff($g_hScriptTimer)/1000), $Config_ADB_Game_Check) = 0 Then + If ADB_isGameRunning() = False Then + Log_Add("AntiStuck: Game is not running. Restarting Game.", $LOG_ERROR) + $bOutput =_AntiStuck_Restart() + If $bOutput = False Then Stop() + EndIf + EndIf + EndIf + $g_bAntiStuck = True + Log_Level_Remove() Return $bOutput EndFunc @@ -107,8 +107,8 @@ EndFunc Func _AntiStuck_Restart() Local $bOutput = True - If Emulator_RestartGame(3) <= 0 Then - If Emulator_Restart(3) <= 0 Then + If Emulator_RestartGame(3) = False Then + If Emulator_Restart(3) = False Then Log_Add("AntiStuck: Could not restart emulator.", $LOG_ERROR) $bOutput = False EndIf @@ -180,7 +180,7 @@ Func _ProcessLines($aLines, $bDisplayArray = True, $bLog = True) Local $sResult = Execute($aLines[$i]) If (@error) Then - If $bLog Then Log_Add("ERROR <= " & $aLines[$i], $LOG_INFORMATION) + If $bLog Then Log_Add("ERROR (" & @error & "," & @extended & ") <= " & $aLines[$i], $LOG_INFORMATION) ContinueLoop EndIf diff --git a/msl-bot/bin/_src/imports.au3 b/msl-bot/bin/_src/imports.au3 index 97c210b7..cb3ec0ef 100644 --- a/msl-bot/bin/_src/imports.au3 +++ b/msl-bot/bin/_src/imports.au3 @@ -70,6 +70,7 @@ #include "scripts/Farm_Guardian.au3" #include "scripts/Farm_Starstone.au3" +#include "scripts/sub/doExpedition.au3" #include "scripts/sub/helper.au3" #include "scripts/sub/handlers.au3" #include "scripts/sub/navigate.au3" diff --git a/msl-bot/bin/_src/scripts/Farm_Golem.au3 b/msl-bot/bin/_src/scripts/Farm_Golem.au3 index 42dcb46b..b89fc006 100644 --- a/msl-bot/bin/_src/scripts/Farm_Golem.au3 +++ b/msl-bot/bin/_src/scripts/Farm_Golem.au3 @@ -2,7 +2,7 @@ Func Farm_Golem($bParam = True, $aStats = Null) If $bParam > 0 Then Config_CreateGlobals(formatArgs(Script_DataByName("Farm_Golem")[2]), "Farm_Golem") - ;Runs, Dungeon Level, Refill, Gold Goal, Target Boss + ;Runs, Dungeon Level, Filter, Refill, Gold Goal, Target Boss Log_Level_Add("Farm_Golem") @@ -107,9 +107,13 @@ Func Farm_Golem($bParam = True, $aStats = Null) Status("Found egg x" & $Eggs_Found) Cumulative_AddNum("Resource Collected (Egg)", 1) Case Else - If filterGem($aGem) <= 0 Then + Local $sFilter = filterGem($aGem, $Farm_Golem_Filter) + If $sFilter = False Then $bSold = True clickPoint(getPointArg("battle-sell-item-sell")) + _GemWindow_AddFound($aGem, "Sold") + Else + _GemWindow_AddFound($aGem, "Kept (" & $sFilter & ")") EndIf If $bSold = 0 Then diff --git a/msl-bot/bin/_src/scripts/Farm_Guardian.au3 b/msl-bot/bin/_src/scripts/Farm_Guardian.au3 index 640a789f..2f9cccb5 100644 --- a/msl-bot/bin/_src/scripts/Farm_Guardian.au3 +++ b/msl-bot/bin/_src/scripts/Farm_Guardian.au3 @@ -30,13 +30,12 @@ Func Farm_Guardian($bParam = True, $aStats = Null) While $g_bRunning = True If _Sleep($Delay_Script_Loop) Then ExitLoop - If $bIdle > 0 Then - If $Farm_Guardian_Idle_Time = 0 Then ExitLoop + If $bIdle = True Then + If $Farm_Guardian_Idle_Time = $CONFIG_NEVER Then ExitLoop $g_hTimerLocation = Null If getLocation() <> "village" Then navigate("village") - If $Farm_Guardian_Idle_Time = 0 Then ExitLoop If $hIdle = Null Then $hIdle = TimerInit() Local $iSeconds = $Farm_Guardian_Idle_Time*60 - Int((TimerDiff($hIdle)/1000)) diff --git a/msl-bot/bin/_src/scripts/sub/catch.au3 b/msl-bot/bin/_src/scripts/sub/catch.au3 index 96564455..23c7c989 100644 --- a/msl-bot/bin/_src/scripts/sub/catch.au3 +++ b/msl-bot/bin/_src/scripts/sub/catch.au3 @@ -20,6 +20,8 @@ Func catch($aImages, $iAstrochips = -1, $iMaxCatch = -1, $bSaveMissed = True) Local $aPoints[0] Local $hTimer = TimerInit() Log_Add("Trying to catch " & _ArrayToString($aImages, ",") & (($iMaxCatch <> -1)?", Max: " & $iMaxCatch & ".":"."), $LOG_DEBUG) + $g_bCaptureQuest = True ; Trigger quest + While TimerDiff($hTimer) < 60000 If _Sleep(100) Then ExitLoop @@ -47,7 +49,7 @@ Func catch($aImages, $iAstrochips = -1, $iMaxCatch = -1, $bSaveMissed = True) Next EndIf - If isArray($aPoints) > 0 And $iCurrent <> -1 Then + If UBound($aPoints) > 0 And $iCurrent <> -1 Then #cs If $bScreenshot = False And clickUntil("737,123", "isLocation", "battle,battle-auto", 3, 500) Then $bScreenshot = True @@ -73,7 +75,25 @@ Func catch($aImages, $iAstrochips = -1, $iMaxCatch = -1, $bSaveMissed = True) SendBack(2, 100) clickPoint(getPointArg("battle-continue"), 3, 200) - clickUntil(getPointArg("tap"), "isLocation", "catch-mode,catch-success,battle-auto,battle", 50, 100) + ;Local $iCounter = 0 + ;While (FileExists(@ScriptDir & "\legendary" & $iCounter & ".bmp")) + ; $iCounter += 1 + ;WEnd + + Local $hTempTimer = TimerInit() + While(isLocation("catch-mode,catch-success,battle-auto,battle") = False) + clickPoint(getPointArg("tap")) + + If _Sleep(100) Then ExitLoop(2) + If TimerDiff($hTempTimer) > 7000 Then ExitLoop + + ; If ($aPoints[$iCurrent])[2] == "legendary" Then + ; CaptureRegion(($aPoints[$iCurrent])[2] & $iCounter) + ; $iCounter += 1 + ; EndIf + WEnd + + ;clickUntil(getPointArg("tap"), "isLocation", "catch-mode,catch-success,battle-auto,battle", 50, 100) Else Log_Add("Could not detect catch status", $LOG_ERROR) _ArrayDelete($aPoints, $iCurrent) diff --git a/msl-bot/bin/_src/scripts/sub/doExpedition.au3 b/msl-bot/bin/_src/scripts/sub/doExpedition.au3 new file mode 100644 index 00000000..3b4ab23b --- /dev/null +++ b/msl-bot/bin/_src/scripts/sub/doExpedition.au3 @@ -0,0 +1,103 @@ +#include-once + +Func doExpedition() + Log_Level_Add("doExpedition") + Local $bResult = False + + Local $iCounter = 1 + Local $hTimer = TimerInit() + While TimerDiff($hTimer) < 120000 + If _Sleep($Delay_Script_Loop) Then ExitLoop + Local $sLocation = getLocation() + Switch $sLocation + Case "expedition" + Log_Add("Searching for an expedition.") + Local $aPoint = Expedition_FindExplore() + If isArray($aPoint) > 0 Then + clickPoint($aPoint) + waitLocation("expedition-explore", 5) + Else + Log_Add("Expedition Complete.") + $bResult = True + ExitLoop + EndIf + Case "expedition-cancel" + closeWindow() + Case "expedition-explore" + Select + Case findImage("expedition-complete", 90, 0, 609, 399, 180, 132) <> -1 + clickPoint("702,463") + Case findImage("expedition-unknown") <> -1 + clickPoint("705,401") + Case findImage("expedition-explore", 90, 0, 609, 399, 180, 132) <> -1 + If isPixel("399,248,0x7D624D") > 0 Then clickPoint(getPointArg("expedition-autoselect")) + + clickPoint(getPointArg("expedition-explore")) + If _Sleep(2000) Then ExitLoop + Case findImage("expedition-exploring", 90, 0, 609, 399, 180, 132) <> -1 + Cumulative_AddNum("Collected (Expedition)", 1) + Log_Add("Explored expedition x" & $iCounter, $LOG_INFORMATION) + $iCounter += 1 + + navigate("expedition") + Case Else + clickPoint("705,401") + EndSelect + Case "refill" + doRefill() + Case "map" + navigate("expedition", True) + Case "unknown" + If waitLocation("expedition,expedition-explore", 2) <= 0 And isPixel("399,109,0xBBB6E5/357,142,0xF5DE06", 10, CaptureRegion()) > 0 Then + clickPoint("698,380") + Else + ContinueCase + EndIf + Case Else + If HandleCommonLocations($sLocation) = 0 And $sLocation <> "unknown" Then + If waitLocation("expedition,expedition-explore", 2) = 0 Then + If navigate("expedition", True, 2) = 0 Then + ExitLoop + EndIf + EndIf + EndIf + EndSwitch + WEnd + navigate("village") + + Log_Level_Remove() + Return $bResult +EndFunc + +Func Expedition_FindExplore() + Local $aOutput = -1 ;End with point for explore/complete button + Local Const $SWIPE = [675,169,375,169] ;Swipe Left + + If getLocation() <> "expedition" Then + If navigate("expedition", True, 2) = 0 Then Return $aOutput + EndIf + + Local $hTimer = TimerInit() + Local $aPoint[2] = [Null, Null] + While TimerDiff($hTimer) < 20000 + CaptureRegion() + Local $aPoints = findImageMultiple("expedition-explored", 90, 10, 10, 3, 185, 427, 615, 100, False) + If $aPoints <> -1 Then + For $i = 0 To UBound($aPoints)-1 + If isPixel(CreateArr($aPoints[$i][0], 364, 0x203909), 5, CaptureRegion()) = 0 Then + $aPoint[0] = $aPoints[$i][0] + $aPoint[1] = $aPoints[$i][1] + ExitLoop(2) + EndIf + Next + EndIf + + If findImage("expedition-end", 90, 0, 404, 147, 400, 50) <> -1 Then ExitLoop + clickDrag($SWIPE) + If _Sleep(1500) Then ExitLoop + WEnd + + If $aPoint[0] <> Null Then $aOutput = $aPoint + + Return $aOutput +EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/scripts/sub/doHourly.au3 b/msl-bot/bin/_src/scripts/sub/doHourly.au3 index b09661ad..29d1e1d5 100644 --- a/msl-bot/bin/_src/scripts/sub/doHourly.au3 +++ b/msl-bot/bin/_src/scripts/sub/doHourly.au3 @@ -5,7 +5,7 @@ Func doHourly() Log_Add("Performing hourly tasks") Local $hTimer = TimerInit() - Local $aTurn = ["Collect_Hiddens", "Click_Nezz"] + Local $aTurn = ["Collect_Hiddens", "Collect_Inbox", "Click_Nezz", "Expedition"] For $i = 0 To UBound($aTurn)-1 If _Sleep(100) Then ExitLoop @@ -26,9 +26,9 @@ EndFunc Func Close_Village_Interface() CaptureRegion() - If isPixel(getPixelArg("village-missions-popup")) = True Then clickPoint(getPointArg("village-missions-popup-close")) - If isPixel(getPixelArg("village-events")) = True Then clickPoint(getPointArg("village-events-close")) - If isPixel(getPixelArg("village-pack")) = True Then clickPoint(getPointArg("village-pack-close")) + If isPixel(getPixelArg("village-missions-popup"), 30) = True Then clickPoint(getPointArg("village-missions-popup-close"), 2) + If isPixel(getPixelArg("village-events"), 30) = True Then clickPoint(getPointArg("village-events-close"), 2) + If isPixel(getPixelArg("village-pack"), 30) = True Then clickPoint(getPointArg("village-pack-close"), 2) EndFunc Func Get_Village_Pos() @@ -125,4 +125,29 @@ Func Click_Nezz() EndIf Return False +EndFunc + +Func Collect_Inbox() + Log_Add("Collecting inbox.") + + If navigate("inbox", False, 3) > 0 Then + If isPixel(getPixelArg("inbox-accept-all"), 10, CaptureRegion()) > 0 Then + clickPoint(getPixelArg("inbox-accept-all"), 3) + waitLocation("unknown", 5) + clickPoint(getPointArg("inbox-confirm"), 3) + EndIf + EndIf + + If navigate("friend-gifts", False, 3) > 0 Then + If isPixel(getPixelArg("inbox-accept-all"), 10, CaptureRegion()) > 0 Then + clickPoint(getPixelArg("inbox-accept-all"), 3) + EndIf + EndIf + + navigate("village") + Return True +EndFunc + +Func Expedition() + Return doExpedition() EndFunc \ No newline at end of file diff --git a/msl-bot/bin/_src/scripts/sub/enterBattle.au3 b/msl-bot/bin/_src/scripts/sub/enterBattle.au3 index 42bd6d18..b73ccd8c 100644 --- a/msl-bot/bin/_src/scripts/sub/enterBattle.au3 +++ b/msl-bot/bin/_src/scripts/sub/enterBattle.au3 @@ -16,6 +16,22 @@ Func enterBattle() clickPoint(getPointArg("map-battle-play")) waitLocation("loading,unknown,refill", 5) Case "battle-end" + If $General_Collect_Quests = True And isPixel(getPixelArg("battle-end-quest"), 10) Then + If $General_Collect_Quests == "Only On Capture" Then + If $g_bCaptureQuest = True Then + $g_bCaptureQuest = False + + Log_Add("Capture and quest detected, collecting quests.", $LOG_INFORMATION) + collectQuest() + ExitLoop + EndIf + Else + Log_Add("Completed quests detected, collecting quests.", $LOG_INFORMATION) + collectQuest() + ExitLoop + EndIf + EndIf + If TimerDiff($hTimer) > 15000 Then clickPoint("99,261") If _Sleep(500) Then ExitLoop diff --git a/msl-bot/bin/_src/scripts/sub/enterStage.au3 b/msl-bot/bin/_src/scripts/sub/enterStage.au3 index e793727a..e8f8ca5a 100644 --- a/msl-bot/bin/_src/scripts/sub/enterStage.au3 +++ b/msl-bot/bin/_src/scripts/sub/enterStage.au3 @@ -67,11 +67,6 @@ Func enterStage($sMap, $sDifficulty = "Normal", $sStage = "Exp") Case "refill" ExitLoop Case "map-battle" - If isPixel(getPixelArg("map-battle-autofill-on"), 20, CaptureRegion()) <= 0 Then - clickPoint(getPointArg("astrochips-refill")) - ContinueLoop - EndIf - enterBattle() Case "autobattle-prompt", "popup-window" closeWindow() diff --git a/msl-bot/bin/_src/scripts/sub/handlers.au3 b/msl-bot/bin/_src/scripts/sub/handlers.au3 index 83852258..2a954702 100644 --- a/msl-bot/bin/_src/scripts/sub/handlers.au3 +++ b/msl-bot/bin/_src/scripts/sub/handlers.au3 @@ -24,12 +24,10 @@ Func HandleCommonLocations($sCurrLocation) _Sleep(100) Return True Case "app-maintenance" - appMaintenance() - Return True + Return SetExtended(1, True) Case "app-update" - appUpdate() - Return True - Case "another-device0" + Return SetExtended(2, True) + Case "another-device" anotherDevice() Return True Case "dragon-dungeons-popup", "dragon-astral-essence", "exotic-ticket-claim" @@ -37,7 +35,7 @@ Func HandleCommonLocations($sCurrLocation) Case "monsters" clickUntil(getPointArg("monsters-grid"), "isPixel", CreateArr("133,30,0xF6C02A"), 5, 200, "CaptureRegion()") clickUntil(getPointArg("monsters-recent"), "isPixel", CreateArr("265,473,0x45F5A7"), 5, 200, "CaptureRegion()") - Case "association-expedition" + Case "expedition" clickPoint("698,380") Case "map-limit" clickPoint(findImage("misc-ok")) diff --git a/msl-bot/bin/_src/scripts/sub/helper.au3 b/msl-bot/bin/_src/scripts/sub/helper.au3 index 0bf841bc..c413e666 100644 --- a/msl-bot/bin/_src/scripts/sub/helper.au3 +++ b/msl-bot/bin/_src/scripts/sub/helper.au3 @@ -8,75 +8,99 @@ - If one of the items are missing then return -1 #ce Func getGemData($bCapture = True) - Local $aGemData[6] = ["-", "-", "-", "-", "-", "-"] ;Stores current gem data - If (isLocation("battle-sell-item")) Then - Select ;grade - Case isPixel(getPixelArg("battle-item-egg"), 20) - $aGemData[0] = "EGG" - Return $aGemData - Case isPixel(getPixelArg("battle-item-gold"), 20) - $aGemData[0] = "GOLD" - Return $aGemData - Case isPixel("406,144,0x261612") - $aGemData[0] = 1 - Case isPixel("413,144,0x261612") - $aGemData[0] = 2 - Case isPixel("418,144,0x261612") - $aGemData[0] = 3 - Case isPixel("423,144,0x261612") - $aGemData[0] = 4 - Case isPixel("428,144,0x261714") - $aGemData[0] = 5 - Case Else - $aGemData[0] = 6 - EndSelect - - Select ;shape - Case Not(isPixel("413,159,0x261612")) - $aGemData[1] = "S" - Case Not(isPixel("414,168,0x261612")) - $aGemData[1] = "D" - Case Else - $aGemData[1] = "T" - EndSelect - - For $strType In $g_aGem_pixelTypes ;types - Local $sType = StringSplit($strType, ":", 2) - If (isPixel($sType[1], 20)) Then - $aGemData[2] = $sType[0] - ExitLoop - EndIf - Next - - For $strStat In $g_aGem_pixelStats ;main stats - Local $aStat = StringSplit($strStat, ":", 2) - If (isPixel($aStat[1], 20)) Then - $aGemData[3] = $aStat[0] - ExitLoop - EndIf - Next + Local $aGemData[7] = ["-", "-", "-", "-", "-", "-", "-"] ;Stores current gem data + CaptureRegion() + Select ;grade + Case isPixel(getPixelArg("battle-item-egg"), 20) + $aGemData[0] = "EGG" + Return $aGemData + Case isPixel(getPixelArg("battle-item-gold"), 20) + $aGemData[0] = "GOLD" + Return $aGemData + Case isPixel("406,144,0x261612") + $aGemData[0] = 1 + Case isPixel("413,144,0x261612") + $aGemData[0] = 2 + Case isPixel("418,144,0x261612") + $aGemData[0] = 3 + Case isPixel("423,144,0x261612") + $aGemData[0] = 4 + Case isPixel("428,144,0x261714") + $aGemData[0] = 5 + Case Else + $aGemData[0] = 6 + EndSelect + + Select ;shape + Case Not(isPixel("413,159,0x261612")) + $aGemData[1] = "S" + Case Not(isPixel("414,168,0x261612")) + $aGemData[1] = "D" + Case Else + $aGemData[1] = "T" + EndSelect - If (isArray(findColor("350,329", "50,1", "0xE9E3DE", 20))) Then ;number of substats - $aGemData[4] = "4" - ElseIf (isArray(findColor("350,311", "50,1", "0xE9E3DE", 20))) Then - $aGemData[4] = "3" - ElseIf (isArray(findColor("350,296", "50,1", "0xE9E3DE", 20))) Then - $aGemData[4] = "2" - ElseIf (isArray(findColor("350,329", "50,1", "0xE9E3DE", 20))) Then - $aGemData[4] = "1" + For $strType In $g_aGem_pixelTypes ;types + Local $sType = StringSplit($strType, ":", 2) + If (isPixel($sType[1], 20)) Then + $aGemData[2] = $sType[0] + ExitLoop EndIf + Next - ;Handles if gem is unknown - If (($aGemData[0] == "-") Or ($aGemData[1] == "-") Or ($aGemData[2] == "-") Or ($aGemData[3] == "-") Or ($aGemData[4] == "-")) Then - $g_sErrorMessage = "getGemData() => Something is missing: " & _ArrayToString($aGemData) - Return -1 + For $strStat In $g_aGem_pixelStats ;main stats + Local $aStat = StringSplit($strStat, ":", 2) + If (isPixel($aStat[1], 20)) Then + $aGemData[3] = $aStat[0] + ExitLoop EndIf + Next - $aGemData[5] = getGemPrice($aGemData) + If (isArray(findColor("350,329", "50,1", "0xE9E3DE", 20))) Then ;number of substats + $aGemData[4] = "4" + ElseIf (isArray(findColor("350,311", "50,1", "0xE9E3DE", 20))) Then + $aGemData[4] = "3" + ElseIf (isArray(findColor("350,296", "50,1", "0xE9E3DE", 20))) Then + $aGemData[4] = "2" + ElseIf (isArray(findColor("350,329", "50,1", "0xE9E3DE", 20))) Then + $aGemData[4] = "1" EndIf + + ;Handles if gem is unknown + If (($aGemData[0] == "-") Or ($aGemData[1] == "-") Or ($aGemData[2] == "-") Or ($aGemData[3] == "-") Or ($aGemData[4] == "-")) Then + Return SetError(1, 0, -1) + EndIf + + $aGemData[5] = getGemPrice($aGemData) + $aGemData[6] = getGemSubs() + Return $aGemData EndFunc +Func getGemSubs() + Local Const $aSubstats = ["attack", "critdmg", "critrate", "defense", "hp", "recovery", "resist"] + Local $aSubFound[0] + + Local $aPercentages = findImageMultiple("gem-percent", 85, 5, 5, 4, 322, 266, 461-322, 344-266) + For $sSubstat in $aSubstats + Local $aFind = findImageMultiple("gem-" & $sSubstat, 85, 5, 5, 2, 322, 266, 461-322, 344-266) + For $i = 0 To UBound($aFind)-1 + Local $bPercent = False + For $x = 0 To UBound($aPercentages)-1 + If Abs($aFind[$i][1] - $aPercentages[$x][1]) <= 5 Then + _ArrayDelete($aPercentages, $x) + $bPercent = True + ExitLoop + EndIf + Next + _ArrayAdd($aSubFound, $sSubstat & (($bPercent)?"%":"+")) + If UBound($aSubFound) = 4 Then ExitLoop(2) + Next + Next + + Return $aSubFound +EndFunc + #cs Function: Returns gem price using the data passed in Parameters: @@ -119,7 +143,7 @@ EndFunc Returns: If the gem meets the criteria returns true; otherwise, returns false. #ce -Func filterGem($aGemData, $bCheckDragonGems = False) +Func old_filterGem($aGemData, $bCheckDragonGems = False) If ($bCheckDragonGems And StringInStr("leech,pugilist,siphon", $aGemData[2])) Then Local $iGrade = $aGemData[0] Local $t_bFilter = Eval("DragonFilter_" & $iGrade & "_Star_Filter") @@ -139,6 +163,204 @@ Func filterGem($aGemData, $bCheckDragonGems = False) Return True EndFunc +;Return name of filter that passes it +;Return false if it does not pass filter +Func filterGem($aGemData, $aFilters) + If isArray($aFilters) = False Then $aFilters = StringSplit($aFilters, ",", $STR_NOCOUNT) + If isArray($aFilters) = False Then $aFilters = CreateArr($aFilters) + + For $i = 0 To UBound($aFilters)-1 + Local $sFilter = $aFilters[$i] + If ($sFilter <> "_Filter") And FileExists($g_sFilterFolder & $sFilter) = False Then + Log_Add("Filter does not exist: " & $sFilter, $LOG_ERROR) + ContinueLoop + EndIf + + Local $bResult = _filterGem($aGemData, $sFilter) + If @error = 0 Then + If $bResult = True Then Return $sFilter + Else + Local $iError = @error + Log_Add("Filter did not work: " & $FILTERGEM_ERROR_STRING[$iError], $LOG_ERROR) + Return SetError(1, $iError, "Error") + EndIf + Next + + Return False +EndFunc + +Global $FILTERGEM_ERROR_STRING = _ + ["No error.", _ + "Invalid gem data.", _ + "Unable to parse gem data.", _ + "Could not get filter data.", _ + "Invalid filter data.", _ + "Invalid filter value."] +Func _filterGem($aGemData, $sFilter) + If isArray($aGemData) = False Or UBound($aGemData) <> 7 Then Return SetError(1, 0, True) ;Invalid gem data. + + If $sFilter == "_Filter" Then + Return old_filterGem($aGemData, True) + Else + Local $aGem = Null + If UBound($aGemData) = 7 Then $aGem = parseGem($aGemData) + ;_ArrayDisplay($aGem) + IF isArray($aGem) = False Or UBound($aGem) <> 8 Then Return SetError(2, 0, True) ;Invalid gem data. + + Local $aCurrentSub[0] + For $i = 4 To 7 + If $aGem[$i] <> "" Then _ArrayAdd($aCurrentSub, $aGem[$i]) + Next + + Local $aFilter = getFilter($sFilter) + If @error Then + Return SetError(3, @error, True) ;Could not get filter + EndIf + + Local $aFilterSub[0] + For $x = 0 To UBound($aFilter)-1 + Local $aData = StringSplit($aFilter[$x], ":", $STR_NOCOUNT) + If isArray($aData) = False Or UBound($aData) <> 2 Then Return SetError(4, 0, True) ;Invalid filter + + $aData[0] = StringLower(StringStripWS($aData[0], $STR_STRIPALL)) + $aData[1] = StringLower(StringStripWS($aData[1], $STR_STRIPALL)) + If StringInStr($aData[1], ",") Then + $aData[1] = StringSplit($aData[1], ",", $STR_NOCOUNT) + Else + $aData[1] = CreateArr($aData[1]) + EndIf + + Local $sType = $aData[0] + Local $aValue = $aData[1] + If isArray($aValue) = False Or UBound($aValue) = 0 Then Return SetError(5, 0, True) ;Invalid value + + Local $sCurrent = $aGem[Eval("GEM_PARSED_" & StringUpper($sType))] + Switch $aData[0] + Case "grade", "shape", "type" + If $aValue[0] == "any" Then ContinueLoop ;Accepts any of that data type + Local $aFind = _ArrayFindAll($aValue, $sCurrent) + If isArray($aFind) = False Then Return SetExtended(1, False) ;Not Found + Case "stat" + If $aValue[0] == "any" Then ContinueLoop ;Accepts any of that data type + Local $aFind = _ArrayFindAll($aValue, $sCurrent) + If isArray($aFind) = False Then $aFind = _ArrayFindAll($aValue, StringMid($sCurrent, 1, StringLen($sCurrent) - 1)) + If isArray($aFind) = False Then + Local $bFound = False + Local $aFindP = _ArrayFindAll($aValue, "any%") + Local $aFindF = _ArrayFindAll($aValue, "any+") + + If isArray($aFindP) = True And StringRight($sCurrent, 1) == "%" Then $bFound = True + If $bFound = False And (isArray($aFindF) And StringRight($sCurrent, 1) == "+") Then $bFound = True + + If $bFound = False Then Return SetExtended(2, False) + EndIf + Case Else ;handles substats + _ArrayAdd($aFilterSub, $aValue, 0, "|", @CRLF, $ARRAYFILL_FORCE_SINGLEITEM) + EndSwitch + Next + + ;handle substats + If UBound($aCurrentSub) < UBound($aFilterSub) Then Return SetExtended(3, False) ;minimum substat + + Local $aPermutedCurrent = _ArrayPermute($aCurrentSub, "|") + Local $bFits = False ;Fits filter + For $z = 1 To $aPermutedCurrent[0] + $aCurrentSub = StringSplit($aPermutedCurrent[$z], "|", $STR_NOCOUNT) + If isArray($aCurrentSub) = False Then $aCurrentSub = CreateArr($aPermutedCurrent[$z]) + + Local $aFilterSub_Inner = $aFilterSub + For $x = UBound($aCurrentSub)-1 To 0 Step -1 + Local $sSub = $aCurrentSub[$x] + Local $bFound = False + For $y = 0 To UBound($aFilterSub_Inner)-1 + Local $aSub = $aFilterSub_Inner[$y] + If $aSub[0] == "any" Then + $bFound = True + ExitLoop + EndIf + + Local $aFind = _ArrayFindAll($aSub, $sSub) + If isArray($aFind) = False Then $aFind = _ArrayFindAll($aSub, StringMid($sSub, 1, StringLen($sSub)-1)) + If isArray($aFind) = False Then + Local $aFindP = _ArrayFindAll($aSub, "any%") + Local $aFindF = _ArrayFindAll($aSub, "any+") + + If isArray($aFindP) = True And StringRight($sSub, 1) == "%" Then $bFound = True + If $bFound = False And (isArray($aFindF) = True And StringRight($sSub, 1) == "+") Then $bFound = True + Else + $bFound = True + EndIf + + If $bFound = True Then ExitLoop + Next + + If UBound($aFilterSub_Inner) > 0 And $bFound = True Then + _ArrayDelete($aFilterSub_Inner, $y) + _ArrayDelete($aCurrentSub, $x) + EndIf + Next + + If UBound($aFilterSub_Inner) = 0 Then + $bFits = True + ExitLoop + EndIf + Next + + If $bFits = False Then Return SetExtended(4, False) + EndIf + + Return SetExtended(1, True) ;Fits the criteria +EndFunc + +Func getFilter($sFilter) + Local $sContent = FileRead($g_sFilterFolder & $sFilter) + If @error Then Return SetError(1, 0, False) + If _GemWindow_isValid($sContent) = False Then SetError(2, @error, False) + + Local $aFilter = StringSplit($sContent, @CRLF, $STR_NOCOUNT) + For $i = UBound($aFilter)-1 To 0 Step -1 + If $aFilter[$i] == "" Then _ArrayDelete($aFilter, $i) + Next + + Return $aFilter +EndFunc + +Global Const $GEM_PARSED_GRADE = 0, $GEM_PARSED_SHAPE = 1, $GEM_PARSED_TYPE = 2, $GEM_PARSED_STAT = 3, _ + $GEM_PARSED_SUB1 = 4, $GEM_PARSED_SUB2 = 5, $GEM_PARSED_SUB3 = 6, $GEM_PARSED_SUB4 = 7 +Func parseGem($aGemData) + If isArray($aGemData) = False Or UBound($aGemData) < 7 Then Return SetError(1, 0, False) + + Local $aGem[8];[grade, shape, type, stat, sub1, sub2, sub3, sub4] + $aGem[$GEM_PARSED_GRADE] = $aGemData[0] + If $aGemData[1] == "S" Then $aGem[$GEM_PARSED_SHAPE] = "square" + If $aGemData[1] == "T" Then $aGem[$GEM_PARSED_SHAPE] = "triangle" + If $aGemData[1] == "D" Then $aGem[$GEM_PARSED_SHAPE] = "square" + $aGem[$GEM_PARSED_TYPE] = StringLower($aGemData[2]) + If StringLeft($aGemData[3], 2) == "F." Then + $aGem[$GEM_PARSED_STAT] = StringLower(StringMid($aGemData[3], 3)) & "+" + ElseIf StringLeft($aGemData[3], 2) == "P." Then + $aGem[$GEM_PARSED_STAT] = StringLower(StringMid($aGemData[3], 3)) & "%" + Else + $aGem[$GEM_PARSED_STAT] = StringLower(StringStripWS($aGemData[3], $STR_STRIPALL)) & "%" + EndIf + Switch StringLeft($aGem[$GEM_PARSED_STAT], 3) + Case "atk" + $aGem[$GEM_PARSED_STAT] = "attack" & StringRight($aGem[$GEM_PARSED_STAT], 1) + Case "def" + $aGem[$GEM_PARSED_STAT] = "defense" & StringRight($aGem[$GEM_PARSED_STAT], 1) + Case "rec" + $aGem[$GEM_PARSED_STAT] = "recovery" & StringRight($aGem[$GEM_PARSED_STAT], 1) + EndSwitch + + Local $aSubs = $aGemData[6] + For $i = 0 To UBound($aSubs)-1 + If $aSubs[$i] == "" Then ContinueLoop + $aGem[4+$i] = $aSubs[$i] + Next + + Return $aGem +EndFunc + #cs Function: Puts gem data into readable string. Parameters: @@ -175,7 +397,7 @@ Func stringGem($aGemData) $sSub = $aGemData[4] & " Substat" If ($aGemData[4] > 1) Then $sSub &= "s" - Return $aGemData[0] & "*; " & $sShape & "; " & $sType & "; " & $sStat & "; " & $sSub + Return $aGemData[0] & "*; " & $sShape & "; " & $sType & "; " & $sStat & "; " & $sSub & "; " & _ArrayToString($aGemData[6]) EndFunc #cs @@ -213,13 +435,16 @@ Func findLevel($iLevel) EndFunc Func findBLevel($iLevel) - Local $aPoint0 = findImage("level-b" & ($iLevel-1<10?"0":"") & $iLevel-1 , 90, 0, 310, 160, 50, 330, True, True) - Local $aPoint1 = findImage("level-b" & ($iLevel<10?"0":"") & $iLevel , 90, 0, 310, 160, 50, 330, ($iLevel <= 1), True) + Local $aPoint0, $aPoint1 - If isArray($aPoint1) = False Then Return -1 - If ($iLevel > 1) Then - If isArray($aPoint0) = False Then Return -1 - If Abs($aPoint0[1]-$aPoint1[1]) < 10 Then Return -1 + If $iLevel > 1 Then $aPoint0 = findImage("level-b" & ($iLevel-1<10?"0":"") & $iLevel-1 , 90, 0, 310, 160, 50, 330, True) + $aPoint1 = findImage("level-b" & ($iLevel<10?"0":"") & $iLevel , 90, 0, 310, 160, 50, 330, ($iLevel <= 1)) + + If isArray($aPoint1) = False Or UBound($aPoint1) < 2 Then Return SetError(1, 0, False) ;Could not find + If $iLevel > 1 Then + If isArray($aPoint0) = False Or UBound($aPoint0) < 2 Then Return SetError(2, 0, False) ;Partner could not find + If Abs($aPoint0[1]-$aPoint1[1]) < 30 Then Return SetError(3, 0, False) ;Same position + If $aPoint0[1] > $aPoint1[1] Then Return SetError(4, 0, False) ;Incorrect position EndIf $aPoint1[0] = 626 ;x coordinate for left side of button @@ -261,7 +486,7 @@ Func getVillagePos() ;Traverse through idShip checking the pixel sets. For $i = 0 To UBound($g_aVillagePos)-1 - If isPixel($g_aVillagePos[$i], 20) Then Return $i + If isPixel($g_aVillagePos[$i], 10) Then Return $i Next ;Return -1 if ship not found. @@ -312,9 +537,6 @@ Func getStone() For $sCurElement In $aElements For $sCurGrade In $aGrades If isPixel(getPixelArg("stone-" & $sCurElement & "-" & $sCurGrade)) > 0 Or findImage("stone-" & $sCurElement & "-" & $sCurGrade, 90, 0, 359, 131, 80, 80, False) <> -1 Then - If FileExists(@ScriptDir & "\bin\images\stone\stone-" & $sCurElement & "-" & $sCurGrade & ".bmp") = 0 Then - CaptureRegion("\bin\images\stone\stone-" & $sCurElement & "-" & $sCurGrade, 382, 145, 35, 45) - EndIf $sElement = $sCurElement $sGrade = $sCurGrade @@ -328,7 +550,6 @@ Func getStone() While FileExists(@ScriptDir & "\bin\images\stone\stone-unknown" & $iCounter & ".bmp") $iCounter += 1 WEnd - CaptureRegion("\bin\images\stone\stone-unknown" & $iCounter, 382, 145, 35, 45) Log_Add("Could not get Element or Grade", $LOG_ERROR) Return -1 EndIf @@ -560,10 +781,10 @@ Func anotherDevice() Log_Add("Another device detected!", $LOG_INFORMATION) Switch $Config_Another_Device_Timeout - Case -1 + Case $CONFIG_NEVER Log_Add("Restart time set to Never, Stopping script.", $LOG_INFORMATION) Stop() - Case 0 + Case $CONFIG_IMMEDIATELY Log_Add("Restart time set to Immediately", $LOG_INFORMATION) Case Else Local $iMinutes = $Config_Another_Device_Timeout @@ -588,21 +809,25 @@ EndFunc Func appMaintenance() Log_Level_Add("appMaintenance") - If getLocation() == "app-maintenance" Then + Local $bAntiStuck = $g_bAntiStuck + $g_bAntiStuck = False + Local $bScheduleBusy = $g_bScheduleBusy + $g_bScheduleBusy = True + While waitLocation("app-maintenance", 10) Local $iMinutes = $Config_Maintenance_Timeout Log_Add("Maintenance found. Waiting " & ($Config_Maintenance_Timeout) & " minutes then restarting game.", $LOG_INFORMATION) Local $hTimer = TimerInit() - $g_bAntiStuck = False While TimerDiff($hTimer) < ($iMinutes*60000) Local $iSeconds = Int(($iMinutes*60) - (TimerDiff($hTimer)/1000)) Status("Restarting in: " & getTimeString($iSeconds)) - If _Sleep(1000) Then ExitLoop + If _Sleep(1000) Then ExitLoop(2) WEnd - $g_bAntiStuck = True - - If $g_bRestarting = False Then Emulator_RestartGame() - EndIf + + Emulator_RestartGame() + WEnd + $g_bScheduleBusy = $bScheduleBusy + $g_bAntiStuck = $bAntiStuck Log_Level_Remove() EndFunc @@ -612,11 +837,15 @@ Func appUpdate() Local $bOutput = True Local $hTimer = Null + + Local $bAntiStuck = $g_bAntiStuck $g_bAntiStuck = False + Local $bScheduleBusy = $g_bScheduleBusy + $g_bScheduleBusy = True While $g_bRunning If _Sleep(2000) Then ExitLoop - Local $sLocation = getLocation() + Local $sLocation = waitLocation("app-update,app-google-update,app-google-open,app-update-ok,popup-window,tap-to-start", 200, False) If $sLocation <> "unknown" Then $hTimer = Null Switch $sLocation Case "app-update" @@ -625,8 +854,10 @@ Func appUpdate() clickPoint(findImage("misc-google-update")) Case "app-google-open" clickPoint(findImage("misc-google-open")) - Case "app-update-ok" + Case "app-update-ok", "popup-window" clickPoint(findImage("misc-ok")) + Case "tap-to-start" + ExitLoop Case "unknown" If $hTimer = Null Then $hTimer = TimerInit() If TimerDiff($hTimer) > 300000 Then @@ -636,7 +867,8 @@ Func appUpdate() EndIf EndSwitch WEnd - $g_bAntiStuck = True + $g_bScheduleBusy = $bScheduleBusy + $g_bAntiStuck = $bAntiStuck Log_Level_Remove() If $bOutput = False Then Stop() diff --git a/msl-bot/bin/_src/scripts/sub/navigate.au3 b/msl-bot/bin/_src/scripts/sub/navigate.au3 index 5c2006c7..2e37353c 100644 --- a/msl-bot/bin/_src/scripts/sub/navigate.au3 +++ b/msl-bot/bin/_src/scripts/sub/navigate.au3 @@ -15,15 +15,26 @@ Func navigate($sFind, $bForceSurrender = False, $iAttempt = 1) Log_Add("Navigating to " & $sFind & ".") $sFind = StringStripWS(StringLower($sFind), $STR_STRIPALL) - + Local $iExtended = 0 While $iAttempt > 0 $iAttempt -= 1 Local $hTimer = TimerInit() While TimerDiff($hTimer) < $Delay_Navigation_Timeout*1000 - If $sFind == getLocation() Or _Sleep(300) Then ExitLoop(2) - If HandleCommonLocations(getLocation()) > 0 Then ContinueLoop - + If _Sleep($Delay_Script_Loop) Then ExitLoop(2) + + Local $sCurrent = getLocation() + If $sFind == $sCurrent Then ExitLoop(2) + + If HandleCommonLocations($sCurrent) Then + $iExtended = @extended + If $iExtended Then + ExitLoop(2) + EndIf + + ContinueLoop + EndIf + Switch getLocation() Case "defeat" clickPoint(getPointArg("battle-give-up")) @@ -122,22 +133,19 @@ Func navigate($sFind, $bForceSurrender = False, $iAttempt = 1) If navigate("village", $bForceSurrender) = 0 Then ExitLoop EndSwitch Case "catch-mode" - If isArray(findImage("misc-no-astrochips", 90, 0, 625, 50, 799-625, 329-100)) = True Then ExitLoop - Switch $sLocation - Case "battle-auto" - If isPixel(getPixelArg("catch-mode-available")) = True Then clickPoint(getPointArg("battle-catch")) - If waitLocation("battle", 1) = False Then clickBattle() - Case "battle", "catch-success" - If isPixel(getPixelArg("catch-mode-available")) = True Then - clickPoint(getPointArg("battle-catch")) + Case "battle", "battle-auto", "catch-success", "unknown" + Local $aPixels = getPixelArg("catch-mode-available") + Local $aPoint = getPointArg("battle-catch") + If isPixel($aPixels, 30) = True Then + clickWhile($aPoint, "isPixel", CreateArr($aPixels, 30), 10, 300, "CaptureRegion()") + Else + If isArray(findImage("misc-no-astrochips", 90, 0, 625, 50, 799-625, 329-100)) = True Then ExitLoop EndIf Case "pause" clickPoint(getPointArg("battle-continue")) Case "battle-end-exp", "battle-sell", "battle-sell-item", "battle-end" ExitLoop - Case "unknown" - If waitLocation("battle-auto,battle,catch-mode", 5) = False Then ExitLoop Case Else goBack() EndSwitch @@ -222,6 +230,43 @@ Func navigate($sFind, $bForceSurrender = False, $iAttempt = 1) Case Else If navigate("dungeons", $bForceSurrender) = 0 Then ExitLoop EndSwitch + Case "expedition" + Switch $sLocation + Case "village" + Local $iVillage = getVillagePos() + If $iVillage = -1 Or $g_aExpeditionPos[$iVillage] = -1 Then + navigate("map", $bForceSurrender) + ContinueLoop + Else + clickPoint($g_aExpeditionPos[$iVillage]) + waitLocation("expedition", 3) + EndIf + Case "popup-window", "expedition-explore" + goBack() + Case Else + If navigate("village", $bForceSurrender) = 0 Then ExitLoop + EndSwitch + Case "inbox" + Switch $sLocation + Case "village" + Local $aInbox = findImage("misc-inbox", 90, 0, 0, 180, 60, 40) + If isArray($aInbox) > 0 Then + clickPoint(getPointArg("tab-inbox")) + Else + clickPoint(getPointArg("tab-expand")) + EndIf + Case "friend-gifts" + clickPoint(getPointArg("inbox-inbox")) + Case Else + If navigate("village", $bForceSurrender) = 0 Then ExitLoop + EndSwitch + Case "friend-gifts" + Switch $sLocation + Case "inbox" + clickPoint(getPointArg("inbox-friend-gifts")) + Case Else + If navigate("inbox", $bForceSurrender) = 0 Then ExitLoop + EndSwitch Case Else Log_Add($sFind & " is not navigable.", $LOG_ERROR) ExitLoop @@ -232,5 +277,5 @@ Func navigate($sFind, $bForceSurrender = False, $iAttempt = 1) Local $bOutput = (getLocation() == $sFind) Log_Add("Navigating result: " & $bOutput, $LOG_DEBUG) Log_Level_Remove() - Return $bOutput + Return SetExtended($iExtended, $bOutput) EndFunc \ No newline at end of file diff --git a/msl-bot/bin/images/expedition/expedition-complete.bmp b/msl-bot/bin/images/expedition/expedition-complete.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f1dc42bc3127a6f99536a14eb671dfa2c52a11af GIT binary patch literal 7734 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 literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-complete2.bmp b/msl-bot/bin/images/expedition/expedition-complete2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..11510f203dd276eb20e4972922818f6526a85ef6 GIT binary patch literal 8022 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 U&oXALFJ7PYbgVpPXr9ae0W}@^1^@s6 literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-complete3.bmp b/msl-bot/bin/images/expedition/expedition-complete3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..1218042d68c7efc8365cc629e4d9382b19872bcd GIT binary patch literal 8374 zcmc(khhJ4k+Q;XddjU((WKFPu01mk)@{=mzaAdL1vd;ZlaP=!FjzT_%BM*^N6uXeauX`ubMyrQFd}>O0MEW?(BF``YT$k7=9H>daK%EG;x5Bc$i@At^?a zmS-x^@=S~+qCj+nRO8HE0R>G<)8vd`C9H*Wzvxu zMe#d|Eepyo9Qk>XtQ5aE4Vnh`WF^b$o4m#^WBh!;3fYIqZ5 zC5oRCze+9OQF0JXJ1uuiYlWxfiX?Jo4QGP1w8VH+wu-He+2AjAnW|8nlbP(AkxWFD ztr2JEJ4pv*iVTvcwlo$9azTYgqRpngK0m$BmVe8P)!; z=Dnv#^^Do&vo*vwIM8?VCaVH`mU+oi4sb>_1)$0HjM?L}CB%2L)h57y*~SeXf&TK; z!^8kuT2h+7pr#__K-`X{UUQ;%61{>pR+jixmaDdgeeAV_how&rBzmMp1>1bxbwdz<{L4MBa)t(=% zAxBd!Xt8cu#gf=4?=S}sSuDOjv-a+x-5HfKvu9O#cGT`rFHhIFSWXXwRou?(=4gM&YME}55l z5buwMZ_DV-&M_{`}{`!5@YsvyqWMAVlcFgW>t} z=S4;kokDi&MlCEcTWoAx&?chHB1WxjWOz(!{D-^yytut|U!SbqiWc;3X}Ppy5lKt5 z^Xu#!7$5%&G%)aLc=$&I3QNSgcJ0Rj8)&AUs1AAcilV)AsomoPKIJgU(~#zd9TOA( zKqHoJaKPdri>0The@l>CRw^}Pdf0uF4ZCjLhMk{+pQXLIA>zf0zq3J*8jdtDNLc9H z^d!!p=0wV`OoKDe?e5J+m?MrykDi^VFK@2T_@e2^=gm~DO)1BVHfsPtE&uLTGc&t( zt;1Z9)6|gOdMf?GIm7t)k8HNEuur9Io5C*>>+Q@hmWawJ{1WW^FkoNb%a&8k4K*2O zTb2F&189NN>bw=pxy+ISL;x>;4@Y`eRyJV*FluTw#{WUn&`xva)(#Zw@=X!8!ku4^gwO zj<1+mQd0V=mG6JD#eH9tYsw)`n?s*YQjc@~fgdwq`x+6Yq-3pH<$*!=N`t7gDKnb{ z%CAJl*A{re7V7VRHD|Ug;~+7sNr9w%92F{(Cn;a!(tZCL%)l=+^pkM9qv;t2emAev z-3os3@rj!@lH3d#Yq9L#0JLCfo%zKOq{7J>r~OO$HCfKTlPAwE^&~h=F$Hw4HJO3I zNlE!7l7=d${hNG{n%(dGA7<9oHF)ym7b>MTI(pZ}4SpLwUK|{_AUw<^`2da=%a}b6 z9QJQGNBK!}NsB;_i~IM78XM25Rl4ZtNdJv~>pxl?v}wV%Ev||2SP)K7f?u(UuPa&( zTTFZJUf-PAB=e9Jo|?jA{4lW5ncucB`c}XhHkF@Z3O`&}49@)a$I!$&;lOY4B9iLB z5BF#A15r!?wK?;{Nm)OIAIxn0Mo0fNKK5rUDMG`(!cMHNZVCztSi73$E*sO4-;Qv4 z31aOwev<~ddGkR{O>;gNr~KO-fEKvslz-rdJZPx4=O5*Fn6xz7?=Rp7qL>0|J7dp3 zA8!s^>nfe{4>w4d+4$Agp8n$VrmoKK`uYY(M_;j|tgCBTwp5;S$TFrQzwO&N97k-f z&U-inX#UmLpTQuV9d{fDp&v%eXbS3b!LLBc*EsV_J4mo?>CSyUzb#wBw*=8$i3!2) z){O?thQ*GHOAOqIm!q9uVq&`I5?MkVvQ0KJ@(gA;n%{l*H&HtY_REQyaI_#e+(A4S zJMlxyd+)mK*-6w=SZ%GTj6r2(Blhp>_;qz$WoFy9?FbI!a?*%Nn1At{lD!Wa8{52> zy#>GR+jj>C%CeM8t?cE()#enj%2WUGSw>*~0|I2|~U zp1YgetLdvMzP>$rQ7 znI$Bo`7M8USA=`qzWH_4xh$Wms+w1?lxL;7DKgv>;@$7vy~B(*Zw?I#oVP#5eeWK8 zag)2hKhJn4C1w0}`Fm`T+A0O(S5tFp^@px0hdC|d$5ok~_HXJzl809w_({Sk58rw&#_Fm%T+7ftKK|E`;NZ`qiB=(Nzee9E5a#Uc?1%BWbCf-V z)9A^Q?@jq7`9^b3&oEjLM0U0YFC--NY3u$)N8Fjs=Hr;9sHn8R|0T0bPgjJ8aj>kb zaM-`^^NI1)$#1WgF;qDE^YV(&x3IAI@#AsUH!DjO9ww`)h&WL% z98dW%cqncB1SMZzwPkel1zQGqWD`cE-v`%zzkQn8&6dlP`mTejyLYy=y9K{BS-n}CAFuiPp3_+f8 zWhQS}!NH!MQMp`(uOmI)L<)$*MNyDSRA@a{*4z-))p5PAx4*A<$fk!q53hdJq{{YH zq|*;Wn0@Q|H4L^l6Lfx*; zd*4zIrH<%}S?=8W+GGgLO5wHH+?9)Y{e1&yfBxL^dG_eh_~S=Iy}d&zhdr{7&`29= zcXr&p+WWL`(jex%u%oFm<^T{9nrDT=Zzd+#2K>wN<-c9?A)j`b=yT{WO!zRIBthw7 zP|p!n7U6?!ih(OL&?)3}sg!b2Jqwpu)S1v?P|w!q${ic=2(KBmi>ldrr3)T0GyIgM zuy==Lt;7EP;C((J-tj3eXLb+uxfseGf}phc*7M*t%Wr@G&5_&RQ6HV-XoiTSL8vp- zpDC_tC4LIr@Z9hwM+)N5Y;C=~Zrz%X)_MkQS`r$xBs7>RFkk_0#hEE~7bekqgP)GU z{d?-K=l7<5cHeJj8yVlf5ufn6nKN{p-e*FvJ;hvkQ(ffvnB|fLipb~g?qMbz#P#(p z3q1(Fg5H4B%r?_|VN1%ls!Ydk=GiAdz1`kCGW`7c^S^~}TOS!QGe7i&^G+j3?+>;^ zMWxHxmXv}1fsv7yqoaSc>Zj4spGJoNaPh+B_3OBdBwnX*l+$37#{LidtSSo_ANv6b zbmdC>!Vj>2-`XEh<{I+h`W5FRkU1)ZL zX#>>c;Qpe^;U~#Hl7iR1PSb#NobCTte-i+cM;29ctBwWXi$^{E@=mt5M`sJ+bupsd nW;0zylY@VMb|l2Mr(??-)u$VK=9&NdPiJ8EhL3W1iQoSLV+IMM literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-complete4.bmp b/msl-bot/bin/images/expedition/expedition-complete4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..b3f3f242ea3efd616c7073ca33a4eb0200df6adf GIT binary patch literal 9126 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 aW9_?5_dohLF#~SF;&GyQ#|o7)=Klaw-Ak(g literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-end.bmp b/msl-bot/bin/images/expedition/expedition-end.bmp new file mode 100644 index 0000000000000000000000000000000000000000..46631a076f3a0119d7918969b62157410642b075 GIT binary patch literal 2706 zcmc(fXr>5M1?e{cwW=Bm4XN z=8YTl_3uxt#;=h_to{zVZg(62hcwr&Uc=1#zry}+MXt^QBoNES&goI@5h@)b#PvDC z*x0|{M5T8TBJM$jgRyxAKx;4G5R$ z2(jAT)Y`%A0GgD{5$L;R$sN zkM{zbcNEY13L7HjD2Lkvt2$T0omdz#*anqmM`X?!o%W>WiQF<4$aM1uZ#A_c*07U_ zTSIv)khO)2vQc{zhl>SDcxIU=8bK_6PpZ<*6Lj$;T4#c!HW0HH3=aY&Z)SxzD3$1( zuGlP8wuTDUNy_AlxA*XR1;}SMEiuH%7Md$O{=+af*~0BnnnOfxHM#aw;|SQN9#T7R zB8$8J;(BuJ1Ux2RvbpuPJv_(81JkwC`bqillQUZ8a63KeYWC49IqI~Ais{;mLAkDr zFL~fEQaf*5v6&Xuuyv}ok={%tw|yEcZ$y`licj9htH*qitakumd7y8@=WOAJgHUxH z_$;vDnN{#BOm17al&QTCD)eV;kKeiCGaPOgz~{DK8$6-N;$C#=;GS4MthG$cZbd75 zeDN6@P_b+<0olV3OHV#nC$l`E6#5)nJ`f|u9{!N8P)n};eqXBU>6edsbE%EzB(>7T z8#s$g5Qv-nMPP=uT*=naE5!W80epe=^8u*JhSAA&n2qIup_Yb4InHJ z!$uBkK{VUU(WlJj^T^_p(%whv*LOy5to;suEU^HOtbbSupMX^FiY*`F>4k2-Fi_e` ztv|arq-f;aR$^rK(M!iv@hdiHpjd_eRM#L!J@EJ(ks`P2F3Tn}Ius@%IK53$t0YxT zZ=6Jz_W5EtPo!sf$O~*Fu$2$~9G|J7MBG={OszkUR1O4EjeTmmwD$pSO{%wH!Bl?x z)RUYS$V@(}M#p2bN(?7*m6^j&7y9-ZG2`~B^32g+B(q=+3y%jCs95Fs%%&rU837x-kSGyt@9tMwqdsaAUTLY$tg`rl zGq?2`#_Xe0_#7+~Wk@jx%WOQc`YgTif_dNOTDTpa)Czn8D3KXUE){p*!z#2LO2w9s zQ6e`o8W>A1r)w|u?x@xgoBHJdR>2RI;X@uV`dJtl>AqcL+kI~so49$ij@!{^@+Fe1 zPlvUb5V0AFyk%m>Iynm?%oSJ&vg8jYjb1u#9xnq=e&?+_F?XxE)!@lsfqXYlC`8O~ zo}eTJ9uS;SGIU&G@Ebg7EJ$_q_VdLWI8UG~2n$YY9Px7)iOvUXFtW0T=iwZPuN;ph z7sz}ywQ&-u>?7uJcokX0dE(^>91*}qLxvq3m|;;t_H|e_8c}hRK680Ijrq?Xk@`mjBMTk@JWcTYfG}W0kk#|` z`j_)zROu8bzC(mSaaG?@;hQOdgdi|nNchMquNkgxR11p1T;r*6x$1HX)uce-XzT1@_Ocs`P_nh-=k~5%utTu< zW_wd}Yg0=b1P3`X@Bl?4-qP0DJ#dfNd#8=j4RuB&hUQkr5J$?D;4ry;PdcW8T?jC= zch(J3Q*&!aKU+8~#2^J~c64?3-Ql;icCdJA;JM^-O*m8T>?U6}!C(%+irOA^L>I@k z<`J2}8l1O<3PgN?Ot0YHWIuc4W?L6(3fSs#lRtxdQ|3TUJYi{LFmZ3*nOtG<$5Eq) zh?o0WoIaLNWs6euCTehj;l4NTO0Kd-L_)RA9-f2BCV$p6L+jmy2W@bv$kDpY z{`u^a-?Wo69n1ll!B3{wV(ZV8RQOsFvGrdZ(K(^ULDALp_LR$ua@nscrv@9mKi zgV_h*>76%P!XI4P4=o?w6-dTZ#_753P{4Op3)5L2tt=hXPbL zz#esHtFiT8?}_9C!;%SCI==aWqF4J^-1E2)g}C06172vywOl=eJlvDZ0$0t@2QL9! zDx23=s6zLh$z^+FK3X|}9f50zivmooUsPQ+uF~=6`s_ zgr8}6Oa{kYq_Kxrj+}|bem2jW-;QrQzdI^zW!#eCRO-ul}|E@+%Uj{VfsBEbmw z$*jQ~v+quWORTd>^`x(`L(yv#T}f=7hL#W50tt(+0iH`P3b=}gzfYB_7#VSAx8fTw zg5^VwNNJfZoj7*PDcqd~kiRvqjBc!s1XCEHID)^x?{9(s+o(2r` z>nhjY2kqqajT=qOo*}(E8e4ldrowrsSx07!(oR;(o}I+@I08YH`C<5m++2 z?;O$jo9&%iB8hu5{VX02HNc&LQ8ai!a1V*GDWTS*B@(!g?in0r3zTqYKv@v(D=4jz z3m60us@)A)0t@h8kF1_d#ulkeCBAtYEFYkTDL91?8P|T**yH|% zeK>Igp_Za?BZwHAX$UoiCY) zg6FHcY4JZwhR^EiiBi2^ZHvPzD$J2jLH+`_XZ^|m literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-end3.bmp b/msl-bot/bin/images/expedition/expedition-end3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..9256f709cfd96c2877e486ef187c039664140e18 GIT binary patch literal 2014 zcmcgtX;&Ia6lFfmrzip{B6?Va20;{rrjfk`WRrby*c9kyM-fTfH72f!CdMUuGD+sl zOfo-ee#<;TJ)Y<+pN3Oir|R{sTesi4Rp66<{zz&5Q0PVQ$lz&%=LZTCdJ5(1<@@I3 zvg3=#noYwMqC5n-cV^>G&&Oo5NvCwwY7IZgJ5sJ7%)KGic@I}CY#sA;&jlvg+qG2Sl!-1 zXLBWdF$x1#zj$C!3*^^;fk6!7J#1k=Uk*!vlhMWMg0%Zk9DtXvL@I zw#bdM#>rQ2w%*BPPfpiMyYDco#}O+P9>11pOrS;QOjhBem4O;ZhWcA4> zAFbo){k#!X`Fm3@4f}C@R5Kr`%+Lqa7}LO9QFjuLWQ$y$Dz_P2a$#f zYoKdzR70hAqqwKC_uiYSeWwL#q0rmzwNaHuS7rZ$H#^Vl<+k#ISv*RUJ6zfb6;~tW zwZh|9*$XY$RbJ}Hza<+x6u7qF zN!K97>6OF5QNxv%xx+8kNS4Xw%PqTG7v4?YyVu5Kb8Jx}|L9y{m>7^~z$PY7+T_hZk6ELVQ44roEFXt4 zL_ieme{oF629?%{;vw9h;RvN-xejciu}v8#XN;aSiibrbW`RV9nnQRX)5jNa5jmW% z3tDeR?@GzFlR$f=W#Pr|aIk#YM!2*J1q7eVbuOMr1CW1iE$_nZ12-O=M{vOqYKANB z_A1e^8TS*B^4|iQTHqt&^}S?cKVIL327K^6BAMwn-|YxoWwF|hpIAm@MzBDlaiDd? z;4k4eQY^=9(Q>kJpmW6U1T?h(N}=}xD>N9$)D9rNO?GDlk(rc6KP-el67ZVJ6qG2f ScOw54(A0A0(*Hk5q5K8^MHheo literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-explore.bmp b/msl-bot/bin/images/expedition/expedition-explore.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5fc7c89a9ea07e4767d8bc0e2418373234d5ffe5 GIT binary patch literal 4614 zcmc&$drZ?u950TsnK_r}bpD|(Tjqn28K=o~Mzd_XY>8Xu7Lz?Rdu0=(D5d3Dip3VB ztq27L#;^(qB0?!`5fD)k#0MZEV~9Ky5Fh0YLU{@7gI~OLEs$Wkc=`5n_qp%qd*9F9 z{qFk7mv(bFPs#_Vm*ck?zt{1z;VeK+<>G7(XYBX1>~`c>#q=7V(b3V7k&*p@tF02y zT0tPxTA{M^{?LdLB3o;%m{y7NTr`S(7W=x-pH}{^PBZrTzw5@en-+_lNn^mCrI~v1 zWOgKaYgG8>G#VoRkj-*9>T3e&aI$?=?q44hwdIsngwc$2-=t%|K@?-jBr7f#stWQV z{C(ae5cx+aH)&G%rU~HW#~<15&7VU)XqT2GYt^1C4r@$Er%*&EjnRj`pkp>+os$^| zhwg3zMk~rQeE4$_U+TByUegUAhKIMzH0GTRYihhcJUoO^)SVqoP$Y1fNm)TMaD28A z%1;Twn$*=^?Ca|S&dShGe@ki_d+zATJVe1_pXhB8Hb>B4$qp-}Uch2p) zOYy4h644Tg=$$j!a>_qWwT;|NH4@TTUjm>0zV6_lHU7f4VN$=P*RQ1#ai6~f+?Yn9 znASwcYDb2BMs%uu-4~FXnMNdFN;hjCkgaVt)L`n~-geYYcgq6A_RNQAOpN=Lfrq2M zp;S*EcP7wMBgJfQZ)7YqPU-d#F+{!&-6=E@9U9N)hH6sX;|~827W@&Gm(QI^0jH%A z6kVD(O^rG+_7@65HPeWtV0cXA7V>ASXQ{EJxfVWct@VtB22K`tu5wHqe6dYQ1RcqGu%1YIAdU37kHA2$p>h!P1#)gt>#Yv`CQj`b>GTdP8Z4FTOsJj{UgZqCg z0^XjVpdkN0BgWs3!NERUCZ>k4cljX)ai6eY&~tO#6%cb3n62}3}LekgP!KwRKjwFhzWMq6sUQL5IY z@=XnLkcpe~3t4(G4m>O)UC8IYn0s1|!|-@$08a^T=M4BTjaZ__`eKACFH7(2yf>CW zUw6=6hsiWvI2T4K)zuV$1%tpoV<*72wt5fOSD8jkhwa9D^w$j?&g35NMHs?!%;*5i zuWRsf0f96AT98JbGbbi;d>_@xF6dfXc*us9mRc-zRpn`s=R7$0`!1@h$p_MGxD^(> z4oHSph%PKY?;vKOw$a#Ocz84SbdX@T9fiddloBQ-1l0hEM@sr z-OK^r)p;L?;b9dP4c#D#JtA1ru|CN5Vt%AIe>NOY-2ST(T}y)sU79=WV8{kG8X2|` zh*s^c+`kqe^O5?!m2h;MRxQA&CWRNL`qs~L9%GqmWS~;9COPqUqR>QeQ~mLk7w;AF ziC29G9H6J`Oti^UB6Axi-%hd@`1| S+pGxX#}d)v$sDYUL*qXuvdPi_ literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-explore2.bmp b/msl-bot/bin/images/expedition/expedition-explore2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..d20071c9fb309a6f77b766d49bd5b64c6b9523c7 GIT binary patch literal 5246 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 J`PxP#`WsXM_H6(F literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-explored.bmp b/msl-bot/bin/images/expedition/expedition-explored.bmp new file mode 100644 index 0000000000000000000000000000000000000000..297882dbdc160f3f7a1157c5f87f27b249eb6236 GIT binary patch literal 3794 zcmaKvYiwLs6@`a?b0;N%q>1Ag@@h~4)oCOsjVel|D&ip;+6t233PdZ!4^#mXD)57+ zN>mjgRfGr>7er|q9x1``V;qm|v1dG%Hejn8DeWCRl-CtT9^UMEvCl{B{vFJ7D zk`VcsKDfiw2705VZY8n-;wbc)fYDI4yRTMhE9{ zcB>7ZT=WD@6nxtnp>T{P)ZoSO>hhjiYiM+an7$Fi8^H?_9L*mUM7G8n!lyBXkS)Y5 z>InxSzb@QbF&>Q)d@!ciho_MPJULp+qR>544BKRUxQb1N!>R#)v#7@El^kFXMR=~=^EM)9ib zXmd812M`LE5k7A5Pr`zqw^Lh=A^03Ioh@crAheRxM4zTvV%l+K1-~7kc z8VYKN$m2A~@Zryr;cVq*X^J3(a!LCN%UM-LNe5LE4Bg=Tf1V2yzbCn0ZlmQ2y|cVN%KiasvlG)!^%Hs9^#!8k{=)J^e3 zGoMaTf0;MOc&L$*PI~9e+zlr3F=CgQy3NmqSX;}%a}3;IZzr4U^1;W= z6k&G@_ea?nYvL{5aq>g(}7a%e>1ENf79UbI6G5TTh?l8wVa7%9PL$?yvCrRR+&BNT=rBjM^h!gI%9hB z4X4ejm2*eJXsdSGqP);;w$salIc=FMe7@DRu3?(D#wkwnwJuIyw|$FJy1?)vU+p$E zdbWekS*uNb8)eY$Nmn@a{F!zhO;I*M*DPOZ3-qleSKKAeCCfQ!&nMR&39&~=ZZz7Q zDu1lHTbn)oqp)RdHX$cDya68w;8|1TUlx^bL|d4 z=x0rg(o5!fYrV>EMu|=t|Nddt#g?>ft*Vc= zHUV))O=VLve6}U`sxT^o+U!OR`1=rGDb9}F#@AT7pjk*7@@UE%XPX_tcJ9l&bMWMb$YKiC#WMSSheh(|u zHwg%$mLClAF(s{RD=YD@-*{d5#(>CsEL)0=F98g1#_0{Q4#A{9cN>LZArGJ*xJn61nUw! z(ni@7ZL^g0QIO>R1RI+SLD-UFZ6hn?eupLmOQ0yGtMP;Pbl3A-qn6qCJtJ~H&pi?LjMJd CmZGx& literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-explored2.bmp b/msl-bot/bin/images/expedition/expedition-explored2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..a07d188977a03c8bf9ee98e8a52d004b36ba0e58 GIT binary patch literal 3474 zcmai0ZA_C_8$NBJEwdm_aj$c1b%N+*(LX{alT|ijvgM8YF|%a}nTcDJ)J6Z8&A7OA z(Jf%IY|^>Jjm<>2{lOPTTT1CuTA-Bj4J{v1Hu)-03gvV1{qbJs9Qufnckjvd+_|6o zT<4tY+|N1BIT`=H5lvW0f!&KI4bN6Q67nxtUYs$6&_^uwgf#p=)DcokNDCnzX1&bu z5UEEhZ~Ra2lA+j1RjZFf{sv)EcI{l8}FflaO*k{7fgB z0MO6ue((Mhz7sDrzaXuVQmKdo=zNI@K*K5|h(UDlx_&sQ9bgd<09V+;;ow2|)of6- zMG*)oVX%ZPcMudE6Pvz$9RXDqabQc@(z zY|N}5Un4^akkgeDZ;7XB|HA;)_~;C}`#KPWpzxLNtIO?|FSk)-RAf9|^z7+e^0Vd-T&w)7n<;c42#A zpm1(^t{_lw?aynNvS-q>u)Lsc(mq%GoH<~|M34=x;VIKog+qm?H3p1d`@V)GAgwY@ zX;9K6L-ReBXZQ?U^OcS(appK4S({ou*x-Pm1bv|99kZ2wb=b35PY27J|2#YI=1G59|)9vM<^1J@KS)MFNdQ3Cl zgJI3T4g8kblzF1=1V_9OFEvUPCdEh1A9eoSxv;We95$v@r9>1*AY*y`bZvax_Hncj zP3+{H|6K2K@6FYl>J_zqRX@Elt@Ug7)a(&LLSQ~XHM8H&mt9{X?O$|#k!Vje2hI3f zzTf!1vRH{(?-X`og7^woyRM#ZJAb?XHYN-4M_fmEmZ)+R{^tp6#>T-M@rgN3)}K_G zl&Q{C=a>_k-Q#Yg==xvR@%NAzB|Oi+5B&Z{%^Uk1`w$lc0u#<%5wft{+l&#qH0$ejZm`Z3_5(L;hpBm zX5etuVft5rRQ&f)_)jLR*$^;XY`>W0&Emi^z}$c7|7CD)@U#1$yGI@j$!3TZpWQS&q0yv1SM;BZOwm)n)g-it_1r(zNr+lZjy0@;~a~zbm2Hcv~ zqk`RYxWzT5g5(b5PAyGoeOi@MMVY)I9E>I2D3B}oVl6o9eQ_-AAQh;^5GeeXbHgJwQT4N=r8V(MZx*Kek1Sc9@&DXEpvJ8et&7RoQ2+=};4F^C9e zS4$#mBU9T_6I&AHwQ_oK<-k~?4*^gPh;7$9B8|&K6(Z;vS8)_R3SRlmUv$J*&TL}@ z_#C`;L)*l97MV{v;)qa!>}}YI7=%dfqaWnW!!*M|8hIw+i$E>saDtb;LJueZFS{WD cK@PMMeeOUK99XdmJ_n?V4wnrL9aQsw0Ri}UyZ`_I literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-explored3.bmp b/msl-bot/bin/images/expedition/expedition-explored3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..36f557e43b00473150c78d5106a7ff01fce06654 GIT binary patch literal 3702 zcmaKvdu&`s6~@bd_il=Vk|vI0$g4qZQJqGD(x{>oRS_W3&{mKHS0Gv;{y-HVp;G?f zsS;I1NEIOh#RXBChDV?{eyo$Vz4orxUfc28j`1swlh~Wsj-A9#>?DMCe|$5ud%cNE ztZ$FbocZR=H)rO~y?$!fD|z?Wzfa3PsNd)GTdm)R?pY_RcBbDpGRE&o`yCdYY5xv% zeNd#$lKawrZ`zkVX{~ddFYBOe-PTtgIkIF2t+K=~8ciFkYBY zn7y6+V3>!KR+7ky2i7^3nVC_;HG9O!5Y6bx!jmv3&pM_V#;-KiJBs%&i$I%OQ5jyT zg$NF6I&$gKaFam;U6*<_Dr@t~`RyppmwCF~mRA+ls$Fso5dyLsUS=gpmBs%pV<68> z^sW^zt86Z9Fojz}K+rP(iKnLYR~QsVSQjB=rz@-?Uj-~Bbd>dB)>N>vjDx4?ndcel zca>D#Z0Yi=SXar1HJvoLDp~6X8pt23q`fOb(Yk1j*Ro#Aa&DRyvg@^c_7M>6gAU4 z*~n)S)L!K6aUQOxxP#t#Gj{zk4vupx&A>JOG*09q(>M9qFl(wgaE8Ha?CD@rO*Z+2 z86xaz=Dsi+A{-tkKEuu?HdXW1IZ`*wbVk*X;jGT?on-rN@5=eM5Hv^1hHHKg>(rrjoxHqNv^^RQ$;%o@g?T_M#|e^!LrPZz6JKpQh1XR=!NIr!=K>UA=>AS@=f(w{atKtpkj*I|1hG%dEMa9 z1UnK|f6D4_v7E_e9G$E3%wy=p%l_(=sqHtNe!C(Cx5teBDyKipi`{1HUmeQmPhR4S zEoKYqW_V|UqBvjgqW`L`f0&X*M$&w(+mzzDb~@&)e${`BA$xvYakO{Ow((ek(n-4J z_;PDb{hPUybHQ>>*gL^qBSybfdz*fHtEk{xqWm?*g&Q2!@f$V;pS#7&{X9@-&d<&F z&6B7aPTgeU2JfV(zQ~nZ{BVHP5lSwY^WSor-;5ESHt~HUtc@(`-%^`RKEdzoLy@?| zOMU!!knTB7FY?E;Jm0}T&RYTEjG5{sX8C+`=9)DxzARoJWpt4jddx*_g4G81R`Yxh zb+epWG#FXr?G%qSvpL3_<7m2?8BSiMe471dshKqw&Yx54XklfPU!S3Ej@nte=gq)( zr+7+rlYV>tcXzQOLUDH{xu))#=lcVEcYu~F%>S3g_e@QGGQ_t}-p=_q1$y~b6OzsV z)%<9f@f++Lqd@O*y}N4()e(xZx`B;JK5ntKnZic$qTCy$pn(kuHYV8I$VU^bli$Ss zN!B-!rwlO)6lvsRA}HQSVFP*f<}2dBIrIGPR-tNG6=g$=t#P&{*wV&hj^IWWP{B76FBzHs!}qmqhjnQI&Q`4~s0*{NqIm?cOO zBP2;eZgN$%iK0%vHNtD-ypb{})-|pjZ!!p-Ak<;eW+QqNEr%BC(1PD;p|Q(oUmf5N zlkC#hoqFSVF+3+e%T&4YTiMdi8YRgFGmaHwl1rGgEqDrQ#uKb)WmP-*LI>+QjK4x^ z19aF=T-8JagP=llub}vvWf_!qy-l9!YR1zlr1SPXp*B;rrQuGklB<%sBs&Rp z+9_m3Q(V(IC=zrz-!+|n)h%Gk2?)y_o$y@da^J179ZyS;Jge%16RIn>S7%TEEcD`a y8kixPOA%*nmm_3sz*kp4UbjUL-d&(=Qnot?Zs2m;h3Aml6$AsvsntRTGWZ`ZXn>3W literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-explored4.bmp b/msl-bot/bin/images/expedition/expedition-explored4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..8020b50b6185be17acc914a975b7eb7a9bf25658 GIT binary patch literal 3654 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 C^LCT~ literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-exploring2.bmp b/msl-bot/bin/images/expedition/expedition-exploring2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..349e64c99b20c92d1ca6c59df80ac94379d20adc GIT binary patch literal 8478 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 CeR*R5 literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-exploring3.bmp b/msl-bot/bin/images/expedition/expedition-exploring3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f0a6e4f4f9dd3293d2e05a1d3e761e164b99fe92 GIT binary patch literal 9414 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 F;6MEm#&rMy literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-exploring4.bmp b/msl-bot/bin/images/expedition/expedition-exploring4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..f538e1be206dca78f5beaaf58effecebb1404fd3 GIT binary patch literal 9450 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 literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-unknown.bmp b/msl-bot/bin/images/expedition/expedition-unknown.bmp new file mode 100644 index 0000000000000000000000000000000000000000..158e60f34120cbb8b3d67bffba3e3207ee945a64 GIT binary patch literal 2838 zcmZvd`EMNM8OPI~iT9X$cFvuhJ!fX``#!vv*SlWF_S(+c>$Sah;vfLAG=kq-8_kE>F zm$8SoY&?E2TENSJmjUljwh&<4d_GWZ+0uURKN^@(0YUVp)DR6K8idgz41_We7=d6G z!Ys5oLmOjSEvtoSElg_>T7%GP_`AdoE#0A|R6r1|hA0gTI5a2%;#)Oz2M}1WF;PL3 z8m6=`0|X%~jBqd_U|d8=&B?JAib*IYz$gbA(7Dj?0t^poG-WFO^i7`MT-<=csqn}n$3;FTnA!MVSpg2 zU>=yDhIA@O*XDztm`O`JA#F!tzdp7TRYJ=b-p@$ zFkP6my96kz_-R&dyP8QOwHT@nGlP{>e+rr`|k& z?UT!|eR|~4+e3{LE>AbXhG|=uF+3_~X6&8wN@mUyn_!()hzqE2E8rVKb#M3nVD)IA za@b$mAMQQo$uC=iP0rG-r+oq&waEj%_)0jlZ+!0QGgsb!;m((DeE99fYadT9TnR<$ ztfgd&wL;sDCF>8zht4KP9*GT}a^`mHHT0M}K5G$+E>FuJ+Y<@z+Gg*4 zs@S->d~WUP`r73bWg-Sw4Uqvu-3fOSUxs&cJ<8YFiMM%5URszyP#Bjx#e{2Y^C+|(A>+l@#oTk*52XSzubBK z+s{7w@9%&6_1ky8ym;kCW?)b6;lYXZZDZ@D;Y)$^vLiC(%kCyQKZJ2wl+YqNE!q~~ zt6)L}VH%i3aFH>lBITo@!oFnnMDNskeg4%-&zZ6ArOPWvzWBp?-+XfKtJ}9eKK}}e8jqJdgk;T^=v#(ULN6Sj}-t8OzzIXSp*RS7LJlYt2VzBvK|LA(Qd{&W%OqL#S zWZvu|L0L3fyhDROq{iCP;B9|UqZTzlr~qRo+K@=q9Cm_aA(%nVdX7bMV~q`ToJnjhR=g zLzknGMM)@I`Lw7{SzH6b(tb)G02~N2L%0pXWuWi*n29mPeWe4z>T#>wW8{-IA@4L+ z(!~RZFWhg81WkkdLS3k5Tu5}2?_DupVC^^OWcDG+Y@ zj!!5XdQ^?5}o`CKEdU6)_F``MnKzBOFGFfjCZWBz7$ z|60&Dt%zl-K5yhxJQL>iF_Wj?8g7ze6vC}-LkI;p^MFs8Q`Y2+BQr-a0hS5r*@ThL zS`A&2zE~(M9J})F?$hr#7jF(vzcko-F`7K!k_IKAXwqi|E(z9Clo!*vl*AM(bwPv- z0|DDf$9;cfly(vNFeQWu%1zTjj)@6e#-z_%^#zZk)-`Z^^2nXhm0Pu)*DE7Gb2}T7 zShDDI1}?+137QU(lm{afg7cyjI8EDT^WXDHU=gS&gO43XI!Ve;Gf|#R30$X1pR*VW zieqSS>Gka^w|b{v%xpU+nY+z=r;!KnB*VmXbP(6MQ4%JQ5(+{n zDCs09pN&mo*<{Br4-&yHI5w_lqoR;Z^q;KGy_Bu5S>1I5ALE%Q%fzTQ zJb>xE2qmv^+!zInY71N{Lgym6Ajtz`ydGT{{s`KeZK$z literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-unknown2.bmp b/msl-bot/bin/images/expedition/expedition-unknown2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..5616ed3880640c60d17a256946317dd0eb9f46d6 GIT binary patch literal 738 zcmZ?reZ<5724+A~1BkhSSQv;I86n|c>rn6m0xP50*TxCWpa zMHy2iIU6mVP*b~NE9bJr?3ry-4=&jLY|Zg66BeFL%bN;RqatgqsS#jko@r@cYN8)k z7Faa5Wzn3i_ZRJY(LL{UYTh)U8VwasL*o=P+Y)Q5+#tQc>7H?Gi#jIGIXGp-wYmxW zW78%A)#w=}SUXf$*pyi7Ma*{dKOUB_J+7!OwY_=5zKpUJJ|WFOHI@!#R(7SHc3A}; zv8M`(ZeOGAG_Seq%x2n>lkHH+9`i%scBIQDYJu z=UeUS4_4z*=V=<<8k6~O&4PE^wmh7>>_%p8lal6#CcBUDW#EFx3{nUa_jW_b0^5wO-#Y+ zxU3a^uC>0p0mn8ke|2p4on_0G7u3eZP7Y6)7ZM9H$1S)mDrP_X9s}dZNdowFLih4uBr^IEh42YOwV_g7L zW1#BiUer=mt~+0OSlAaR2}S literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-unknown3.bmp b/msl-bot/bin/images/expedition/expedition-unknown3.bmp new file mode 100644 index 0000000000000000000000000000000000000000..7d6109bddef9393c9d38161a52edef1965d3b228 GIT binary patch literal 390 zcmZ?rZDV8r12Z700mPg@%mc)X3=%*R0*>%8Fn}-&7#gRT*_K#a@ zU3?-YXJJ5QRYFHX!bAoO%ba-U_>Bd5Z|2N-+|+e5G4HHD{vC3*KRsPRR^T z<|(C-S+}>Z{&MT|`*SDXY~B8B!qnx?p(TOU41WG?@jiu9ifbO9-}mvtu@{>+o^9=J z@GDG>>SKt@TH)tf>#G}ZZ1eJ0$9CUYwrqJpZCvc+@Pv5`QCZ8QljeuHSJp>m?VdPk zbN{T|$d>rDMd69_83GfgXH{=1uUwVjkldSD*-_LR5 literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/expedition/expedition-unknown4.bmp b/msl-bot/bin/images/expedition/expedition-unknown4.bmp new file mode 100644 index 0000000000000000000000000000000000000000..85511d27de37648e531b14797c70bb4a0effa8c4 GIT binary patch literal 882 zcmZ?rEn;Q>12Z700mM8&EDpqs3=%++fx!kU59UA#F)<|xF*PZ1b#Y-WZOb%MmqMq& zs*udd{-LGLUTFq~9wH*jk`ijt654V=q~dMjQsxre5R);rqHlM3$L5rrNp9Zha&o$I zl3I$=`U=vPx|SK1uH~UAQ_H(|O_(WS4L4TCHxB<*MsdTD4&9sZT2oyq~!8 zdQR?C1N}fH2`fFrRD1UZGlyCgE~E3FUR!f2Ca=D(oMZDF3L!fmuIJNL)D1@C&M9J2C%h9a7sT=R; zRHevkR&5{fWB!~M)8@RMzUZ8p*A2UX%MPCI(xz_yo$BgQet{iI?CPtkYk%KA`|B}P0mYHfsy31O>ID6pNGe=h~Tu<3kOUYeJ*$b#lQ^vD?*73rQW07e~A~Kf8WUsNbtI|{U z)>igZS9DcV1S<2?lyx$7s>o)8Q&)6Uk#|;*bC8#_SCV&BRdAFOHgr#%9#OI>G;fWTak9F+ ywX(dOf}EY4tgVcUjl8U_qP(q=q>+JRUURtmD#vNBfEGFAZE;y&#F literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/gem/gem-defense2.bmp b/msl-bot/bin/images/gem/gem-defense2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..e7173cbbb50f5fbcd1df600745c15dd349eee93e GIT binary patch literal 3726 zcmeHJ`BRNy6wc3P%E3Nm|7^;szy7tz|;kHOLJcHxmp&^KL& zBPWvau}g(*UO{SXQuYpt-Dqg(LSlM849y%EN5PFsG`97?T;`0d+#+-jjHqMjQH>xt zJPvwG?I7ioV$hZk!d2hYfoSDfjxqmg8M^vE;aOb+R#-Vf?%>6-ym;M+C}jr1jwSF| zDXi%l$Pjrl9qm1X@bn4ALL>R4_UpIo!iUywq-9-!(Q-$Q=lZStXzNxnF53;>IB+PA z{U47_<9wCht%1VLf6^GFa6PH5XD*2A32Awty7>k~a2+V0k89sD28Ej+3m}f0Th;0!fQ{Mq)%~==1ld{#I-~4)7;+2_3_vl z!amze&Tne#MOrFU>t-RESdaP^b4ck-C17ikn}Q)W&f>xRT#XDyms0 zs2`|Saz`&opT;XD`gAJw3J8s1ZigI>XDvD!mBL&lE|SJnRMjv)Ho5Et=?rPu>69E0 ze~C*{_QWaTecqKaJbL@O=j zcU0HBWZfWLmf9!ghjfedkTCstFNy1aYbIQML*rb3>Jz%l=shAfm38k|arp;Fb8QJ5 zX&~|GS9|`%dQjLYzPn=L&+<(76Wv+!msn3JKB^J*d-9nJtdaCRLHF99h<*Bu>2LRc HkptfVTqZW| literal 0 HcmV?d00001 diff --git a/msl-bot/bin/images/gem/gem-hp2.bmp b/msl-bot/bin/images/gem/gem-hp2.bmp new file mode 100644 index 0000000000000000000000000000000000000000..0962e66b538d2b4fb48079ac724db54edd4d86b8 GIT binary patch literal 1286 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 K#i|+3kp2U*;y&mA literal 2634 zcmdUwX;4#F6vye;j#)`aNWknb3yIki60(tnCLur)lb8eoZh!(6Q4w$hr2~o}t{@^- zu@o0@sfc4ctF1m$;nd& z@R!5auz4!(+-6DN1i0OCY9UaReB6d};J_*zxy4qX3#<0D|C1We8x-0Ba|bQYVhMi!arY)RZp9%mKm_;Q=NxXHM#$GUmYzGcX?_7GjDgbi4TN*CK| z-gwl!v0omnGuI!{tZc>Ni2}9DRC~bE^eU{VW1H;Frx*$|TVZpxy}>hj$&`fDV#i?VT*S^sumJ z0#BkCDm$X*9=N;TcD0WMj(=V<_Pf}#Qe+FqE>9_o8&Ot7v&b3^z5X@Gf|O_X)#&K` z@R_?996@3)1~Xk%r>1P{Tq3I2W?Op6CT4GrI!VdYD6{YP$uhQHzH^F;=q%u(t+ zI1w4WPolFV_L9=^N0x>Gw#u$AYXR1x-brE_&ADR~=6qY2skEBw`(Z9FC>PnIC~IsJ zutM%?g6m`BQ#ot)v6VKZw|dF&o$%Qo;H)H$lGyko{mb39twVE(sLQq`SOdpCTXOpD zW2`c3WaM7qp$Qy5mC2RUnOW8?uSGBZlA6Jhx|YNC>ZQ%#$(PxpqYqG464kP{r}WAr z$F^ZZRhP4UtYqw=xUeG03JJ~TYqFzFvCDtRLUoXrJc-fY_Ytt7ah+z}qhGxn0x_!y zu#(6$uEZE;{q8YVxed+&5`aKX&so`)*K#&^@^SBNpZOkx#U)sE)txMP zuD$8RY$8*-Rl61}z)%LU~=NM1%)-kTHfy5an99x{-tfFU|m%N`%P(< zHB+ceo&;s}9=;AefhEx7EZuIX>DE_wxjWx1x%69>YneR1yzJ^jzm^b>igP8O^UkKFV2-+)HMLDXn%p{%11 z3iiK;#S%DDi`W>Dn1T>~L~KxcDuE9w4|)(^YJoiV^?nH53K5%}+ecvTJA55#tLVV{ zB3+@3qw3Xrgf6yNhhah27UeLtlXz7$oymY>hyjnQHd31=-G)Sw(&-I{1ON zXVTyIad7aKp?qheb;enxRw#B5r7(qXMv%2|%Fxot&<_=P+VDn+IfS+gQH~T(Yxc9$ zjXdhBm+>a1^SXupStkf!eTF=*7T zS1#z6wI(7zf31J9L?kBY>Wc?%f~MTL!q+=#tnA<*=tpt>BhDJf<;$!RQ$T8s!hkj| u$}X6{%CjwnI&qEHq5w4`9{TyvQ1C?#83d|MMqH{eSTMESL`>UcJBj|IX7B|3UhZ^Cn2$pTECx znu)9yolUG;wj6H4hj^a*qyV3c? zx@F(F>0mqR<{81wM-LZJ{(1B9;s2*^uKoY{``iDcR~Ez7qT7p&4{{60%!UPK|3UVo z_wvE@BgawGLW}=jzrP2E!?{}<|KECiMVzrTZN zklvQXHekCh+}Q%oKh<+|;dXC0(g;>JcUuZv4B2jUHo99t=?|1&L1Bd)E--z)tGxd& z-&^t@RDNXj3&ZVbUSx%lZ!-D>{$4mKL(mY47E{NHh^@Bhxz6Ts;h z7i!sy%^XlTgVH4kgTfS94Jf`q;-Gwi TEI!Jne;a5t%tyl(crPxhloJL)gYO zTUW6~+$t(E;(hamRg(^}>3t=R7JY2pw1>TpW_+_5b~NN@{g@|MzJxw~7Jtf5b+DSo zcq86ojHc;xY^&)Yd2^l%U&qf$jv<_oBk5tKoF^=)Z{#OFyW>pk)>ch6y*-L)JF9HRa8C?WA~l!w>OoW$r8 zal$vk)P!7E+$wc>4{Acik+5R#uBSHaqRQcvv1Uy{Gsofxp~WG(=2GlDeiV%_tO%4vTSORrDb7Aax(dNb2^S*2h}GO+#?3gQ7_x86}+SEC|7mt z6K5pWtml6-bqQPxpbiWD^hTUa*zryXtz4i?)G9lNTZ~5 zY63^ZEGO_j>Z55cDQ04b@au89Zhb=;P^3PIPm{7=Z7X^7*%Y3c^BBcAE-{O0yPMm8 O-Z1cehTM+_GX5`wlp@0b literal 954 zcmZwFOHUI~7{+moOBW_agSNGFD$;V70wNa$%C)sXfeM!1OA9TRfkFkfRg_Q^jT!`R z3yHXJp{`9d8WUX^jd5j+iTDlp3V%;WofVV(PR`8adCxiTjJ4~{?i}ShE=IGk_n%!k z1~JRYSrYH}?fFZ2AO^YHPq49v672&Tsy|_|e5a=LA)c-i$k9$-Jk9X#=MUa){Z@S5 z+UCEho&brSAi+~koMqLxEEeo$Gw!w$Jg18kQJ00=*Cu%R;We*5e&hYuUwrws&9pP9 zWV88rM>i3xRn#b>wLBMRQ=VeDzk-o7l}rat;&3SU5 z6B_Kbx%4*aIn!#SuCP|z-zMn_?`WnsM5noi3WI^ZW+U#-0{mUYN;aEM4yTwOjO=K( zFN~|Ig<_3{Qr!WDY$k#|rD`^tzi>9HIzKqd`N5bXF%ZJtWTQrJLZ{JEC>|zt8juc39NvGJ1^>9}f?q}!YsUK{q~}vCFJ~C__A1$d4iolM1?21WnDQj@ zwR)}wCRFnQ8SiN?sqr++i`RJm`~|aP5oW^e$i7BAwj$~(Dyb?dr9hv@Vkn_Xh(66l z=aA(E?%jLB`r2bQ?muI5b(6KrH}KWh(_(26|4Snl$-+{2mZjk&SA)|`iSM%@a(C`L zVQpYuWBO`Nebu0nWtEsNU@$-XZ`Lbt2geGNna->dhh8t U%be)TQg}qHlU-|;WdAUK07byq?EnA( diff --git a/msl-bot/bin/images/misc/misc-guardian-right.bmp b/msl-bot/bin/images/misc/misc-guardian-right.bmp index 1cca6ae1249325adcfcd51db4ae41978b7b1995c..f10c6ed226aed573074803fff81faca7184e39d0 100644 GIT binary patch literal 954 zcmZvYT}V@57{?b~b`eAu-4#^SKt`oA6}PE3X*NbulH^C*oS#Y&q%6pEYq>U$J7=5V3`z=S(9-r{Gwt8=zGt%q9{8Q-J?DLY@AFZiAKk3rPa(bc z6I(NEQtYCYLNP%5+qTH?AN2AsEJ6Iaj8GztaPl`NNHIhNlS!G$03^2n$ukXcc9x%E z`?;<}-;6*ee*K<;+aHGD@n1mm;AccS1lSgcg4xvXsUgF)hr%M^2D= zl=C%x&(c1-o7E*I)*z01F*W8zV1n-DcV{B4na7y=^kcmj*#qX|Ky>~aCh1=P1ocD& zT?9peqAwJ|msk=~;*Xq*r`F}3=yPVxfe?L1J9 zo5y?5cftaP^A4ivG@mV-b#~5dE%&#Ek1?9Z!ZPymG*Bu_@W$l8g}PR>7@G0o<$KC2 z``LL&Y#xloI35j+Ait;zTCD+HN6Z*A58&eIR$Qv@L}ghmgzy|fan_TZkJat|979=| zi95_=IbXG0$6K=#)`qrqs%h`ay~h|Dcj5lC=O`{diqcX&G#Wj3^HmjaH(iCtXy@1) zJCKXDsT1{d$CJu79NJxgf<0$V~3CG{9w5T53PA#iVkDtsPdVsb6p312}X>)a@uigR&Yo4%Q%gJA%Jx#+$VO literal 954 zcmZXST})GF7=STedSSBLCB{qRofq5HF6JP5Y-fs0%}3RYTMZjSKT9+dxn@ ztv|)mQV1%Y)|Pgg*ebRK><~(O&Y=ei_LTla@M4KGdG__Ik{D0&eCIpo&2!%OyzlqL zCg1W3d3`F@HG-9ISyr)H>?$hGi13=KO454j1YYMqbhi%TY6)T5;^Ne?2%oI8&~f1@ zw)R;r{bX?byRv&kxcj!R=VVl_0EZ@7Q|HD32?&NVH_ zyhmyZY*}APPmiDL*YEK6Kn&+)FSgb{sHthD-sEHO9>Oi-x%(fd8*((53>wT?EOizU zixLcu6B$zJx$4K>?xCZ@N5j6rd#=;=ilzg?6YgQ*Mj|RhLkW_}9I@C8ZbwkMfk2A= zyZf-QK5WjB%;iw>d9-2?!!Ssv(`cGTWNeJk$Oy{J z4EAeYc5OUI{a&xE`A5qe(eHmz3kB(wTqQP)`k)uhcbkMVP4ID)a5N^r<@bd7_DdVv zKEK78AL5++eip4zM9pSV|Gb0d`c0y^t}r}2PD=DI6pAvLNTN-pNQ}>8slCni$`*EP zxQniedOd!U4hOp9nnbl*#mv&8ei56>;2R9{WHionenHkaX=Lf_dPvHBPkJRc>AX?K z)ydS0BAV#m)Li*KsT 0 Then @@ -62,7 +63,6 @@ Func Initialize() Next EndIf - Config_Update() CreateGUI() EndFunc diff --git a/msl-bot/profiles/gem_filters/premade_5star_4sub b/msl-bot/profiles/gem_filters/premade_5star_4sub new file mode 100644 index 00000000..1b2f8415 --- /dev/null +++ b/msl-bot/profiles/gem_filters/premade_5star_4sub @@ -0,0 +1,8 @@ +grade:5 +shape:any +type:leech,siphon,pugilist,ruin,intuition,conviction,protection,valor,life +stat:critrate,critdmg,hp%,attack%,defense% +sub1:critrate,critdmg,resist,hp%,attack%,defense% +sub2:critrate,critdmg,resist,hp%,attack%,defense% +sub3:critrate,critdmg,resist,hp%,attack%,defense% +sub4:critrate,critdmg,resist,hp%,attack%,defense% \ No newline at end of file diff --git a/msl-bot/profiles/gem_filters/premade_6star_2sub b/msl-bot/profiles/gem_filters/premade_6star_2sub new file mode 100644 index 00000000..34028980 --- /dev/null +++ b/msl-bot/profiles/gem_filters/premade_6star_2sub @@ -0,0 +1,6 @@ +grade:6 +shape:any +type:any +stat:any% +sub1:any% +sub2:any% \ No newline at end of file diff --git a/msl-bot/profiles/gem_filters/premade_6star_dragon b/msl-bot/profiles/gem_filters/premade_6star_dragon new file mode 100644 index 00000000..ea341238 --- /dev/null +++ b/msl-bot/profiles/gem_filters/premade_6star_dragon @@ -0,0 +1,7 @@ +grade:6 +shape:any +type:pugilist,siphon,leech +stat:hp%,defense%,attack%,critrate,critdmg +sub1:any% +sub2:any% +sub3:any% \ No newline at end of file diff --git a/msl-bot/profiles/gem_filters/premade_6star_healer b/msl-bot/profiles/gem_filters/premade_6star_healer new file mode 100644 index 00000000..107d1dd8 --- /dev/null +++ b/msl-bot/profiles/gem_filters/premade_6star_healer @@ -0,0 +1,6 @@ +grade:6 +shape:any +type:any +stat:hp%,defense% +sub1:recovery% +sub2:hp%,defense% \ No newline at end of file diff --git a/msl-bot/profiles/gem_filters/premade_6star_pvp b/msl-bot/profiles/gem_filters/premade_6star_pvp new file mode 100644 index 00000000..4e776125 --- /dev/null +++ b/msl-bot/profiles/gem_filters/premade_6star_pvp @@ -0,0 +1,6 @@ +grade:6 +shape:any +type:ruin,valor,intuition,pugilist +stat:hp%,attack%,defense%,critrate +sub1:resist +sub2:hp%,defense%,attack%,critrate \ No newline at end of file diff --git a/msl-bot/profiles/gem_filters/premade_6star_standard b/msl-bot/profiles/gem_filters/premade_6star_standard new file mode 100644 index 00000000..f4feeba1 --- /dev/null +++ b/msl-bot/profiles/gem_filters/premade_6star_standard @@ -0,0 +1,6 @@ +grade:6 +shape:any +type:ruin,intuition,conviction,protection,valor,life +stat:attack%,hp%,defense%,critrate,critdmg +sub1:attack%,hp%,defense%,critrate,critdmg,resist +sub2:attack%,hp%,defense%,critrate,critdmg,resist \ No newline at end of file