#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases. SendMode Input ; Recommended for new scripts due to its superior speed and reliability. SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory. CoordMode, Tooltip, Screen CoordMode, Pixel, Screen CoordMode, Mouse, Screen OnExit, Exit #Include, Gdip.ahk pToken := Gdip_Startup() global XOff global YOff global Seed global Tab := 4 global FriendsList global Ini := "Data.ini" global Delimiters := "|-" global Inventory := MultiplyString(SubStr(Delimiters, 1, 1), 27) IniRead, Seed, % Ini, Seed, Seed, Error If (Seed = "Error") IniWrite, % Seed := GSeed(SubStr(Delimiters, 1, 1)), % Ini, Seed, Seed ; Inventory(Pos, Type := 0, Move := 1, Section := "", RCoords := 0) ; WaitContains(Image, Colors, tSleep := 0) ; AreaContains(Image, Colors) ; Inv Grey: "55-85-50-75-40-70" ICount := 2 global Coordlist $Numpad9:: Msgbox % QuickText(XOff + 9 "|" YOff + 445 "|" 50 "|" 11, "0-15-0-15-0-15", "OCR Text", 3, 50, 1) Return $Numpad8:: Count++ If (Count > ICount) Count := 0 Grid%Count% := MarkGrid("0-140-165-255-125-255", 5, 5) Tooltip, % Grid%Count%, 0, % Round(A_ScreenHeight / 2) Return $Numpad4:: Loop, % ICount PrevC%A_Index% := SubStr(Grid%A_Index%, 1, InStr(Grid, SubStr(Delimiters, 1, 1),,, 2) - 1) InvCount := 25 Loop { Loop, % ICount { Index := A_Index SearchCount := 0 Coordlist := Coordlist%A_Index% PrevC%A_Index% := SearchGrid(PrevC%A_Index%, SubStr(Grid%A_Index%, InStr(Grid%A_Index%, SubStr(Delimiters, 1, 1),,, 2) + 1), "OCR Examine", "0-140-165-255-125-255", XOff + 7, YOff + 7, 100, 64, 32) Coordlist%A_Index% := Coordlist Loop { Start := A_TickCount If InStr(QuickText(XOff + 8 "|" YOff + 9 "|" 500 "|" 11, "0-140-165-255-125-255", "OCR Examine", 4, 50, 1), "Rocks") Send("LButton", 0, RSeed(50, 80), RSeed(50, 80)) Else SearchCount++ If (SearchCount > 3) { SearchGrid(PrevC%Index%, SubStr(Grid%Index%, InStr(Grid%Index%, SubStr(Delimiters, 1, 1),,, 2) + 1), "OCR Examine", "0-140-165-255-125-255", XOff + 7, YOff + 7, 100, 64, 32) SearchCount := 0 } Sleep % RSeed(50, 700) If InStr(QuickText(XOff + 9 "|" YOff + 445 "|" 50 "|" 11, "0-15-0-15-0-15", "OCR Text", 3, 50, 1), "Youswin") OR (A_Index > 2) AND AreaContains(Inventory(InvCount, 1, 0, "", 1), "55-85-50-75-40-70", 0, 1) Break } Area := Inventory(InvCount, 1, 1, "", 1) Sleep % RSeed(100, 200) WaitContains(Area, "55-85-50-75-40-70", RSeed(200, 300), 0, 1) QuickRCMenu(2, 4) Sleep % RSeed(100, 200) } } Return $Numpad1:: MouseGetPos, MX, MY Tooltip, % MX - XOff " and " MY - YOff " vs " MX " and " MY, 0, % Round(A_ScreenHeight / 2) Return $Numpad0:: OrionOffset() Return $NumpadDot:: Tooltip, Return OrionOffset() { WinGetActiveStats, T, W, H, X, Y XOff := X + 5 YOff := Y + 52 } SendCombo(Key1, Key2) { FirstKey := ((RSeed(1, 2) = 1) ? Key1 : Key2) Send % "{" FirstKey " Down}" Sleep % RSeed(15, 50) Send % "{" ((FirstKey = Key1) ? Key2 : Key1) " Down}" Sleep % RSeed(15, 50) Send % "{" Key1 " Up}" Sleep % RSeed(15, 50) Send % "{" Key2 " Up}" Sleep % RSeed(15, 50) } ; "190-255-190-255-175-255|155-255-105-170-30-130|195-255-195-255-0-150|0-140-165-255-125-255|0-100-135-255-0-100" ; Examine area QuickText(XOff + 8 "|" YOff + 9 "|" 500 "|" 11, "190-255-190-255-175-255|155-255-105-170-30-130|195-255-195-255-0-150|0-140-165-255-125-255|0-100-135-255-0-100", "OCR Examine", 4, 50, 1) ; Change times to not end in 0s all the time and widen if possible ; eventually pray + hp tracker, trade interaction ; (item identifier?), minimap interaction (+ icon search, building recognition?) ; countermeasures for endless loops*** ; add color for millions (GP) ; Drop-all itemname function MarkGrid(Colors, W, H) { MouseGetPos, MX, MY Text := QuickText(XOff + 8 "|" YOff + 9 "|" 500 "|" 11, Colors, "OCR Examine", 4, 50, 1) Return Floor((MX - XOff - 7) / W) "|" Floor((MY - YOff - 7) / H) "|" ((InStr(Text, "/")) ? SubStr(Text, 1, InStr(Text, 1, "/") - 1) : Text) "|" "|" W "|" H } ; AverageColor(Floor((MX - XOff - 7) / W) * W + XOff + 7 "|" Floor((MY - YOff - 7) / H) * H + YOff + 7 "|" W "|" H, "", "", 1) SearchGrid(Prev, Grid, Section, Colors, X1, Y1, W1 := 50, H1 := 32, Tolerance := 32) { XCoord := X1 + ReturnPos(Prev, 1, SubStr(Delimiters, 1, 1)) * ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) YCoord := Y1 + ReturnPos(Prev, 2, SubStr(Delimiters, 1, 1)) * ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)) Random, XR, 1, 3 Random, YR, 1, 3 tXC := XCoord + (XR - 2) * ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) tYC := YCoord + (YR - 2) * ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)) If (ReturnPos(Grid, 2, SubStr(Delimiters, 1, 1)) = "") ; AverageColor(tXC "|" tYC "|" ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) "|" ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)), ReturnPos(Grid, 2, SubStr(Delimiters, 1, 1))) { RandomBezier(0, 0, tXC + RSeed(0, ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) - 1), tYC + RSeed(0, ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)) - 1, 1), "t" RSeed(50, 80) " RO P3-10") Sleep % RSeed(100, 120) If InStr(QuickText(XOff + 8 "|" YOff + 9 "|" 500 "|" 11, Colors, Section, 4, 50, 1), ReturnPos(Grid, 1, SubStr(Delimiters, 1, 1))) { RCoord := Floor((tXC - X1) / ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1))) "|" Floor((tYC - Y1) / ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1))) If !InString(Coordlist, RCoord, "-") Coordlist := LTrim(Coordlist "-" RCoord, "-") Return RCoord } } If (Coordlist <> "") { Guess := ReturnPos(Coordlist, RSeed(1, CountVarBy(Coordlist, "-")), "-") RandomBezier(0, 0, X1 + SubStr(Guess, 1, InStr(Guess, "|") - 1) * ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) + RSeed(0, ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) - 1), Y1 + SubStr(Guess, InStr(Guess, "|") + 1) * ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)) + RSeed(0, ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)) - 1, 1), "t" RSeed(50, 80) " OT0 OB0 OL0 OR0 RO P3-10") Sleep % RSeed(100, 120) If InStr(QuickText(XOff + 8 "|" YOff + 9 "|" 500 "|" 11, Colors, Section, 4, 50, 1), ReturnPos(Grid, 1, SubStr(Delimiters, 1, 1))) Return Guess Else Coordlist := Trim(RegExReplace(Coordlist, "(-?)" SubStr(Guess, 1, InStr(Guess, "|") - 1) "\|" SubStr(Guess, InStr(Guess, "|") + 1) "(-?)", "-"), "-") } OSign := Sign := ((RSeed(1, 2) = 1) ? -1 : 1) ; Coordlist Loop { Index := A_Index Loop, 2 { Inner := A_Index Loop, % Index { If (Inner = 1) XCoord := XCoord + Sign * ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) Else If (Inner = 2) YCoord := YCoord + Sign * ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)) If (XCoord < X1) OR (XCoord > X1 + W1 * ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1))) OR (YCoord < Y1) OR (YCoord > Y1 + H1 * ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1))) Continue Running := 1 ;If !AverageColor(XCoord "|" YCoord "|" ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) "|" ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)), ReturnPos(Grid, 2, SubStr(Delimiters, 1, 1))) ; Continue RandomBezier(0, 0, XCoord + RSeed(0, ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1)) - 1), YCoord + RSeed(0, ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1)) - 1, 1), "t" RSeed(50, 80) " OT0 OB0 OL0 OR0 RO P3-6") Sleep % RSeed(100, 120) If InStr(QuickText(XOff + 8 "|" YOff + 9 "|" 500 "|" 11, Colors, Section, 4, 50, 1), ReturnPos(Grid, 1, SubStr(Delimiters, 1, 1))) Break 3 Else Coordlist := Trim(RegExReplace(Coordlist, "(-?)" Floor((XCoord - X1) / ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1))) "\|" Floor((YCoord - Y1) / ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1))) "(-?)", "-"), "-") } } Sign := ((A_Index / 2 = Ceil(A_Index / 2)) ? OSign : OSign * -1) If !Running AND !PrevRunning Return PrevRunning := Running Running := 0 } RCoord := Floor((XCoord - X1) / ReturnPos(Grid, 3, SubStr(Delimiters, 1, 1))) "|" Floor((YCoord - Y1) / ReturnPos(Grid, 4, SubStr(Delimiters, 1, 1))) If !InString(Coordlist, RCoord, "-") Coordlist := LTrim(Coordlist "-" RCoord, "-") Return RCoord } ; ItemName-Amount-Noted| DepositBoxInteract(Section, SubSection, DList) { NewInv := Inventory StringReplace, DList, DList, % A_Space,, All Loop { If (QuickText(XOff + 145 "|" YOff + 36 "|" 250 "|" 11, "155-255-110-170-30-130", Section, 4, 20) = "TheBankofRuneScape-DepositBox") Break Sleep % RSeed(200, 300) } Loop, Parse, DList, % SubStr(Delimiters, 1, 1) { LoopField := A_LoopField Loop, Parse, NewInv, % SubStr(Delimiters, 1, 1) If (A_LoopField = ReturnPos(LoopField, 1, SubStr(Delimiters, 2))) OR RegExMatch(A_LoopField, "i)([0-9]+)([+]" ReturnPos(LoopField, 1, SubStr(Delimiters, 2)) ")([" SubStr(Delimiters, 1, 1) "]|$)") AND ReturnPos(LoopField, 3, SubStr(Delimiters, 2)) { InvPos := A_Index Amount := DepositBoxGUI(A_Index, SubSection) Break } If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 1) Send("LButton", RSeed(100, 150), RSeed(30, 80)) Else If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 5) QuickRCMenu(2, 7) Else If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 10) QuickRCMenu(3, 7) Else If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "All") QuickRCMenu(4, 7) Else If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) > 1) { QuickRCMenu(5, 7) Loop { If (QuickText(XOff + 213 "|" YOff + 396 "|" 95 "|" 11, "0-15-0-15-0-15", Section, 4, 345) = "EnterAmount:") Break Sleep % RSeed(200, 300) } Type(ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) "{Enter}", StrLen(ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2))) * 60) WaitContains(DepositBoxGUI(InvPos, "", 1), "55-85-50-75-40-70", RSeed(200, 300), 0) } If ReturnPos(A_LoopField, 3, SubStr(Delimiters, 2)) StringReplace, NewInv, NewInv, % ReturnPos(NewInv, InvPos, SubStr(Delimiters, 1, 1)), % ((Amount - ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) > 0) ? Amount - ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) "+" ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) : "") Else NewInv := RPLInstance(NewInv, ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)), SubStr(Delimiters, 1, 1),, ((ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "All") ? 28 : ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)))) } RandomBezier(0, 0, XOff + RSeed(421, 446), YOff + RSeed(30, 50), "t" RSeed(30, 60) " RO P3-10") Send("LButton", RSeed(100, 150), RSeed(30, 70)) Loop { If (QuickText(XOff + 145 "|" YOff + 36 "|" 250 "|" 11, "155-255-110-170-30-130", Section, 4, 20) <> "TheBankofRuneScape-DepositBox") Break Sleep % RSeed(200, 300) } Return Inventory := NewInv } ; Type-AreaPos-RListPos QuickBankInteract(List, Section) { Loop { Text := ((ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) = "DB") ? QuickText(XOff + 145 "|" YOff + 36 "|" 250 "|" 11, "155-255-110-170-30-130", Section, 4, 20) : QuickText(XOff + 183 "|" YOff + 36 "|" 155 "|" 11, "155-255-110-170-30-130", Section, 4, 156)) If (Text = "TheBankofRuneScape") Break Sleep % RSeed(200, 300) } Loop, Parse, List, % SubStr(Delimiters, 1, 1) { If (ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) = "D") Inventory(ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)), 1) Else If (ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) = "W") BankGUI(ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2))) Else If (ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) = "DB") DepositBoxGUI(ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2))) Sleep % RSeed(50, 80) QuickRCMenu(ReturnPos(A_LoopField, 3, SubStr(Delimiters, 2)), 8) } RandomBezier(0, 0, XOff + ((ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) = "DB") ? RSeed(421, 446) : RSeed(475, 500)), YOff + RSeed(30, 50), "t" RSeed(30, 60) " RO P3-10") Send("LButton", RSeed(100, 150), RSeed(30, 70)) Loop { NewText := ((ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) = "DB") ? QuickText(XOff + 145 "|" YOff + 36 "|" 250 "|" 11, "155-255-110-170-30-130", Section, 4, 20) : QuickText(XOff + 183 "|" YOff + 36 "|" 155 "|" 11, "155-255-110-170-30-130", Section, 4, 156)) If (Text <> NewText) Break Sleep % RSeed(200, 300) } Return } ; BankInteract("OCR Examine", "OCR Subtext", "Shrimps-All|Cod-All-1|Green Partyhat-1|Arrow Shaft-5-1|Herring-10-1", "Shrimps-10-0-1|Green Partyhat-1|Cod-10-0-1|Coins-AB1-69-1") ; DList := "ItemName-Amount-Noted|ItemName-Amount-Noted|..." ; WList := "ItemName-Amount-Threshold-Noted|ItemName-Amount-Threshold-Noted|..." BankInteract(Section, SubSection, DList := 0, WList := "") ; Add Close option, Function for all and all but one as amount options, maybe 'all' and -1 and search to wait for text rather than some sleep amount { Note := Search := 0 Loop { If (QuickText(XOff + 183 "|" YOff + 36 "|" 155 "|" 11, "155-255-110-170-30-130", Section, 4, 156) = "TheBankofRuneScape") Break Sleep % RSeed(200, 300) } If (DList <> "") { StringReplace, DList, DList, % A_Space,, All If (DList = "All") OR (DList = 1) { RandomBezier(0, 0, RSeed(426, 461) + XOff, RSeed(287, 322, 1) + YOff, "t" RSeed(20, 80) " RO P3-10") Send("LButton", RSeed(100, 200), RSeed(20, 80), RSeed(600, 800)) Inventory := MultiplyString(SubStr(Delimiters, 1, 1), 27) } Else { NewInv := Inventory Loop, Parse, Inventory, % SubStr(Delimiters, 1, 1) { Found := NestedSearchPos(DList, SubStr(A_LoopField, ((InStr(A_LoopField, "+")) ? InStr(A_LoopField, "+") + 1 : 1)), ((InStr(A_LoopField, "+")) ? 1 : 0), 3) If Found { Obj := ReturnPos(DList, Found, SubStr(Delimiters, 1, 1)) If ReturnPos(Obj, 3, SubStr(Delimiters, 2)) AND InStr(A_LoopField, "+") OR !ReturnPos(Obj, 3, SubStr(Delimiters, 2)) AND !InStr(A_LoopField, "+") { Inventory(A_Index, 1) Sleep % RSeed(100, 150) If (ReturnPos(Obj, 2, SubStr(Delimiters, 2)) = "All") OR (ReturnPos(Obj, 2, SubStr(Delimiters, 2)) >= 28) AND !InStr(A_LoopField, "+") QuickRCMenu(6, 8) Else If (ReturnPos(Obj, 2, SubStr(Delimiters, 2)) = 1) Send("LButton", RSeed(50, 100), RSeed(50, 100), RSeed(50, 100)) Else If (ReturnPos(Obj, 2, SubStr(Delimiters, 2)) = 5) QuickRCMenu(2, 8) Else If (ReturnPos(Obj, 2, SubStr(Delimiters, 2)) = 10) QuickRCMenu(3, 8) Else { QuickRCMenu(5, 8) Loop { If (QuickText(XOff + 213 "|" YOff + 396 "|" 95 "|" 11, "0-15-0-15-0-15", Section, 4, 345) = "EnterAmount:") Break Sleep % RSeed(200, 300) } Type(ReturnPos(Obj, 2, SubStr(Delimiters, 2)) "{Enter}", StrLen(ReturnPos(Obj, 2, SubStr(Delimiters, 2))) * 60) WaitContains(Inventory(A_Index, 1, 0, "", 1), "55-85-50-75-40-70", RSeed(200, 300), 0) } } If ReturnPos(Obj, 3, SubStr(Delimiters, 2)) StringReplace, NewInv, NewInv, % A_LoopField, % ((SubStr(A_LoopField, 1, InStr(A_LoopField, "+") - 1) - ReturnPos(Obj, 2, SubStr(Delimiters, 2)) > 0) ? SubStr(A_LoopField, 1, InStr(A_LoopField, "+") - 1) - ReturnPos(Obj, 2, SubStr(Delimiters, 2)) "+" SubStr(A_LoopField, InStr(A_LoopField, "+") + 1) : "") Else NewInv := RPLInstance(NewInv, ReturnPos(Obj, 1, SubStr(Delimiters, 2)), SubStr(Delimiters, 1, 1),, ((ReturnPos(Obj, 2, SubStr(Delimiters, 2)) = "All") ? 28 : ReturnPos(Obj, 2, SubStr(Delimiters, 2)))) StringReplace, DList, DList, % Obj } } Inventory := NewInv } } If (WList <> "") { Loop, Parse, WList, % SubStr(Delimiters, 1, 1) { If !Search { RandomBezier(0, 0, RSeed(380, 415) + XOff, RSeed(287, 322) + YOff, "t" RSeed(50, 100) " RO P3-10") Send("LButton", RSeed(50, 100), RSeed(20, 70)) Loop { If (QuickText(XOff + 88 "|" YOff + 396 "|" 345 "|" 11, "0-15-0-15-0-15", Section, 4, 345) = "Showitemswhosenamescontainthefollowingtext:") Break Sleep % RSeed(200, 300) } Search := 1 } If (Note <> ReturnPos(A_LoopField, 4, SubStr(Delimiters, 2))) { RandomBezier(0, 0, ((Note = 1) ? RSeed(201, 285) : RSeed(286, 370)) + XOff, RSeed(302, 323) + YOff, "t" RSeed(50, 100) " RO P3-10") Send("LButton", RSeed(50, 100), RSeed(20, 70), RSeed(100, 150)) Note := !Note } Type(TempName := ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)), StrLen(ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2))) * 60) StringReplace, TempName, TempName, % A_Space,, All Sleep % RSeed(600, 700) WaitContains(BankGUI(1, "", 1), "55-85-50-75-40-70", RSeed(200, 300), 0, 1) Loop, 48 { Amount := BankGUI(A_Index, SubSection) If (QuickText(XOff + 9 "|" YOff + 9 "|" 500 "|" 11, "155-255-110-170-30-130", Section, 4, 100) = TempName) Break Index := A_Index } If (A_Index = 48) Continue If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "All") OR (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "AB1") QuickRCMenu(((ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "All") ? 6 : 7), 9) Else If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 1) Send("LButton", 0, RSeed(20, 80), RSeed(150, 200)) Else If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 5) QuickRCMenu(2, 9) Else If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 10) QuickRCMenu(3, 9) Else If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) > 1) { QuickRCMenu(5, 9) Loop { If (QuickText(XOff + 213 "|" YOff + 396 "|" 95 "|" 11, "0-15-0-15-0-15", Section, 4, 345) = "EnterAmount:") Break Sleep % RSeed(200, 300) } Type(ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) "{Enter}", 200) Search := 0 } If (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 1) OR (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 5) OR (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = 10) OR (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "All") OR (ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "AB1") Loop % StrLen(ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2))) Send("Backspace", 0, RSeed(50, 100)) If !ReturnPos(A_LoopField, 4, SubStr(Delimiters, 2)) Inventory := RPLInstance(Inventory, "", SubStr(Delimiters, 1, 1), ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)), ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2))) Else If !RegExMatch(Inventory, "i)([0-9]+)([+]" ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) ")([" SubStr(Delimiters, 1, 1) "]|$)", SubPat) Inventory := RPLInstance(Inventory, "", SubStr(Delimiters, 1, 1), ((ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "All" OR ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "AB1") ? Amount : ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2))) "+" ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2))) Else Inventory := RegExReplace(Inventory, "i)([0-9]+[+]" ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) ")([" SubStr(Delimiters, 1, 1) "]|$)", SubPat1 + ((ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "All" OR ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) = "AB1") ? Amount : ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2))) "+" ReturnPos(A_LoopField, 1, SubStr(Delimiters, 2)) "${2}") WReturn .= ((Amount - ReturnPos(A_LoopField, 2, SubStr(Delimiters, 2)) <= ReturnPos(A_LoopField, 3, SubStr(Delimiters, 2)) AND ReturnPos(A_LoopField, 3, SubStr(Delimiters, 2)) > 0) ? 1 : 0) } } RandomBezier(0, 0, XOff + RSeed(475, 500), YOff + RSeed(30, 50), "t" RSeed(30, 60) " RO P3-10") Send("LButton", RSeed(100, 150), RSeed(30, 70)) Loop { If (QuickText(XOff + 183 "|" YOff + 36 "|" 155 "|" 11, "155-255-110-170-30-130", Section, 4, 156) <> "TheBankofRuneScape") Break Sleep % RSeed(200, 300) } Return WReturn } ; OCR Examine + global FriendsList in ini, perhaps as an initialization function FLInteract(Player, Section, Message := "", FLSection := "", Delete := 0) { If (Tab <> 9) InventoryTabs(9) If !InStr(FriendsList, SubStr(Delimiters, 1, 1) Player SubStr(Delimiters, 1, 1)) { RandomBezier(0, 0, RSeed(562, 633) + XOff, RSeed(429, 464, 1) + YOff, "t" RSeed(30, 60) " RO P3-10") Send("LButton", RSeed(50, 100), RSeed(20, 50)) Loop { Sleep % ((A_Index > 1) ? RSeed(20, 30) * 10 : 0) If (QuickText(146 + XOff "|" 396 + YOff "|" 250 "|" 11, "0-20-0-20-0-20", Section, 4, 15, 1) = "Enternameoffriendtoaddtolist") Break } Type(Player "{Enter}", StrLen(Player) * 60) FriendsList .= Player SubStr(FriendsList, StrLen(FriendsList)) } If (Message <> "") { MouseGetPos, MX, MY If (MX - XOff < 555) OR (MX - XOff > 732) OR (MY - YOff < 230) OR (MY - YOff > 423) RandomBezier(0, 0, RSeed(555, 732) + XOff, RSeed(230, 423, 1) + YOff, "t" RSeed(30, 60) " RO P3-10") Loop { tImage := Gdip_BitmapFromScreen(XOff + 725 "|" YOff + 246 "|" 10 "|" 10) If ColorMatch(Gdip_GetPixel(tImage, 0, 0), "0-15-0-15-0-15", "-") Break Else { Send {WheelUp} Sleep % RSeed(100, 200) } Gdip_DisposeImage(tImage) } StringReplace, TempName, Player, % A_Space,, All Base := 232 Loop, 13 { Answer := FLMatch(FLSection, Base + ((A_Index - 1) * 15), TempName, A_Index) If (Answer > 0) OR (Answer = "E") Break Else If (A_Index = 13) { Loop { Send {WheelDown} Sleep % RSeed(100, 200) tImage := Gdip_BitmapFromScreen(XOff + 725 "|" YOff + 407 "|" 10 "|" 10) If ColorMatch(Gdip_GetPixel(tImage, 0, 0), "0-15-0-15-0-15", "-") ; At the bottom of Friends List Base := 226 Gdip_DisposeImage(tImage) Loop, 3 { Answer := FLMatch(FLSection, Base + ((A_Index + 9) * 15), TempName, A_Index + 10) If (Answer > 0) OR (Answer = "E") OR (A_Index = 3) AND (Base <> 232) Break 3 } } } } If (Answer <> "E") AND (Answer > 0) { RandomBezier(0, 0, RSeed(0, 95) + XOff + 557, RSeed(0, 14, 1) + YOff + Base + ((Answer - 1) * 15), "t" RSeed(30, 60) " RO P3-10") Send("LButton", RSeed(50, 100), RSeed(20, 50), RSeed(100, 200)) Loop, 10 { Sleep % ((A_Index > 1) ? RSeed(20, 30) * 10 : 0) If (QuickText(100 + XOff "|" 396 + YOff "|" 320 "|" 11, "0-20-0-20-0-20", Section, 4, 15, 1) = "Entermessagetosendto" TempName) Break Index := A_Index } If (Index < 10) OR (Index = "") Type(Message, StrLen(Message) * 50) Else Send("Enter", RSeed(50, 100), RSeed(20, 50), RSeed(50, 100)) } } If Delete { RandomBezier(0, 0, RSeed(642, 713), RSeed(429, 464, 1), "t" RSeed(30, 60) " RO P3-10") Send("LButton", RSeed(50, 100), RSeed(20, 50)) Loop { Sleep % ((A_Index > 1) ? RSeed(20, 30) * 10 : 0) If (QuickText(146 + XOff "|" 396 + YOff "|" 250 "|" 11, "0-20-0-20-0-20", Section, 4, 15, 1) = "Enternameoffriendtodeletefromlist") Break } Type(Player "{Enter}", StrLen(Player) * 50) StringReplace, FriendsList, FriendsList, % SubStr(Delimiters, 1, 1) Player SubStr(Delimiters, 1, 1) } Return Answer } FLMatch(Section, YPos, Search, Index) { Item := QuickText(XOff + 556 "|" YOff + YPos "|" 156 "|" 11, "240-255-240-255-240-255|30-120-170-230-30-120|200-255-200-255-0-50", Section, 4, 156) If RegExMatch(Item, "iA)" Search) AND (Item <> Search) Return Index Else If !InStr(Item, "World") AND !InStr(Item, "Lobby") Return "E" Return 0 } QuickRCMenu(Pos, Len := 4) { MouseGetPos, MX, MY Send("RButton",, RSeed(20, 50)) RandomBezier(0, 0, RSeed(-20, 20) + ((MX - XOff + 30 > 765) ? MX - 30 : MX), RSeed(0, 14, 1) + ((MY - YOff + Len * 15 > 482) ? 482 - (Len * 15) + YOff : MY) + (Pos - 1) * 15 + 19, "t" RSeed(30, 60) " OT0 OB0 OL0 OR0 RO P3-10") Return Send("LButton", RSeed(50, 80), RSeed(30, 50)) } ; ; Opt contains text for option, section is OCR Examine, Colors are all, Stop is distance w/o text to stop after, Length is qidth for QuickText, Contains is to choose an option that contains X RCMenu(Opt, Section := "", Colors := "", Stop := 50, Length := "", Contains := 0) { Send("RButton", 0, RSeed(20, 50), RSeed(100, 150)) MouseGetPos, MX, MY MX := MX - XOff MY := MY - YOff Image := Gdip_BitmapFromScreen(XOff "|" YOff "|" 765 "|" 503) Gdip_SaveBitmapToFile(Image, "File.png") Loop, % MY ; Search Up MY + YOff - UpIndex { UpIndex := A_Index - 1 If ColorMatch(Gdip_GetPixel(Image, MX, MY - UpIndex), "80-105-75-95-60-85", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX, MY - UpIndex + 1), "0-15-0-15-0-15", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX, MY - UpIndex + 2), "0-15-0-15-0-15", SubStr(Delimiters, 2)) { MatchCount := SType := 1 Loop, 6 { SIndex := ((SType) ? A_Index : SCount := SCount - 1) If ColorMatch(Gdip_GetPixel(Image, MX + SIndex, MY - UpIndex), "80-105-75-95-60-85", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX + SIndex, MY - UpIndex + 1), "0-15-0-15-0-15", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX + SIndex, MY - UpIndex + 2), "0-15-0-15-0-15", SubStr(Delimiters, 2)) MatchCount++ Else SType := SCount := 0 If (MatchCount = 6) Break 2 } } } Loop, % 503 - MY ; Search Down MY + Yoff + DIndex { DIndex := A_Index - 1 If ColorMatch(Gdip_GetPixel(Image, MX, MY + DIndex), "0-15-0-15-0-15", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX, MY + DIndex - 1), "80-105-75-95-60-85", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX, MY + DIndex - 2), "80-105-75-95-60-85", SubStr(Delimiters, 2)) { MatchCount := SType := 1 Loop, 3 { SIndex := ((SType) ? A_Index : SCount := SCount - 1) If ColorMatch(Gdip_GetPixel(Image, MX + SIndex, MY + DIndex), "0-15-0-15-0-15", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX + SIndex, MY + DIndex - 1), "80-105-75-95-60-85", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX + SIndex, MY + DIndex - 2), "80-105-75-95-60-85", SubStr(Delimiters, 2)) MatchCount++ Else SType := SCount := 0 If (MatchCount = 3) Break 2 } } } Loop, % MX { LIndex := A_Index - 1 If ColorMatch(Gdip_GetPixel(Image, MX - LIndex, MY - UpIndex + 1), "80-105-75-95-60-85", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX - LIndex + 1, MY - UpIndex + 1), "0-15-0-15-0-15", SubStr(Delimiters, 2)) Break } Loop, % 765 - MX { RIndex := A_Index - 1 If ColorMatch(Gdip_GetPixel(Image, MX + RIndex, MY - UpIndex + 1), "80-105-75-95-60-85", SubStr(Delimiters, 2)) AND ColorMatch(Gdip_GetPixel(Image, MX + RIndex - 1, MY - UpIndex + 1), "0-15-0-15-0-15", SubStr(Delimiters, 2)) Break } Gdip_DisposeImage(Image) XCoord := RSeed(1, LIndex + RIndex) If (Section <> "") AND (Colors <> "") AND RegExMatch(Opt, "i)[a-z]") { Loop, % (UpIndex + DIndex - 20) / 15 { If (QuickText(XOff + MX - LIndex + 3 "|" YOff + MY - UpIndex + (A_Index - 1) * 15 + 21 "|" ((Length = "") ? LIndex + RIndex : Length) "|" 11, Colors, Section, 4, Stop) = Opt) OR (Contains) AND InStr(QuickText(XOff + MX - LIndex + 3 "|" YOff + MY - UpIndex + (A_Index - 1) * 15 + 21 "|" ((Length = "") ? LIndex + RIndex : Length) "|" 11, Colors, Section, 4, Stop), Opt) { Opt := A_Index Break } } } Else If (Opt <= 0) Opt := Floor((UpIndex + DIndex - 20) / 15 + Opt) If Opt is digit { RandomBezier(0, 0, XCoord + XOff + MX - LIndex, RSeed(0, 14, 1) + YOff + MY - UpIndex + (Opt - 1) * 15 + 19, "t" RSeed(30, 60) " OT0 OB0 OL" ((XCoord > LIndex) ? LIndex : XCoord) " OR" LIndex + RIndex - ((XCoord < LIndex) ? LIndex : XCoord) " RO P3-10") Return Floor((UpIndex + DIndex - 20) / 15) Send("LButton", RSeed(30, 50), RSeed(30, 50)) } Return 0 } ; Only returns OY, YO should be the previous OY return in order to minimize search time. LaunchRS(YO := 0, W := 69) { IfWinNotExist, Old School RuneScape Game { Run % "http://oldschool" W ".runescape.com/j1" WinGetActiveStats, T, W, H, X, Y Sleep 5000 } WinActivate, Old School RuneScape Game WinWaitActive, Old School RuneScape Game WinGetActiveStats, T, W, H, X, Y If (W < 800) OR (H < 660) WinMove, Old School RuneScape Game, % X := 0, % Y := 0, % W := 800, % H := 860 pImage := Gdip_BitmapFromScreen(((X < 0) ? X := 0 : X) "|" ((Y < 0) ? Y := 0 : Y) "|" ((W > A_ScreenWidth) ? W := A_ScreenWidth : W) "|" ((H > A_ScreenHeight) ? H := A_ScreenHeight : H)) Loop, % Gdip_GetImageWidth(pImage) { XOff := ((A_Index = 1) ? Round(X + (W / 2) - 381) : A_Index - 2) Loop, % Gdip_GetImageHeight(pImage) { YCoord := ((A_Index = 1 AND YO > 0) ? YO - 27 : A_Index - 1) If ColorMatch(Gdip_GetPixel(pImage, XOff, YCoord), "0-15-0-15-0-15", "-") AND ColorMatch(Gdip_GetPixel(pImage, XOff, YCoord + 26), "0-15-0-15-0-15", "-") AND ColorMatch(Gdip_GetPixel(pImage, XOff - 1, YCoord + 27), "0-15-0-15-0-15", "-") AND ColorMatch(Gdip_GetPixel(pImage, XOff - 1, YCoord + 25), "1-255-1-255-1-255", "-") AND ColorMatch(Gdip_GetPixel(pImage, XOff - 2, YCoord + 25), "0-15-0-15-0-15", "-") Return YOff := YCoord + 27 } } } ; OCR Examine Login(User, Pass, Section) { Loop { Sleep % ((A_Index > 1) ? RSeed(10, 30) * 100 : 0) If (QuickText(418 + XOff "|" 285 + YOff "|" 100 "|" 11, "255-255-255-255-255-255|", Section, 4, 15, 1) = "ExistingUser") Break } RandomBezier(0, 0, RSeed(388, 537) + XOff, RSeed(271, 311, 1) + YOff, "t" RSeed(30, 100) * 10 " RO P3-10") Send("LButton", RSeed(20, 100), RSeed(20, 100), RSeed(20, 100)) Type(User "¤" Pass "¤", StrLen(User "¤" Pass "¤") * 50) Loop { Sleep % ((A_Index > 1) ? RSeed(10, 30) * 100 : 0) If (QuickText(361 + XOff "|" 331 + YOff "|" 150 "|" 11, "255-255-255-255-255-255|", Section, 4, 15, 1) = "CLICKHERETOPLAY") Break } RandomBezier(0, 0, RSeed(271, 499) + XOff, RSeed(293, 381, 1) + YOff, "t" RSeed(30, 100) * 10 " RO P3-10") Send("LButton", RSeed(20, 100), RSeed(20, 100), RSeed(20, 100)) Loop { Sleep % RSeed(10, 30) * 100 If (QuickText(361 + XOff "|" 331 + YOff "|" 150 "|" 11, "255-255-255-255-255-255|", Section, 4, 15, 1) <> "CLICKHERETOPLAY") Break } } ; OCR Examine Logout(Section) { If (Tab <> 11) InventoryTabs(11) Loop { RandomBezier(0, 0, RSeed(572, 712) + XOff, RSeed(359, 394) + YOff, "t" RSeed(30, 60) " RO P3-10") Send("LButton", RSeed(20, 50), RSeed(50, 100)) Sleep % ((A_Index > 1) ? RSeed(10, 30) * 100 : 0) If (QuickText(418 + XOff "|" 285 + YOff "|" 100 "|" 11, "255-255-255-255-255-255|", Section, 4, 15, 1) = "ExistingUser") Break } } ; | White | Orange | Yellow | Cyan | Green ; Returns the text within an image, Colors: "190-255-190-255-175-255|155-255-105-170-30-130|195-255-195-255-0-150|0-140-165-255-125-255|0-100-135-255-0-100" ; Image requires "X|Y|W|H", Delimiters: "|-", Data: OCR Section dumped into a var, Space: Maximum space between words to keep text color constant ; Stop: Streak of no-text to cease searching after QuickText(Image, Colors, Section, Space := 0, Stop := 10, StartColor := 0) { IniRead, Data, % Ini, % Section FoundPos := StartColor If InStr(Image, "|") Image := Gdip_BitmapFromScreen(Image) Gdip_SaveBitmapToFile(Image, "File.png") ;Image := Gdip_CreateBitmapFromFile("File.png") Height := Gdip_GetImageHeight(Image) Loop, % Gdip_GetImageWidth(Image) { XCoord := A_Index - 1 Loop, % Height { Container := InitialMatching(Gdip_GetPixel(Image, XCoord, A_Index - 1), Colors, FoundPos) FoundPos := SubStr(Container, 2) Addendum .= SubStr(Container, 1, 1) ; Addendum is either 1 or 0, so the position of the match in the 'colors' string is the data stored after it } ; This is necessary to prevent a yellow pixel from registering as text in the middle of a white word If (Addendum = 0) ; Only when a space (Space) is registered are the word colors allowed to change { ; If a stop is encountered then the image ceases being read (Stop must be > Space) Pixels .= "¤" Count := Count + 1 } Else { Pixels .= Addendum "¦" Count := 0 } If (Count > Stop) Break FoundPos := ((Count > Space) ? 0 : FoundPos) Addendum := } Gdip_DisposeImage(Image) Loop, Parse, Data, `n MaxIndex := A_Index Loop, Parse, Pixels, ¤ { Success := 0 If (%A_LoopField% <> "") Phrase .= %A_LoopField% Else If (%A_LoopField% = "") AND (A_LoopField <> "") { If InStr("`n" Data, "`n" A_LoopField "=") Phrase .= %A_LoopField% := SubStr("`n" Data, InStr("`n" Data, "`n" A_LoopField "=") + StrLen("`n" A_LoopField "="), 1) Else { Field := A_LoopField Loop, Parse, Data, `n { If (StrLen(Field) = StrLen(SubStr(A_LoopField, 1, InStr(A_LoopField, "=") - 1))) ; RegExMatch consuming whole key + search, break 2 releases from search methodology { ; Only needs to run once, first (bc it consumes whole search) StringReplace, Temp, Field, 1, \d, All If RegExMatch(A_LoopField, Temp) { Phrase .= SubStr(A_LoopField, InStr(A_LoopField, "=") + 1, 1) Success := 1 Break } } } If !Success ; The entire search string was not consumed, secondary efforts are necessary { ; First attempt: Look for exact matches of keys inside search, then remove/add/repeat using nested loops SearchField := Field ; If an entire data parse is completed without success (breaking) then break 2 runs and stops the nested loops Substitute := MultiplyString("¤", Height + 1) Loop { Loop, Parse, Data, `n { If (StrLen(SearchField) > StrLen(SubStr(A_LoopField, 1, InStr(A_LoopField, "=") - 1))) AND InStr(SearchField, SubStr(A_LoopField, 1, InStr(A_LoopField, "=") - 1)) AND (StrLen(A_LoopField) > (Height + 1) * 2 + 2) { StringReplace, Field, Field, % SubStr(A_LoopField, 1, InStr(A_LoopField, "=") - 1), % "¤" SubStr(A_LoopField, InStr(A_LoopField, "=") + 1, 1) "¤" StringReplace, SearchField, SearchField, % SubStr(A_LoopField, 1, InStr(A_LoopField, "=") - 1), % Substitute Break } If (A_Index = MaxIndex) Break 2 } } If (StrLen(Field) > Height + 1) ; If there are enough characters left (no character is only one pixel wide, hence this line) { ; Then we start this tertiary search method using the same basic algorithm Loop ; EXCEPT looking for floating matches, then removing from field/adding to phrase/breaking { Loop, Parse, Data, `n { If (StrLen(Field) > StrLen(SubStr(A_LoopField, 1, InStr(A_LoopField, "=") - 1))) { Found := FloatingBinMatch(SearchField, SubStr(A_LoopField, 1, InStr(A_LoopField, "=") - 1), Height + 1) If Found { StringReplace, Field, Field, % SubStr(SearchField, Found, StrLen(SubStr(A_LoopField, 1, InStr(A_LoopField, "=") - 1))), % "¤" SubStr(A_LoopField, InStr(A_LoopField, "=") + 1, 1) "¤" SearchField := LTrim(SubStr(SearchField, 1, Found - 1) Substitute SubStr(SearchField, Found + InStr(A_LoopField, "=") - 1), "¤") Break } } If (A_Index = MaxIndex) Break 2 } } } Loop, Parse, Field, ¤ If !Ceil(SubStr(A_Index / 2, InStr(A_Index / 2, "."))) Phrase .= A_LoopField } } } } Return Phrase } DepositBoxGUI(Pos, Section := "", RCoords := 0) { XCoord := XOff + 131 + (SubStr(Pos / 7, InStr(Pos / 7, ".")) * 7 - 1) * ((Floor(Pos / 7) = Ceil(Pos / 7)) ? -240 : 40) YCoord := YOff + 75 + Floor(Pos / 7) * 42 - ((Floor(Pos / 7) = Ceil(Pos / 7)) ? 42 : 0) If RCoords Return XCoord "|" YCoord "|" 32 "|" 32 RandomBezier(0, 0, RSeed(0, 31) + XCoord, RSeed(0, 31) + YCoord, "t" RSeed(20, 70) " RO P3-10") If (Section <> "") Return PAmount(QuickText(XCoord "|" YCoord "|" 36 "|" 9, "190-255-190-255-175-255|195-255-195-255-0-150", Section, 4, 10)) } ; OCR Subtext BankGUI(Pos, Section = "", RCoords := 0) { XCoord := XOff + 73 + (SubStr(Pos / 8, InStr(Pos / 8, ".")) * 8 - 1) * ((SubStr(Pos / 8, InStr(Pos / 8, ".")) = 0) ? -336 : 48) YCoord := YOff + 71 + Floor(Pos / 8) * 36 - ((Floor(Pos / 8) = Ceil(Pos / 8)) ? 36 : 0) If RCoords Return XCoord "|" YCoord "|" 36 "|" 32 RandomBezier(0, 0, RSeed(0, 35) + XCoord, RSeed(0, 31) + YCoord, "t" RSeed(30, 60) " RO P3-10") If (Section <> "") Return PAmount(QuickText(XCoord "|" YCoord "|" 36 "|" 9, "190-255-190-255-175-255|195-255-195-255-0-150", Section, 4, 10)) } CastSpell(Pos) { If Pos is not digit { StringReplace, Pos, Pos, % A_Space,, All ParseList := "Homeport|Weaken|WaterBolt|FaladorTeleport|Lvl-3Enchant|ChargeWaterOrb|ClawsofGuthix|ChargeAirOrb|Entangle|WindStrike|FireStrike|VarrockTeleport|CrumbleUndead|IbanBlast|lvl-4Enchant|FlamesofZamorak|Vulnerability|Stun|Confuse|BonestoBananas|Lvl-2Enchant|TeleporttoHouse|Snare|WatchtowerTeleport|TrollheimTeleport|Lvl-5Enchant|Charge|EnchantCrossbowBolt|WindBolt|EarthBolt|WindBlast|MagicDart|FireBlast|WindWave|EarthWave|TeleotherFalador|WaterStrike|Curse|LumbridgeTeleport|SuperheatItem|ArdougneTeleport|ChargeEarthOrb|ChargeFireOrb|Enfeeble|TeleBlock|Lvl-1Enchant|Bind|TelekineticGrab|CamelotTeleport|EarthBlast|BonestoPeaches|TeleporttoApeAtoll|TeleotherLumbridge|Lvl-6Enchant|EarthStrike|LowLevelAlchemy|FireBolt|WaterBlast|HighLevelAlchemy|SaradominStrike|WaterWave|FireWave|TeleotherCamelot" Loop, Parse, ParseList, | If (Pos = A_Loopfield) { Pos := A_Index Break } } If (Tab <> 7) InventoryTabs(7) RandomBezier(0, 0, RSeed(0, 23) + Floor(Pos / 9) * 24 + 559 + XOff - ((SubStr(Pos / 9, InStr(Pos / 9, ".")) = 0) ? 24 : 0), RSeed(0, 23, 1) + Round(SubStr(Pos / 9, InStr(Pos / 9, ".")) * 9 - 1) * 24 + YOff + 227 + ((Floor(Pos / 9) = Ceil(Pos / 9)) ? 216 : 0), "t" RSeed(30, 100) * 10 " RO P3-10") Send("LButton", RSeed(100, 150), RSeed(20, 50), RSeed(20, 50)) } InventoryTabs(Pos) { Loop { If (RSeed(0, 100) > SubStr(Seed, InStr(Seed,SubStr(Seed, StrLen(Seed)),,, 8) + 1, InStr(Seed, SubStr(Seed, StrLen(Seed)),,, 9) - InStr(Seed,SubStr(Seed, StrLen(Seed)),,, 8) - 1)) OR (Pos = 4) OR (Pos = 9) OR (Pos = 11) { RandomBezier(0, 0, RSeed(0, ((Pos != 1 AND Pos != 7 AND Pos != 8 AND Pos != 14) ? 32 : 37)) + XOff + ((SubStr(Pos / 7, InStr(Pos / 7, ".")) != SubStr(1 / 7, InStr(1 / 7, "."))) ? 5 : 0) + ((SubStr(Pos / 7, InStr(Pos / 7, ".")) != 0) ? Round(SubStr(Pos / 7, InStr(Pos / 7, ".")) * 7) * 33 + 489 : 720), RSeed(0, 35, 1) + YOff + ((Pos < 8) ? 168 : 466), "t" RSeed(100, 200) " RO P3-10") Send("LButton", RSeed(20, 50), RSeed(20, 50), RSeed(20, 50)) } Else { List := "F1|F2|F3||F4|F5|F6|F7||F9||F10|F11|F12" Loop, Parse, List, "|" If (A_Index = Pos) Send(A_LoopField, 0, RSeed(20, 50), RSeed(20, 50)) } Image := Gdip_BitmapFromScreen(XOff + ((SubStr(Pos / 7, InStr(Pos / 7, ".")) != SubStr(1 / 7, InStr(1 / 7, "."))) ? 5 : 0) + ((SubStr(Pos / 7, InStr(Pos / 7, ".")) != 0) ? Round(SubStr(Pos / 7, InStr(Pos / 7, ".")) * 7) * 33 + 489 : 720) "|" YOff + ((Pos < 8) ? 168 : 466) "|" ((Pos != 1 AND Pos != 7 AND Pos != 8 AND Pos != 14) ? 33 : 38) "|" 36) If (Gdip_RFromARGB(Gdip_GetPixel(Image, Round(Gdip_GetImageWidth(Image) / 2), 2)) > Gdip_GFromARGB(Gdip_GetPixel(Image, Round(Gdip_GetImageWidth(Image) / 2), 2)) + Gdip_BFromARGB(Gdip_GetPixel(Image, Round(Gdip_GetImageWidth(Image) / 2), 2))) { Gdip_DisposeImage(Image) Return Tab := Pos } Else Sleep % RSeed(200, 300) Gdip_DisposeImage(Image) } } ; Type is Vertical by default, other for horizontal Inventory(Pos, Type := 0, Move := 1, Section := "", RCoords := 0) { If (Tab <> 4) AND !RCoords InventoryTabs(4) XCoord := XOff + ((Type = 0) ? (SubStr(Pos / 7, 1, InStr(Pos / 7, ".") - 1) - ((SubStr(Pos / 7, InStr(Pos / 7, ".")) != 0) ? 0 : 1)) * 42 + 563 : ((SubStr(Pos / 4, InStr(Pos / 4, ".")) != 0) ? Round(SubStr(Pos / 4, InStr(Pos / 4, ".")) * 4 - 1) * 42 + 563 : 689)) YCoord := YOff + ((Type = 0) ? ((SubStr(Pos / 7, InStr(Pos / 7, ".")) != 0) ? Round(SubStr(Pos / 7, InStr(Pos / 7, ".")) * 7 - 1) * 36 + 213 : 429) : (SubStr(Pos / 4, 1, InStr(Pos / 4, ".") - 1) - ((SubStr(Pos / 4, InStr(Pos / 4, ".")) != 0) ? 0 : 1)) * 36 + 213) If (Move) RandomBezier(0, 0, RSeed(0, 31) + XCoord, RSeed(0, 31) + YCoord, "t" RSeed(100, 120) " RO P3-10") If (Section <> "") Return PAmount(QuickText(XCoord "|" YCoord "|" 36 "|" 9, "190-255-190-255-175-255|195-255-195-255-0-150", Section, 4, 10)) Return ((RCoords) ? XCoord "|" YCoord "|" 32 "|" 32 : "") } Prayer(Pos) { If (Tab <> 6) InventoryTabs(6) If Pos is not digit { List := "ThickSkin|BurstofStrength|ClarityofThought|SharpEye|MysticWill|RockSkin|SuperhumanStrength|ImprovedReflexes|RapidRestore|RapidHeal|ProtectItems|HawkEye|MysticLore|SteelSkin|UltimateStrength|IncredibleReflexes|ProtectfromMagic|ProtectfromMissiles|ProtectfromMelee|EagleEye|MysticMight|Retribution|Redemption|Smite|Chivalry|Piety" Loop, Parse, List, | { If (Pos = A_LoopField) { Pos := A_Index Break } } } RandomBezier(0, 0, RSeed(0, 29) + (SubStr(Pos / 5, InStr(Pos / 5, ".")) *5 - 1) * 37 + XOff + 553 + ((Floor(Pos / 5) = Ceil(Pos / 5)) ? 185 : 0), RSeed(0, 29, 1) + Floor(Pos / 5) * 37 + YOff + 216 - ((Floor(Pos / 5) = Ceil(Pos / 5)) ? 37 : 0), "t" RSeed(20, 50) " RO P3-10") Return Send("LButton", RSeed(30, 50), RSeed(30, 50)) } Type(Phrase, MS := 500) { Elapsed := 0 StringReplace, Phrase, Phrase, {Enter}, ¤, All Loop, Parse, Phrase { Avg := (MS - Elapsed) / ((StrLen(Phrase) - A_Index + 1) * 2) LoopField := ((A_LoopField = " ") ? "Space" : ((A_LoopField = "¤") ? "Enter" : A_LoopField)) T1 := Ceil(RSeed(0, Round(Avg * 1.1))) T2 := Ceil(RSeed(0, Round(Avg * 1.1), 1)) Sleep % T1 := ((T1 < 16) ? 0 : T1) Send % "{" LoopField " Down}" Sleep % T2 := ((T2 < 16) ? 0 : T2) Send % "{" LoopField " Up}" Elapsed := Elapsed + T1 + T2 } } Send(Char, B := 0, D := 0, A := 0) { Sleep % B Send % "{" Char " Down}" Sleep % D Send % "{" Char " Up}" Sleep % A } WaitContains(Image, Colors, tSleep := 0, All := 0, vNot := 0) { Loop { If AreaContains(Image, Colors, All, vNot) Return Sleep % tSleep } } AreaContains(Image, Colors, All := 0, vNot := 0) { Container := All Image := Gdip_BitmapFromScreen(Image) Loop, % Gdip_GetImageWidth(Image) { XCoord := A_Index - 1 Loop, % Gdip_GetImageHeight(Image) { PXValue := ((vNot) ? !SubStr(InitialMatching(Gdip_GetPixel(Image, XCoord, A_Index - 1), Colors, 0), 1, 1) : SubStr(InitialMatching(Gdip_GetPixel(Image, XCoord, A_Index - 1), Colors, 0), 1, 1)) If !All Container := ((PXValue > Container) ? PXValue : Container) Else Container := ((PXValue < Container) ? PXValue : Container) If Container AND !All Break 2 } } Gdip_DisposeImage(Image) Return Container } RSeed(Min, Max, Set := 0) { Seed_Array := StrSplit(Seed, SubStr(Seed, StrLen(Seed))) Return WRandomVertex(Min, Max, Min + Round((Max - Min) * Seed_Array[Set + 1] / 100), Seed_Array[Set + 3], Seed_Array[Set + 5], Seed_Array[Set + 7]) } ;Seed := Vertex|Exponent|Increment|Skew creates around 5.25m potentially distinct options, odds are seed1, evens are seed2 ; Vertex1 |Vertex2 |Exponent1 |Exponent2 |Increment1 |Increment2 |Skew1 |Skew2 |Choice (8-9 D) GSeed(Delimiter) { Return RReturn(10, 90) Delimiter RReturn(10, 90) Delimiter RReturn(.5, 3) Delimiter RReturn(.5, 3) Delimiter RReturn(.1, 2) Delimiter RReturn(.1, 2) Delimiter RReturn(0, 100) Delimiter RReturn(0, 100) Delimiter RReturn(20, 80) Delimiter } RReturn(Min, Max) { Random, Temp, Min, Max Return Temp } WRandomVertex(RangeMin, RangeMax, Vertex := "", Exponent := 2, Increment := .1, Skew := 0, Probability := "H", Display := 0) { Vertex := ((Vertex = "" OR Vertex < RangeMin OR Vertex > RangeMax) ? Round((RangeMax - RangeMin) / 2) : Vertex) Skew := ((Skew >= 0 AND Skew <= 100) ? Skew : 0) Loop, % Vertex - RangeMin LeftSum += (-(Abs(A_Index - (Vertex - RangeMin)) ** Exponent) + (((Vertex - RangeMin) ** Exponent))) Loop, % RangeMax - Vertex RightSum += (-(Abs(A_Index - (RangeMax - Vertex)) ** Exponent) + (((RangeMax - Vertex) ** Exponent))) If !(Probability >= 0 AND Probability <= 100) { Loop { Probability += Increment LeftSideProbability := (100 - Probability) * ((Vertex <> RangeMax AND Vertex <> RangeMin) ? (1 - Skew / 100) : 0) / (RangeMax - RangeMin) * (Vertex - RangeMin) + (100 - Probability) * ((Vertex <> RangeMax AND Vertex <> RangeMin) ? (Skew / 200) : 1) RightSideProbability := (100 - Probability) * ((Vertex <> RangeMax AND Vertex <> RangeMin) ? (1 - Skew / 100) : 0) / (RangeMax - RangeMin) * (RangeMax - Vertex) + (100 - Probability) * ((Vertex <> RangeMax AND Vertex <> RangeMin) ? (Skew / 200) : 1) If (Probability > ((Vertex - RangeMin) ** Exponent) / LeftSum * LeftSideProbability) AND (Probability > ((RangeMax - Vertex) ** Exponent) / RightSum * RightSideProbability) Break } } Else { LeftSideProbability := (100 - Probability) * ((Vertex <> RangeMax AND Vertex <> RangeMin) ? (1 - Skew / 100) : 0) / (RangeMax - RangeMin) * (Vertex - RangeMin) + (100 - Probability) * ((Vertex <> RangeMax AND Vertex <> RangeMin) ? (Skew / 200) : 1) RightSideProbability := (100 - Probability) * ((Vertex <> RangeMax AND Vertex <> RangeMin) ? (1 - Skew / 100) : 0) / (RangeMax - RangeMin) * (RangeMax - Vertex) + (100 - Probability) * ((Vertex <> RangeMax AND Vertex <> RangeMin) ? (Skew / 200) : 1) } Random, Random, 0, 100 Random := ((Display = 0) ? Random : 101) Loop, % RangeMax - RangeMin + 1 { If (A_Index = Vertex - RangeMin + 1) Value := Probability Else If (A_Index < Vertex - RangeMin + 1) Value := (((-(Abs(A_Index - Vertex + RangeMin)) ** Exponent) + ((Vertex - RangeMin) ** Exponent)) / LeftSum) * LeftSideProbability Else If (A_Index > Vertex - RangeMin + 1) Value := (((-(Abs(Vertex + 2 - RangeMin - A_Index)) ** Exponent) + ((RangeMax - Vertex) ** Exponent)) / RightSum) * RightSideProbability Remainder += SubStr(Value, 0) Value := SubStr(Value, 1, StrLen(Value) - 1) If (Remainder > 10) OR (Remainder > 0) AND (A_Index = RangeMax - RangeMin + 1) AND (Random - Value > 0) Remainder := Remainder - 10, Value := Value + .00001 If (0 >= Random -= Value) Return A_Index + RangeMin - 1 } Return RangeMax } PAmount(Amount) { If InStr(Amount, "k") Return RTrim(Amount, "k") * 1000 Else If InStr(Amount, "m") Return RTrim(Amount, "m") * 1000000 Return ((Amount = "") ? 0 : Amount) } RPLInstance(List, Instance, Delimiter, Replacement := "", Amnt := 1) { Count = 0 Loop, Parse, List, % Delimiter { NewList .= Delimiter If (A_LoopField = Instance) AND (Count < Amnt) { NewList .= Replacement Count++ } Else NewList .= A_LoopField } StringReplace, NewList, NewList, % Delimiter Return NewList } InString(String, Item, Delimiter) { Loop, Parse, String, % Delimiter If (A_LoopField = Item) Return 1 Return 0 } ReturnPos(String, Pos, Delimiter) { Loop, Parse, String, % Delimiter If (A_Index = Pos) Return A_LoopField Return 0 } NestedSearchPos(String, Search, 2Search := 0, 2Pos := 0) { Loop, Parse, String, % SubStr(Delimiters, 1, 1) { Index := A_Index LoopField := A_LoopField Loop, Parse, A_LoopField, % SubStr(Delimiters, 2) If (A_LoopField = Search) AND (A_Index = 1) AND (ReturnPos(LoopField, 2Pos, SubStr(Delimiters, 2)) = 2Search) Return Index } Return 0 } CountVarBy(Var, Delimiter) { Len := 0 Loop, Parse, Var, % Delimiter Len := A_Index Return Len } MultiplyString(String, Multiple) { Loop, % Multiple NewString .= String Return NewString } FloatingBinMatch(Bin1, Bin2, Increment := 1) { Large := ((StrLen(Bin1) >= StrLen(Bin2)) ? Bin1 : Bin2) Small := ((StrLen(Bin1) < StrLen(Bin2)) ? Bin1 : Bin2) Loop, % (StrLen(Large) - StrLen(Small)) / Increment + 1 { Float := SubStr(Large, (A_Index - 1) * Increment + 1, StrLen(Small)) StringReplace, Float, Float, 1, \d, All If RegExMatch(Small, Float) Return (A_Index - 1) * Increment + 1 } Return 0 } ; DelimiterList := "|-" ; Ex. 220-230-210-215-230-235|110-115-160-170-165-185 InitialMatching(Pixel, Colors, Pos := "") { Pos := ((Pos = "") ? 0 : Pos) Color_Array := StrSplit(Colors, SubStr(Delimiters, 1, 1)) If (Pos > 0) AND ColorMatch(Pixel, Color_Array[Pos], SubStr(Delimiters, 2, 1)) Return 1 Pos Else If (Pos > 0) Return 0 Pos Loop, % Color_Array.MaxIndex() If ColorMatch(Pixel, Color_Array[A_Index], SubStr(Delimiters, 2, 1)) Return 1 A_Index Return 0 Pos } ColorMatch(Pixel, Match, Delimiter) { RGB_Array := StrSplit(Match, Delimiter) If (Gdip_RFromARGB(Pixel) >= RGB_Array[1]) AND (Gdip_RFromARGB(Pixel) <= RGB_Array[2]) AND (Gdip_GFromARGB(Pixel) >= RGB_Array[3]) AND (Gdip_GFromARGB(Pixel) <= RGB_Array[4]) AND (Gdip_BFromARGB(Pixel) >= RGB_Array[5]) AND (Gdip_BFromARGB(Pixel) <= RGB_Array[6]) Return 1 Return 0 } AverageColor(Area, Colors := "", Tolerance := 32, Test := 0) { Image := Gdip_BitmapFromScreen(Area) Gdip_SaveBitmapToFile(Image, "File.png") Loop, % Gdip_GetImageWidth(Image) { XCoord := A_Index - 1 Loop, % Gdip_GetImageHeight(Image) { Count++ Red += Gdip_RFromARGB(Gdip_GetPixel(Image, XCoord, A_Index - 1)) Green += Gdip_GFromARGB(Gdip_GetPixel(Image, XCoord, A_Index - 1)) Blue += Gdip_BFromARGB(Gdip_GetPixel(Image, XCoord, A_Index - 1)) } } Gdip_DisposeImage(Image) If !Test AND (((Red / Count - ReturnPos(Colors, 1, SubStr(Delimiters, 2))) ** 2 + (Green / Count - ReturnPos(Colors, 2, SubStr(Delimiters, 2))) ** 2 + (Blue / Count - ReturnPos(Colors, 3, SubStr(Delimiters, 2))) ** 2) <= (Tolerance ** 2)) Return 1 Else If !Test Return 0 Return Red / Count "-" Green / Count "-" Blue / Count } ; This needs to reorder the .ini section too, so I don't need to do it manually ; ReadKey("Key.png", "Data.ini", "New", "1-255-1-255-1-255", "|-") ReadKey(File, Section, Colors, Stop := 10) { InputBox, Actual, Key Reader, Please input the key's actual data so we can create your .ini!`n`nNO SPACES! StringReplace, Actual, Actual, % A_Space,, All pImage := Gdip_CreateBitmapFromFile(File) Loop, % Gdip_GetImageWidth(pImage) { XCoord := A_Index - 1 Loop, % Gdip_GetImageHeight(pImage) { Container := InitialMatching(Gdip_GetPixel(pImage, XCoord, A_Index - 1), Colors, FoundPos) FoundPos := SubStr(Container, 2) Addendum .= SubStr(Container, 1, 1) } If (Addendum = 0) { Pixels .= "¤" Count := Count + 1 } Else { Pixels .= Addendum "¦" Count := 0 } If (Count > Stop) Break FoundPos := ((Count > Space) ? 0 : FoundPos) Addendum := } Gdip_DisposeImage(Image) Loop, Parse, Pixels, ¤ { If (A_LoopField = "") Continue AnotherCount++ %A_LoopField% := SubStr(Actual, AnotherCount, 1) TempList .= A_LoopField "¤" } TempList := RTrim(TempList, "¤") Sort, TempList, D¤ F IniSort Loop, Parse, TempList, ¤ IniWrite, % %A_LoopField%, % Ini, % Section, % A_LoopField Tooltip, Complete Return } IniSort(V1, V2) { V1Amnt := V2Amnt := 0 Loop, Parse, V1 If A_LoopField is digit V1Amnt := V1Amnt + A_LoopField Loop, Parse, V2 If A_LoopField is digit V2Amnt := V2Amnt + A_LoopField If (V1Amnt / StrLen(V1) > V2Amnt / StrLen(V2)) AND (StrLen(V1) = StrLen(V2)) OR (StrLen(V1) > StrLen(V2)) Return -1 Else If (V1Amnt / StrLen(V1) = V2Amnt / StrLen(V2)) AND (StrLen(V1) = StrLen(V2)) Return 0 Else If (V1Amnt / StrLen(V1) < V2Amnt / StrLen(V2)) AND (StrLen(V1) = StrLen(V2)) OR (StrLen(V1) < StrLen(V2)) Return 1 } RecordFL(Section) { FriendsList := If (Tab <> 9) InventoryTabs(9) MouseGetPos, MX, MY If (MX - XOff < 555) OR (MX - XOff > 710) OR (MY - YOff < 230) OR (MY - YOff > 423) RandomBezier(0, 0, RSeed(555, 710) + XOff, RSeed(230, 423, 1) + YOff, "t" RSeed(20, 50) " RO P3-10") Loop { tImage := Gdip_BitmapFromScreen(XOff + 725 "|" YOff + 246 "|" 10 "|" 10) If ColorMatch(Gdip_GetPixel(tImage, 0, 0), "0-15-0-15-0-15", "-") Break Else { Send {WheelUp} Sleep % RSeed(100, 200) } Gdip_DisposeImage(tImage) } Base := 232 Loop, 13 { FriendsList .= SubStr(Delimiters, 1, 1) QuickText(XOff + 556 "|" YOff + Base + ((A_Index - 1) * 15) "|" 96 "|" 11, "240-255-240-255-240-255", Section, 4, 156) If (A_Index = 13) { Loop { Send {WheelDown} Sleep % RSeed(100, 200) tImage := Gdip_BitmapFromScreen(XOff + 725 "|" YOff + 407 "|" 10 "|" 10) If ColorMatch(Gdip_GetPixel(tImage, 0, 0), "0-15-0-15-0-15", "-") Base := 226 Gdip_DisposeImage(tImage) Loop, 3 { If (Base = 232) FriendsList .= SubStr(Delimiters, 1, 1) QuickText(XOff + 556 "|" YOff + Base + ((A_Index + 9) * 15) "|" 96 "|" 11, "240-255-240-255-240-255", Section, 4, 156) Else If (Base <> 232) { Temp := QuickText(XOff + 556 "|" YOff + Base + ((A_Index + 9) * 15) "|" 96 "|" 11, "240-255-240-255-240-255", Section, 4, 156) If !InStr(FriendsList SubStr(Delimiters, 1, 1), SubStr(Delimiters, 1, 1) Temp SubStr(Delimiters, 1, 1)) FriendsList .= SubStr(Delimiters, 1, 1) Temp } If (A_Index = 3) AND (Base <> 232) Break 3 } } } } FriendsList .= SubStr(Delimiters, 1, 1) IniWrite, % FriendsList, % Ini, Seed, FriendsList } RecordInv(Section, SubSection) { Loop, 28 { Index := A_Index If !AreaContains(Inventory(Index, 1, 0, "", 1), "55-85-50-75-40-70", 0, 1) { Inv .= SubStr(Delimiters, 1, 1) Continue } Loop { Noted := Inventory(Index, 1, 1, SubSection) Text := QuickText(XOff + 9 "|" YOff + 9 "|" 500 "|" 11, "155-255-105-170-30-130", Section, 4, 50) If (Text <> "") Break Sleep % RSeed(200, 300) } Inv .= SubStr(Delimiters, 1, 1) ((Noted <> 0) ? Noted "+": "") Text } StringReplace, Inv, Inv, % SubStr(Delimiters, 1, 1) Return Inv } ; Add "OT0 OB0 OL0 OR0" to options to avoid movement outside box ; (0, 0, 400, 300) Moves to point (400, 300) from current ; (400, 300, 0, 0) Moves from point (400, 300) to current ; "OTx" (where x is a number) means Offset Top ; "OBx" (where x is a number) means Offset Bottom ; "OLx" (where x is a number) means Offset Left ; "ORx" (where x is a number) means Offset Right ; > These offsets, specified in pixels, are actually boundaries that ; apply to the [X0,Y0,Xf,Yf] rectangle, making it wider or narrower ; > It is possible to use multiple offsets at the same time ; > When not specified, an offset defaults to 100 ; - This means that, if none are specified, the random Bézier control ; points will be generated within a box that is wider by 100 pixels ; in all directions, and the trajectory will never go beyond that RandomBezier(V1, V2, V3, V4, V5) { Loop { RealBezier(V1, V2, V3, V4, V5) MouseGetPos, MX, MY If (MX = V3) AND (MY = V4) OR (MX = Floor(V3)) AND (MY = Floor(V4)) OR (MX = Ceil(V3)) AND (MY = Ceil(V4)) Break } } RealBezier(X0, Y0, Xf, Yf, O="" ) { Time := RegExMatch(O,"i)T(\d+)",M)&&(M1>0)? M1: 200 RO := InStr(O,"RO",0) , RD := InStr(O,"RD",0) N:=!RegExMatch(O,"i)P(\d+)(-(\d+))?",M)||(M1<2)? 2: (M1>19)? 19: M1 If ((M:=(M3!="")? ((M3<2)? 2: ((M3>19)? 19: M3)): ((M1=="")? 5: ""))!="") Random, N, %N%, %M% OfT:=RegExMatch(O,"i)OT(-?\d+)",M)? M1: 100, OfB:=RegExMatch(O,"i)OB(-?\d+)",M)? M1: 100 OfL:=RegExMatch(O,"i)OL(-?\d+)",M)? M1: 100, OfR:=RegExMatch(O,"i)OR(-?\d+)",M)? M1: 100 MouseGetPos, XM, YM If ( RO ) X0 += XM, Y0 += YM If ( RD ) Xf += XM, Yf += YM If ( X0 < Xf ) sX := X0-OfL, bX := Xf+OfR Else sX := Xf-OfL, bX := X0+OfR If ( Y0 < Yf ) sY := Y0-OfT, bY := Yf+OfB Else sY := Yf-OfT, bY := Y0+OfB Loop, % (--N)-1 { Random, X%A_Index%, %sX%, %bX% Random, Y%A_Index%, %sY%, %bY% } X%N% := Xf, Y%N% := Yf, E := ( I := A_TickCount ) + Time While ( A_TickCount < E ) { U := 1 - (T := (A_TickCount-I)/Time) Loop, % N + 1 + (X := Y := 0) { Loop, % Idx := A_Index - (F1 := F2 := F3 := 1) F2 *= A_Index, F1 *= A_Index Loop, % D := N-Idx F3 *= A_Index, F1 *= A_Index+Idx M:=(F1/(F2*F3))*((T+0.000001)**Idx)*((U-0.000001)**D), X+=M*X%Idx%, Y+=M*Y%Idx% } MouseMove, %X%, %Y%, 0 Sleep, 1 } MouseMove, X%N%, Y%N%, 0 Return N+1 } Exit: Gdip_Shutdown(pToken) ExitApp Return $F1::ExitApp $F2::ListVars $F3::Reload $F4::Pause