Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ;
- ; v1.0
- ; by Muche, parts by DevourlordGig
- ;
- #Persistent
- #NoEnv
- #Warn All
- ; Warn,LocalSameAsGlobal used to give way too many false positives
- ; I had to encapsulate a couple of subroutines into functions, so their variables could become local and don't clutter global variable space
- ;CoordMode, Tooltip, Relative
- CoordMode, Pixel, Client
- CoordMode, Mouse, Client
- SendMode Input
- Thread, NoTimers
- Thread, Interrupt, 60
- winName = Time Clickers ahk_class UnityWndClass
- IfWinNotExist, %winname%
- {
- MsgBox, Window '%winname%' not found`, exiting...
- ExitApp
- }
- showdebug := false ; show debug tooltips
- reqActiveWindow := true ; false - try to do stuff in the background, true - activate the window and do stuff in it in the foreground
- autoclick := false
- StartFromIdxWindowActive := 0 ; it would be better to initialize this near subroutines that use it, but can't, because apparently they are not in the autoexecute section of the script
- cooldown_time := 50*60*1000 ; cooldown time for cooldown active ability; changing it might need some scheduled actions to be moved around
- cooldown_delay := 2*60*1000 ; delay of the first cooldown active ability; changing it might need some scheduled actions to be moved around
- DimpsTest := false ; do Dimps' test - don't accumulate active ability time due to killed bosses' max.damage bonus for the first few minutes of the run
- DimpsTest_time := 10*60*1000 ; amount of time skipped; changing it might need some scheduled actions to be moved around
- ;
- ;
- ; Autoupgrader configuration
- ;
- ;
- autoupgrader := new CAutoupgrader
- autoupgrader.RegisterCallback("b", "Beeper")
- autoupgrader.RegisterCallback("A", "ClickUpgrade_A") ; direct nondelayed team upgrades, needed for priority actions to avoid deadlock
- autoupgrader.RegisterCallback("S", "ClickUpgrade_S")
- autoupgrader.RegisterCallback("D", "ClickUpgrade_D")
- autoupgrader.RegisterCallback("F", "ClickUpgrade_F")
- autoupgrader.RegisterCallback("G", "ClickUpgrade_G")
- autoupgrader.RegisterCallback(" ", "ClickAbility_space")
- autoupgrader.RegisterCallback("7", "ClickAbility_7")
- autoupgrader.RegisterCallback("p", "PriorityActions")
- autoupgrader.RegisterCallback("Q", "ClickDelayedUpgrade_A") ; delayed team upgrades, for usual cyclic upgrading
- autoupgrader.RegisterCallback("W", "ClickDelayedUpgrade_S")
- autoupgrader.RegisterCallback("E", "ClickDelayedUpgrade_D")
- autoupgrader.RegisterCallback("R", "ClickDelayedUpgrade_F")
- autoupgrader.RegisterCallback("T", "ClickDelayedUpgrade_G")
- autoupgrader.AddAction(1000, " pQ")
- autoupgrader.AddActionRelative(1000, " 7")
- autoupgrader.AddActionRelative(1000, " pW")
- autoupgrader.AddActionRelative(1000, " ")
- autoupgrader.AddActionRelative(1000, " pE")
- autoupgrader.AddActionRelative(1000, " ")
- autoupgrader.AddActionRelative(1000, " pR")
- autoupgrader.AddActionRelative(1000, " ")
- autoupgrader.AddActionRelative(1000, " pT")
- autoupgrader.AddActionRelative(1000, " ")
- ; autoupgrader's priority colors & actions configuration
- ; color scheme used requires Day mode and Post screen effects disabled
- ;
- ; RGB colors:
- ; 0x400000 (darkred) - SpecOps Training levelup available
- ; 0x800000 (darkred-mouseover)
- ; 0x000000 (black) - SpecOps initiation, availability unknown
- ; (black-mouseover=deepred)
- ; 0xFF7B00 (orange) - SpecOps skill available
- ; 0xFF9C3E (orange-mouseover)
- ; --------
- ; 0x29FF00 (lightgreen) - SpecOps levelup available
- ; 0x5EFF3E (lightgreen-mouseover)
- ; 0x200000 (deepred) - SpecOps Training levelup not available
- ; 0x401F00 (brown/darkorange) - SpecOps skill not available
- ; (darkorange-mouseover=darkorange)
- ; --------
- ; 0x0067FF (lightblue) - basic upgrade available
- ; 0x3E8DFF (lightblue-mouseover)
- ; 0x001A40 (darkblue) - no (basic) upgrade available
- ; 0x0A4000 (darkgreen) - SpecOps levelup not available
- ; (darkgreen-mouseover=darkgreen)
- ; team upgrade indicators
- autoupgrader.RegisterColor(0x400000, true, true, "darkred - SpecOps Training levelup")
- autoupgrader.RegisterColor(0x800000, true, true, "darkred-mouseover - SpecOps Training levelup")
- autoupgrader.RegisterColor(0x000000, true, true, "black - SpecOps initiation")
- autoupgrader.RegisterColor(0xFF7B00, true, false, "orange - SpecOps skill")
- autoupgrader.RegisterColor(0xFF9C3E, true, false, "orange-mouseover - SpecOps skill")
- autoupgrader.RegisterColor(0x29FF00, false, false, "lightgreen - SpecOps levelup")
- autoupgrader.RegisterColor(0x5EFF3E, false, false, "lightgreen-mouseover - SpecOps levelup")
- autoupgrader.RegisterColor(0x200000, false, true, "deepred - SpecOps Training levelup")
- autoupgrader.RegisterColor(0x401F00, false, false, "darkorange - SpecOps skill")
- autoupgrader.RegisterColor(0x0067FF, false, false, "lightblue - basic upgrade")
- autoupgrader.RegisterColor(0x3E8DFF, false, false, "lightblue-mouseover - basic upgrade")
- autoupgrader.RegisterColor(0x001A40, false, false, "darkblue - no (basic) upgrade")
- autoupgrader.RegisterColor(0x0A4000, false, false, "darkgreen - SpecOps levelup")
- autoupgrader.RegisterColor(0x294000, false, false, "darkgreen2 - SpecOps levelup")
- ; gold OP indicator
- autoupgrader.RegisterColor(0xFFE600, true, false, "yellow gold OP")
- ; TODO: these variables remain to clutter the global variable space, it would be better to enclose them in a function in the future
- x1 := 17, x2 := 102, x3 := 125
- yd := 96, y1 := 215, y3 := 229
- ;autoupgrader.AddPriorityAction(x1, y1, "A", "A_left")
- autoupgrader.AddPriorityAction(x2, y1, "A", "A_right")
- autoupgrader.AddPriorityAction(x3, y3, "AAA", "A_goldOP")
- ;autoupgrader.AddPriorityAction(x1, y1+yd, "S", "S_left")
- autoupgrader.AddPriorityAction(x2, y1+yd, "S", "S_right")
- autoupgrader.AddPriorityAction(x3, y3+yd, "SSS", "S_goldOP")
- ;autoupgrader.AddPriorityAction(x1, y1+2*yd, "D", "D_left")
- autoupgrader.AddPriorityAction(x2, y1+2*yd, "D", "D_right")
- autoupgrader.AddPriorityAction(x3, y3+2*yd, "DDD", "D_goldOP")
- ;autoupgrader.AddPriorityAction(x1, y1+3*yd, "F", "F_left")
- autoupgrader.AddPriorityAction(x2, y1+3*yd, "F", "F_right")
- autoupgrader.AddPriorityAction(x3, y3+3*yd, "FFF", "F_goldOP")
- ;autoupgrader.AddPriorityAction(x1, y1+4*yd, "G", "G_left")
- autoupgrader.AddPriorityAction(x2, y1+4*yd, "G", "G_right")
- autoupgrader.AddPriorityAction(x3, y3+4*yd, "GGG", "G_goldOP")
- ;autoupgrader.AddDelayCoord(x1, y1, "A_left")
- autoupgrader.AddDelayCoord(x2, y1, "A_right")
- ;autoupgrader.AddDelayCoord(x1, y1+yd, "S_left")
- autoupgrader.AddDelayCoord(x2, y1+yd, "S_right")
- ;autoupgrader.AddDelayCoord(x1, y1+2*yd, "D_left")
- autoupgrader.AddDelayCoord(x2, y1+2*yd, "D_right")
- ;autoupgrader.AddDelayCoord(x1, y1+3*yd, "F_left")
- autoupgrader.AddDelayCoord(x2, y1+3*yd, "F_right")
- ;autoupgrader.AddDelayCoord(x1, y1+4*yd, "G_left")
- autoupgrader.AddDelayCoord(x2, y1+4*yd, "G_right")
- ;
- ;
- ; Scheduler configuration
- ;
- ;
- scheduler := new CScheduler
- scheduler.RegisterCallback("b", "Beeper")
- scheduler.RegisterCallback("A", "ClickUpgrade_A")
- scheduler.RegisterCallback("S", "ClickUpgrade_S")
- scheduler.RegisterCallback("D", "ClickUpgrade_D")
- scheduler.RegisterCallback("F", "ClickUpgrade_F")
- scheduler.RegisterCallback("G", "ClickUpgrade_G")
- scheduler.RegisterCallback(" ", "ClickAbility_space")
- scheduler.RegisterCallback("7", "ClickAbility_7")
- scheduler.RegisterCallback("0", "ClickAbility_0")
- scheduler.RegisterCallback("m", "ClickBuyMode") ; the game uses Z for buy mode
- scheduler.RegisterCallback("c", "EnableAutoclick")
- scheduler.RegisterCallback("u", "EnableAutoupgrade")
- scheduler.RegisterCallback("W", "Warp")
- scheduler.RegisterCallback("R", "RestartScheduler")
- scheduler.RegisterCallback("[", "ClickIdleLauncher") ; the game uses Q for click launcher idle mode
- scheduler.RegisterCallback("]", "ClickIdleCannon") ; the game uses W for click cannon idle mode
- scheduler.RegisterCallback("\", "ClickIdlePistol") ; the game uses E for click pistol idle mode
- scheduler.RegisterCallback("p", "PriorityActions")
- if DimpsTest {
- scheduler.RegisterCallback("k", "UnlockAbilities")
- }
- scheduler.AddAction(1000, "[]", "disable click launcher & cannon") ; to improve performance during Overpowered waves on my old PC (framerate drop below 30 FPS with them enabled)
- if DimpsTest {
- scheduler.AddAction(DimpsTest_time, "k", "Unlock abilities - Dimps' test") ; may have to be moved if the DimpsTest_time is changed
- }
- scheduler.AddAction(17*60*1000, "[[", "enable click launcher") ; click launcher is OK in this phase, click cannon not, performance-wise
- scheduler.AddAction(20*60*1000, "b")
- scheduler.AddAction(21*60*1000, "bb")
- scheduler.AddAction((21*60+40)*1000, "FGb" , "2000|")
- scheduler.AddActionRelative(61*1000, "AA", "2100|")
- scheduler.AddActionRelative(63*1000, "SS", "2100|")
- scheduler.AddActionRelative(59*1000, "DDb", "2100|")
- scheduler.AddActionRelative(57*1000, "FF", "2100|")
- scheduler.AddActionRelative(58*1000, "GG", "2100|")
- scheduler.AddActionRelative(55*1000, "AA", "2200|")
- scheduler.AddActionRelative(55*1000, "SS", "2200|")
- scheduler.AddActionRelative(55*1000, "DDb", "2200|")
- scheduler.AddActionRelative(53*1000, "FF", "2200|")
- scheduler.AddActionRelative(53*1000, "GG", "2200|")
- scheduler.AddActionRelative(54*1000, "AA", "2300|")
- scheduler.AddActionRelative(55*1000, "SS", "2300|")
- scheduler.AddActionRelative(56*1000, "DDb", "2300|")
- scheduler.AddActionRelative(55*1000, "FF", "2300|")
- scheduler.AddActionRelative(55*1000, "GG", "2300|")
- scheduler.AddActionRelative(54*1000, "AA", "2400|")
- scheduler.AddActionRelative(55*1000, "SS", "2400|")
- scheduler.AddActionRelative(56*1000, "DDb", "2400|")
- scheduler.AddActionRelative(56*1000, "FF", "2400|")
- scheduler.AddActionRelative(53*1000, "GG", "2400|")
- scheduler.AddActionRelative(54*1000, "AA", "2500|")
- scheduler.AddActionRelative(55*1000, "SS", "2500|")
- scheduler.AddActionRelative(55*1000, "DDb", "2500|")
- scheduler.AddActionRelative(54*1000, "FF", "2500|")
- scheduler.AddActionRelative(54*1000, "GGbb", "2500|")
- scheduler.AddActionRelative((6*60+13)*1000, "AAAAAAb", "|2700+")
- if !DimpsTest {
- timediff := scheduler.AddAction(cooldown_delay + cooldown_time, "0", "#1")
- } else {
- timediff := 0
- }
- scheduler.AddActionRelative(93*1000 - timediff, "SSSSSSb", "|2700+")
- scheduler.AddActionRelative(83*1000, "DDDDDDb", "|2700+")
- scheduler.AddActionRelative(78*1000, "FFFFFFb", "|2700+")
- scheduler.AddActionRelative(72*1000, "GGGGGGAb", "|2700+")
- scheduler.AddActionRelative(68*1000, "ppAAASb", "|2800+")
- scheduler.AddActionRelative(67*1000, "ppSSSDb", "|2800+")
- scheduler.AddActionRelative(65*1000, "ppDDDFb", "|2800+")
- if DimpsTest {
- timediff := scheduler.AddAction(DimpsTest_time + cooldown_time, "0", "#1")
- } else {
- timediff := 0
- }
- scheduler.AddActionRelative(64*1000 - timediff, "ppFFFGb", "|2800+")
- scheduler.AddActionRelative(65*1000, "ppGGGAb", "|2800+")
- scheduler.AddActionRelative(63*1000, "ppAAASb", "|2900+")
- scheduler.AddActionRelative(70*1000, "ppSSSDb", "|2900+")
- scheduler.AddActionRelative(64*1000, "pDDDFb", "|2900+")
- scheduler.AddActionRelative(60*1000, "FFFGb", "|2900+")
- scheduler.AddActionRelative(58*1000, "GGGbb", "|2900+")
- scheduler.AddActionRelative(1000, "ASDFG")
- scheduler.AddActionRelative(1000, "mmm", "buy mode from Promotion to Upgrade")
- scheduler.AddActionRelative(1000, "cu", "enable autoclick and autoupgrade")
- scheduler.AddActionRelative(1000, "bbbb")
- if DimpsTest {
- scheduler.AddAction(DimpsTest_time + 2*cooldown_time, "0", "#2")
- } else {
- scheduler.AddAction(cooldown_delay + 2*cooldown_time, "0", "#2")
- }
- scheduler.AddActionRelative(cooldown_time, "0", "#3")
- timediff := scheduler.AddAction((2*3600+40*60)*1000, "]]", "enable click cannon")
- if !DimpsTest {
- scheduler.AddActionRelative(cooldown_time - timediff, "0", "#4")
- }
- scheduler.AddAction((4*3600+45*60+10*60)*1000, "bb 07 ", "last prewarp abilities usage")
- ; +10min due to halloween bonuses
- ; could be another +5min till max.damage time ends, but last 5min is crawl anyway so keeping it short for higher efficiency
- scheduler.AddActionRelative(3*60*1000, "bbbbbWbR", "Warp, restart scheduler")
- ;
- ;
- ; Utilities
- ;
- ;
- ; returns formatted time (_h__m__s)
- ; @param time integer time to be formatted (in milliseconds)
- ; @return string
- FormatTime(time) {
- if time is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . time . ")] time (" . time . ") is not an integer"
- return
- }
- if (time < 0) {
- time := Abs(time)
- sign := -1
- } else {
- sign := 1
- }
- h := time // 3600000
- m := mod(time, 3600000) // 60000
- s := mod(time, 60000) // 1000
- ms := mod(time, 1000)
- res := (sign < 0) ? "-" : ""
- if (h > 0) {
- res .= h . "h"
- }
- if (m < 10 && h > 0) {
- res .= "0" . m . "m"
- } else if (m > 0) {
- res .= m . "m"
- }
- if (s < 10 && (h > 0 || m > 0)) {
- res .= "0" . s . "s"
- } else {
- res .= s . "s"
- }
- /* ; is it useful to have milliseconds shown?
- if (ms > 0) {
- if (ms >= 100) {
- res .= ms . "ms"
- } else if (ms >= 10) {
- res .= "0" . ms . "ms"
- } else {
- res .= "00" . ms . "ms"
- }
- }
- */
- return res
- }
- tooltipoff:
- ToolTip
- return
- tooltipDoff:
- ToolTip, , , ,2
- return
- Beeper() {
- SoundBeep
- }
- ;
- ;
- ; Scheduler & Autoupgrader classes
- ;
- ;
- class CScheduler
- {
- regCallbacks := {} ; registered callbacks for actions; associative array, item is (key: function)
- actions := [] ; array of all timed actions; item is {time":time, "keys":keys, "comment":comment}
- started := false ; true if it's been started, remains true even if all actions were performed
- nextActionIdx := 0 ; index of next timed action to be performed when it's time
- timeStart := 0
- timeShift := 0 ; time shift, to allow interactive alteration of the timeline, in milliseconds
- ; registers callback for given key to be used in actions
- ; @param key 1-character string, not case sentitive
- ; @param funcname function name
- RegisterCallback(key, funcname) {
- if (StrLen(key) != 1) {
- MsgBox, % "[" . A_ThisFunc . "(" . key . "," . funcname . ")] key's length is " . StrLen(key) . ", expected 1"
- return
- }
- param := IsFunc(funcname)
- if (!param) {
- MsgBox, % "[" . A_ThisFunc . "(" . key . "," . funcname . ")] parameter '" . funcname . "' is not a function"
- return
- }
- if (param > 1) {
- MsgBox, % "[" . A_ThisFunc . "(" . key . "," . funcname . ")] function '" . funcname . "' requires " . (param-1) . " parameter(s), expected 0"
- return
- }
- if (this.regCallbacks[key]) {
- MsgBox, % "[" . A_ThisFunc . "(" . key . "," . funcname . ")] callback for key '" . key . "' already registered to '" . (this.regCallbacks[key]) . "'"
- return
- }
- this.regCallbacks[key] := funcname
- }
- ; checks if each key in keys has a registered callback
- ; @return true/false
- CheckKeys(keys) {
- Loop, % StrLen(keys) {
- key := SubStr(keys, A_Index, 1)
- if (!this.regCallbacks.HasKey(key)) {
- return false
- }
- }
- return true
- }
- ; adds new action at the end of the array of actions
- ; @param time integer time at which (or later) this action should be executed, in milliseconds
- ; @param keys string sequence of letters, each of which describes what will be executed via its callback
- ; @param comment string
- ; @return integer time difference from previous action, 0 if there is no previous action, in milliseconds
- AddAction(time, keys, comment := "") {
- if time is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . time . "," . keys . "," . comment . ")] time (" . time . ") is not an integer"
- return
- }
- if (time < 0) {
- MsgBox, % "[" . A_ThisFunc . "(" . time . "," . keys . "," . comment . ")] time (" . time . ") is negative"
- return
- }
- if (!this.CheckKeys(keys)) {
- MsgBox, % "[" . A_ThisFunc . "(" . time . "," . keys . "," . comment . ")] some of keys '" . keys . "' have no registered callback"
- return
- }
- if (this.actions.Length() > 0) {
- lastAction := this.actions[this.actions.Length()]
- if (time < lastAction.time) {
- MsgBox, % "[" . A_ThisFunc . "(" . time . "," . keys . "," . comment . ")] time (" . time . " - " . FormatTime(time) . ") is earlier than last action's time (" . lastAction.time . " - " . FormatTime(lastAction.time) . ")"
- } else {
- this.actions.Push({"time": time, "keys": keys, "comment": comment})
- return (time - lastAction.time)
- }
- } else {
- this.actions.Push({"time": time, "keys": keys, "comment": comment})
- return 0
- }
- }
- ; adds new action at the end, time is relative to the last action's time
- ; @param timerel integer time difference from the last action at which (or later) this action should be executed, in milliseconds
- ; @param keys string sequence of letters, each of which describes what will be executed via its callback
- ; @param comment string
- AddActionRelative(timerel, keys, comment := "") {
- if timerel is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . timerel . "," . keys . "," . comment . ")] timerel (" . timerel . ") is not an integer"
- return
- }
- if (timerel < 0) {
- MsgBox, % "[" . A_ThisFunc . "(" . timerel . "," . keys . "," . comment . ")] timerel (" . timerel . ") is negative"
- return
- }
- if (this.actions.Length() <= 0) {
- MsgBox, % "[" . A_ThisFunc . "(" . timerel . "," . keys . "," . comment . ")] last action not found"
- return
- }
- if (!this.CheckKeys(keys)) {
- MsgBox, % "[" . A_ThisFunc . "(" . timerel . "," . keys . "," . comment . ")] some of keys '" . keys . "' have no registered callback"
- return
- }
- lastAction := this.actions[this.actions.Length()]
- newtime := lastAction.time + timerel
- this.actions.Push({"time": newtime, "keys": keys, "comment": comment})
- }
- ; start timer
- Start() {
- this.nextActionIdx := 1
- this.timeStart := A_TickCount
- this.timeShift := 0
- this.started := true
- }
- ; starts timer with alternative first action
- ; @param idx integer index of the first executed action
- StartFromIndex(idx) {
- if idx is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . idx . ")] idx (" . idx . ") is not an integer"
- return
- }
- if (idx < 1) {
- MsgBox, % "[" . A_ThisFunc . "(" . idx . ")] idx (" . idx . ") is less than 1"
- return
- }
- if (idx > this.actions.Length()) {
- MsgBox, % "[" . A_ThisFunc . "(" . idx . ")] idx (" . idx . ") is greater than number of actions (" . this.actions.Length() . ")"
- return
- }
- this.nextActionIdx := idx
- this.timeStart := A_TickCount
- this.timeShift := -this.actions[idx].time
- this.started := true
- }
- Stop() {
- this.nextActionIdx := 0
- this.timeStart := 0
- this.timeShift := 0
- this.started := false
- }
- ; executes the next action if it's time for it
- ; @return boolean true if there are more actions waiting, false otherwise
- Next() {
- elapsedTime := A_TickCount - this.timeStart - this.timeShift
- nextAction := this.actions[this.nextActionIdx]
- if nextAction {
- if (elapsedTime >= nextAction.time) {
- this.nextActionIdx++ ; increase index first, so restarting this scheduler within callback is correct
- ; execute scheduled action
- keys := nextAction.keys
- old_IsCritical := A_IsCritical
- Critical
- Loop, % StrLen(keys) {
- key := SubStr(keys, A_Index, 1)
- funcname := this.regCallbacks[key]
- %funcname%()
- }
- Critical, %old_IsCritical%
- }
- }
- return (this.nextActionIdx <= this.actions.Length())
- }
- ; returns next scheduled action, with time property updated to reflect passed time since start
- ; @return false if no next action exists, {"time":time, "keys":keys, "comment":comment} otherwise
- GetNextActionRelative() {
- nextAction := this.actions[this.nextActionIdx]
- if nextAction {
- newTime := nextAction.time - (A_TickCount - this.timeStart - this.timeShift)
- return {"time": newTime, "keys": nextAction.keys, "comment": nextAction.comment}
- } else {
- return false
- }
- }
- ; returns time elapsed since the start (timeshift not taken into account)
- ; @return integer
- GetElapsedTime() {
- return A_TickCount - this.timeStart
- }
- ; shifts perceived time so next scheduled action is executed earlier/later
- ; @param time integer shift next actions' time earlier (negative number) / later (positive number)
- ShiftTime(time) {
- if time is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . time . ")] time (" . time . ") is not an integer"
- return
- }
- this.timeShift += time
- }
- ; returns timeshift
- ; @return integer
- GetShiftTime() {
- return this.timeShift
- }
- ; returns basic description
- ; @return string
- GetDescription() {
- n := this.actions.Length()
- return "Number of scheduled actions: " . n . ", last action at " . FormatTime(this.actions[n].time)
- }
- ; returns time till last scheduled action
- ; @return integer, or empty if scheduled hasn't been started yet or there are no actions scheduled
- GetRemainingTime() {
- n := this.actions.Length()
- lastAction := this.actions[n]
- if (!lastAction || !this.started) {
- return
- }
- return (lastAction.time - (A_TickCount - this.timeStart - this.timeShift))
- }
- ; adds scheduled actions into specified listbox
- ; @param listbox string name of the listbox variable
- AddListBoxItems(listbox) {
- Loop, % this.actions.Length() {
- action := this.actions[A_Index]
- s := A_index . ". " . FormatTime(action.time) . " (" . action.keys . ")" . (action.comment ? " - " . action.comment : "")
- GuiControl, , %listbox%, %s%
- }
- ; preselect active pending action if applicable
- if (this.started && this.nextActionIdx <= this.actions.Length()) {
- GuiControl, Choose, %listbox%, % this.nextActionIdx
- }
- }
- }
- class CAutoupgrader extends CScheduler
- {
- colors := {} ; associative array of colors approved for priority & delay upgrade, item is (color: {"priority":boolean, "delay":boolean, "comment":comment})
- priorityActions := [] ; array of all priority actions, item is {"coords":{"x":x, "y":y}, "keys":keys, "comment":comment}
- delayCoords := [] ; array of all delaying coordinates, item is {"coords":{"x":x, "y":y}, "comment":comment}
- ; executes the next action if it's time for it
- ; restarts scheduled actions if there are no more actions
- ; @return boolean true if there are more actions waiting, false otherwise
- ; @Override
- Next() {
- elapsedTime := A_TickCount - this.timeStart - this.timeShift
- nextAction := this.actions[this.nextActionIdx]
- if nextAction {
- if (elapsedTime >= nextAction.time) {
- this.nextActionIdx++ ; increase index first, so restarting this scheduler within callback is correct
- ; execute scheduled action
- keys := nextAction.keys
- old_IsCritical := A_IsCritical
- Critical
- Loop, % StrLen(keys) {
- key := SubStr(keys, A_Index, 1)
- funcname := this.regCallbacks[key]
- %funcname%()
- }
- Critical, %old_IsCritical%
- if (this.nextActionIdx > this.actions.Length()) {
- this.Start()
- }
- }
- }
- return (this.nextActionIdx <= this.actions.Length())
- }
- ; registers color to be used in priority actions & delaying coordinates
- ; @param color integer colorID, usually specified in 0xRRGGBB format
- ; @param priority boolean true - color is used for priority actions, false - color is used for debugging/displaying purposes only
- ; @param delay boolean true - color is used for delaying coordinates, false - color is used for debugging/displaying purposes only
- ; @param comment string
- RegisterColor(color, priority, delay, comment := "") {
- if color is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . color . "," . priority . "," . delay . "," . comment . ")] color (" . color . ") is not an integer"
- return
- }
- if (this.colors[color]) {
- otherColor := this.colors[color]
- MsgBox, % "[" . A_ThisFunc . "(" . color . "," . priority . "," . delay . "," . comment . ")] color (" . color . ") has already been registered to (" . otherColor.priority . "," . otherColor.delay . "," . otherColor.comment . ")"
- return
- }
- this.colors[color] := {"priority": priority, "delay": delay, "comment": comment}
- }
- ; adds priority action
- ; @param x integer x-coordinate of the pixel to be checked
- ; @param y integer y-coortinate of the pixel to be checked
- ; @param keys string sequence of letters, each of which describes what will be executed via its callback
- ; @param comment string
- AddPriorityAction(x, y, keys, comment := "") {
- if x is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . x . "," . y . "," . keys . "," . comment . ")] x (" . x . ") is not an integer"
- return
- }
- if y is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . x . "," . y . "," . keys . "," . comment . ")] y (" . y . ") is not an integer"
- return
- }
- if (!this.CheckKeys(keys)) {
- MsgBox, % "[" . A_ThisFunc . "(" . x . "," . y . "," . keys . "," . comment . ")] some of keys '" . keys . "' have no registered callback"
- return
- }
- this.priorityActions.Push({"coords":{"x":x, "y":y}, "keys":keys, "comment":comment})
- }
- ; collects information about priority actions & current colors they reference
- ; assumes the game window is active, otherwise pixel color detection won't work
- ; @return string
- GetPriorityActionsStatus() {
- s := ""
- Loop, % this.priorityActions.Length() {
- action := this.priorityActions[A_Index]
- PixelGetColor, pixelColor, action.coords.x, action.coords.y, RGB
- color := this.colors[pixelColor]
- s .= (StrLen(s) > 0) ? "`n" : ""
- s .= "[" . action.coords.x . "," . action.coords.y . "] (" . action.keys . ")" . (action.comment ? " - " . action.comment : "") . ", color=" . pixelColor
- if color {
- s .= ", priority=" . (color.priority ? "true" : "false") . ", delay=" . (color.delay ? "true" : "false") . (color.comment ? ", comment=" . color.comment : "")
- } else {
- s .= " (color not recognized)"
- }
- }
- return s
- }
- ; checks priority actions and executes them if applicable
- ; assumes the game window is active, otherwise pixel color detection won't work
- ; @return string info about executed actions, empty string if none were executed
- CheckPriorityActions() {
- s := ""
- Loop, % this.priorityActions.Length() {
- action := this.priorityActions[A_Index]
- PixelGetColor, pixelColor, action.coords.x, action.coords.y, RGB
- color := this.colors[pixelColor]
- if (color && color.priority) {
- ; priority action is activated, execute it
- keys := action.keys
- s .= (StrLen(s) > 0) ? "`n" : ""
- s .= "[" . action.coords.x . "," . action.coords.y . "] (" . keys . ")" . (action.comment ? " - " . action.comment : "") . ", color=" . pixelColor
- s .= (color.comment ? ", colorComment=" . color.comment : "")
- old_IsCritical := A_IsCritical
- Critical
- Loop, % StrLen(keys) {
- key := SubStr(keys, A_Index, 1)
- funcname := this.regCallbacks[key]
- %funcname%()
- }
- Critical, %old_IsCritical%
- }
- }
- return s
- }
- ; adds delaying coordinates
- ; @param x integer x-coordinate of the pixel to be checked
- ; @param y integer y-coortinate of the pixel to be checked
- ; @param comment string
- AddDelayCoord(x, y, comment := "") {
- if x is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . x . "," . y . "," . comment . ")] x (" . x . ") is not an integer"
- return
- }
- if y is not integer
- {
- MsgBox, % "[" . A_ThisFunc . "(" . x . "," . y . "," . comment . ")] y (" . y . ") is not an integer"
- return
- }
- this.delayCoords.Push({"coords":{"x":x, "y":y}, "comment":comment})
- }
- ; collects information about delaying coordinates & current colors they reference
- ; @return string
- GetDelayStatus() {
- s := ""
- Loop, % this.delayCoords.Length() {
- coord := this.delayCoords[A_Index]
- PixelGetColor, pixelColor, coord.coords.x, coord.coords.y, RGB
- color := this.colors[pixelColor]
- s .= (StrLen(s) > 0) ? "`n" : ""
- s .= "[" . coord.coords.x . "," . coord.coords.y . "]" . (coord.comment ? " - " . coord.comment : "") . ", color=" . pixelColor
- if color {
- s .= ", priority=" . (color.priority ? "true" : "false") . ", delay=" . (color.delay ? "true" : "false") . (color.comment ? ", comment=" . color.comment : "")
- } else {
- s .= " (color not recognized)"
- }
- }
- return s
- }
- ; checks priority actions and executes them if applicable
- ; assumes the game window is active
- ; @return boolean true if delay is active, false otherwise
- CheckDelayCoords() {
- Loop, % this.delayCoords.Length() {
- coord := this.delayCoords[A_Index]
- PixelGetColor, pixelColor, coord.coords.x, coord.coords.y, RGB
- color := this.colors[pixelColor]
- if (color && color.delay) {
- ; delay is activated
- return true
- }
- }
- return false
- }
- }
- ;
- ;
- ; Game interaction / Callback functions
- ;
- ;
- ; upgrade given team member
- ; @param key string key to send to upgrade the member
- ; @param posx integer x-position of the member's button
- ; @param posy integer y-position of the member's button
- ClickUpgrade(key, posx, posy) {
- global winName, reqActiveWindow
- if reqActiveWindow {
- currentWinID := 0
- IfWinNotActive, %winName%
- {
- currentWinID := WinActive("A")
- WinActivate, %winname%
- }
- Send, %key%
- Sleep, 200 ; increased delay to improve reliability - very important for scheduler, not so much for autoupgrader
- if (currentWinID != 0) {
- WinActivate, ahk_id %currentWinID%
- }
- } else {
- ; ControlSend seems to send keys into the buffer, buffer gets executed only after the window gets activated, which we don't want to in this case
- ; ControlClick seems to click only to window, not the specified position
- ; ControlClick, % "x" . posx . " y" . posy, %winName%
- ControlClick2(posx, posy, winName)
- Sleep, 200 ; increased delay to improve reliability - very important for scheduler, not so much for autoupgrader
- }
- }
- ClickUpgrade_A() {
- ClickUpgrade("a", 70, 245)
- }
- ClickUpgrade_S() {
- ClickUpgrade("s", 70, 340)
- }
- ClickUpgrade_D() {
- ClickUpgrade("d", 70, 445)
- }
- ClickUpgrade_F() {
- ClickUpgrade("f", 70, 545)
- }
- ClickUpgrade_G() {
- ClickUpgrade("g", 70, 645)
- }
- ClickAbility_space() {
- ClickUpgrade("{Space}", 1200, 525)
- }
- ClickAbility_7() {
- ClickUpgrade("7", 1075, 475)
- }
- ClickAbility_0() {
- ClickUpgrade("0", 1245, 475)
- }
- ; change idle mode of click launcher
- ClickIdleLauncher() {
- ClickUpgrade("q", 385, 700)
- }
- ; change idle mode of click cannon
- ClickIdleCannon() {
- ClickUpgrade("w", 580, 700)
- }
- ; change idle mode of click pistol
- ClickIdlePistol() {
- ClickUpgrade("e", 890, 700)
- }
- ; checks autoupgrader's delaying coordinates if allowed
- ; @return boolean true if the delay is activated, false otherwise
- CheckDelay() {
- global winName, reqActiveWindow, autoupgrader
- if !reqActiveWindow {
- return false
- }
- currentWinID := 0
- IfWinNotActive, %winName%
- {
- currentWinID := WinActive("A")
- WinActivate, %winname%
- }
- b := autoupgrader.CheckDelayCoords()
- if (currentWinID != 0) {
- WinActivate, ahk_id %currentWinID%
- }
- return b
- }
- ClickDelayedUpgrade_A() {
- if !CheckDelay() {
- ; ToolTip, Team upgrade A without delay, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- ClickUpgrade_A()
- } else {
- ; ToolTip, Team upgrade A delayed, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- }
- }
- ClickDelayedUpgrade_S() {
- if !CheckDelay() {
- ; ToolTip, Team upgrade S without delay, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- ClickUpgrade_S()
- } else {
- ; ToolTip, Team upgrade S delayed, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- }
- }
- ClickDelayedUpgrade_D() {
- if !CheckDelay() {
- ; ToolTip, Team upgrade D without delay, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- ClickUpgrade_D()
- } else {
- ; ToolTip, Team upgrade D delayed, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- }
- }
- ClickDelayedUpgrade_F() {
- if !CheckDelay() {
- ; ToolTip, Team upgrade F without delay, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- ClickUpgrade_F()
- } else {
- ; ToolTip, Team upgrade F delayed, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- }
- }
- ClickDelayedUpgrade_G() {
- if !CheckDelay() {
- ; ToolTip, Team upgrade G without delay, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- ClickUpgrade_G()
- } else {
- ; ToolTip, Team upgrade G delayed, 50, 0, 2
- ; SetTimer, tooltipdoff, -2000
- }
- }
- ; click buy mode (upgrade selector)
- ; @param count integer number of times it should be clicked
- ClickBuyMode(count := 1) {
- global winName, reqActiveWindow
- if (count < 1) {
- ; display just tooltip, not MsgBox, in case it's part of scheduler, and we don't want to stop it
- ToolTip, % "[" . A_ThisFunc . "(" . count . ")] count (" . count . ") is less than 1. WHY?", 50, 50
- SetTimer, tooltipoff, -2000
- return
- }
- if reqActiveWindow {
- currentWinID := 0
- IfWinNotActive, %winName%
- {
- currentWinID := WinActive("A")
- WinActivate, %winname%
- }
- Loop, %count% {
- Send, Z
- Sleep, 200 ; increased delay to improve reliability - very important for scheduler, not so much for autoupgrader
- }
- if (currentWinID != 0) {
- WinActivate, ahk_id %currentWinID%
- }
- } else {
- ; ControlSend seems to send keys into the buffer, buffer gets executed only after the window gets activated, which we don't want to in this case
- ; ControlClick seems to click only to window, not the specified position
- ; ControlClick, % "x" . posx . " y" . posy, %winName%
- Loop, %count% {
- ControlClick2(35, 700, winName)
- Sleep, 200 ; increased delay to improve reliability - very important for scheduler, not so much for autoupgrader
- }
- }
- }
- ; needed for Dimps' test
- UnlockAbilities() {
- global winName
- ; abilities unlocking
- ToolTip, [UnlockAbilities] Unlocking abilities..., 50, 50
- SetTimer, tooltipoff, -2500
- Loop, 10 {
- ClickUpgrade("c", 1220, 330)
- }
- ; use abilities - potentially increase max.damage time; they will have enough time for cooldown anyways
- ToolTip, [UnlockAbilities] Using abilities..., 50, 50
- SetTimer, tooltipoff, -2000
- ClickAbility_7()
- ClickAbility_space()
- ClickAbility_0()
- }
- PriorityActions() {
- global winName, reqActiveWindow, showdebug, autoupgrader
- if reqActiveWindow {
- ; priority actions require active window
- currentWinID := 0
- IfWinNotActive, %winName%
- {
- currentWinID := WinActive("A")
- WinActivate, %winname%
- }
- s := autoupgrader.CheckPriorityActions()
- if (showdebug && StrLen(s)>0) {
- ToolTip, % "Priority actions executed:`n" . s, 50, 0, 2
- SetTimer, tooltipDoff, -10000
- }
- if (currentWinID != 0) {
- WinActivate, ahk_id %currentWinID%
- }
- }
- }
- ;
- ;
- ; Warp
- ;
- ;
- ; asks user for confirmation to do warp
- ; @return boolean true if user confirmed, false otherwise
- AskWarp() {
- MsgBox, % 1+32, , Make sure the Buy mode is on Upgrade`, otherwise team upgrades will be incorrect after the warp.`nContinue?, 10
- IfMsgBox, OK
- {
- return true
- } else IfMsgBox, Cancel
- {
- return false
- } else IfMsgBox, Timeout
- {
- return false
- } else {
- return false
- }
- }
- ; Assumes the buy mode is on Upgrade!
- ; @param interactive boolean function is interactive, i.e. is allowed to ask the user questions and such
- Warp(interactive := false) {
- global winName, reqActiveWindow, DimpsTest
- ; disable autoclick and autoupgrade
- ToolTip, [Warp] Disabling autoclick and autoupgrade..., 50, 50
- SetTimer, tooltipoff, -2000
- SetAutoclick(false, false)
- SetAutoupgrade(false, false)
- Sleep, 2000
- old_IsCritical := A_IsCritical
- Critical
- ; activate the window (overriding reqActiveWindow setting)
- ToolTip, [Warp] Activating the window..., 50, 50
- SetTimer, tooltipoff, -2000
- currentWinID := 0
- IfWinNotActive, %winName%
- {
- currentWinID := WinActive("A")
- WinActivate, %winname%
- }
- oldReqActiveWindow := reqActiveWindow
- reqActiveWindow := true
- ; ask for confirmation if allowed
- ; TODO: check Buy mode automatically and warn the user if incorrect
- if (interactive && !AskWarp()) {
- ; warp cancelled
- reqActiveWindow := oldReqActiveWindow
- if (currentWinID != 0) {
- WinActivate, ahk_id %currentWinID%
- }
- Critical, %old_IsCritical%
- ToolTip, [Warp] Warp cancelled., 50, 50
- SetTimer, tooltipoff, -5000
- return
- }
- ; warp
- ToolTip, [Warp] Warping..., 50, 50
- SetTimer, tooltipoff, -5500
- ControlClick2(1220, 330, winName)
- Sleep, 500
- ControlClick2(540, 530, winName) ; yes
- Sleep, 5000
- ; click pistol upgrades
- ToolTip, [Warp] Upgrading click pistol..., 50, 50
- SetTimer, tooltipoff, -3500
- Loop, 13 {
- ClickUpgrade("H", 1220, 240)
- }
- if !DimpsTest {
- ; abilities unlocking
- ToolTip, [Warp] Unlocking abilities..., 50, 50
- SetTimer, tooltipoff, -2500
- Loop, 10 {
- ClickUpgrade("C", 1220, 330)
- }
- ; use abilities - increase max.damage time; they will have enough time for cooldown anyways
- ; team upgrades trigger overpowered mode very quickly, so have to use abilities before them to gain any benefit
- ToolTip, [Warp] Use initial abilities..., 50, 50
- SetTimer, tooltipoff, -2000
- ClickAbility_7()
- ClickAbility_space()
- ClickAbility_0()
- }
- ; team upgrades
- ToolTip, [Warp] Upgrading team (buy mode: Upgrade->Max)..., 50, 50
- SetTimer, tooltipoff, -2000
- ClickBuyMode(2)
- ToolTip, [Warp] Upgrading team (phase 1: Max)..., 50, 50
- SetTimer, tooltipoff, -3000
- Loop, 3 { ; Level 2000|
- ClickUpgrade_A()
- ClickUpgrade_S()
- ClickUpgrade_D()
- }
- Loop, 2 { ; Level |1000
- ClickUpgrade_F()
- ClickUpgrade_G()
- }
- ToolTip, [Warp] Upgrading team (buy mode: Max->Promotion)..., 50, 50
- SetTimer, tooltipoff, -2000
- ClickBuyMode(3)
- ToolTip, [Warp] Upgrading team (phase 2: Promotion)..., 50, 50
- SetTimer, tooltipoff, -8000
- Loop, 19 { ; Level |1900+
- ClickUpgrade_F()
- ClickUpgrade_G()
- }
- ; idle mode: rocket launcher & click pistol
- ToolTip, [Warp] Enabling idle mode for rocket launcher & click pistol..., 50, 50
- SetTimer, tooltipoff, -2000
- ControlClick2(800, 300, winName) ; click in the middle of the window, so the Particle Ball tooltip disappears - isn't needed anymore in v1.3 due to hotkeys
- Sleep, 200
- ClickIdleLauncher() ; idle mode: rocket launcher
- ClickIdleCannon() ; idle mode: click cannon
- ClickIdlePistol() ; idle mode: click pistol
- reqActiveWindow := oldReqActiveWindow
- if (currentWinID != 0) {
- WinActivate, ahk_id %currentWinID%
- }
- Critical, %old_IsCritical%
- ToolTip, [Warp] Warp finished., 50, 50
- SetTimer, tooltipoff, -5000
- }
- ;
- ;
- ; Autoclick control
- ;
- ;
- ; enable/disable autoclick
- ; @param status boolean new status
- ; @param display boolean display tooltip with new status
- SetAutoclick(status, display := true) {
- global autoclick
- if status {
- autoclick := true
- SetTimer, autoclicker, 30
- if display {
- ToolTip, Autoclick enabled, 50, 50
- SetTimer, tooltipoff, -2000
- }
- } else {
- autoclick := false
- SetTimer, autoclicker, Off
- if display {
- ToolTip, Autoclick disabled, 50, 50
- SetTimer, tooltipoff, -2000
- }
- }
- }
- EnableAutoclick() {
- SetAutoclick(true, false)
- }
- ; toggle autoclick
- #c:: ; Win+C
- SetAutoclick(!autoclick, true)
- return
- autoclicker:
- ControlClick2(800, 300, winName)
- return
- ;
- ;
- ; Autoupgrade control
- ;
- ;
- ; enable/disable autoupgrader
- ; @param status boolean new status
- ; @param display boolean display tooltip with new status
- SetAutoupgrade(status, display := true) {
- global autoupgrader
- if status {
- autoupgrader.Start()
- SetTimer, autoupgraderTimer, 1000
- if display {
- ToolTip, Autoupgrader enabled, 50, 50
- SetTimer, tooltipoff, -2000
- }
- } else {
- autoupgrader.Stop()
- SetTimer, autoupgraderTimer, Off
- if display {
- ToolTip, Autoupgrader disabled, 50, 50
- SetTimer, tooltipoff, -2000
- }
- }
- }
- EnableAutoupgrade() {
- SetAutoupgrade(true, false)
- }
- ;toggle autoupgrader
- #m:: ; Win+M
- SetAutoupgrade(!autoupgrader.started, true)
- return
- AutoupgraderTimer() {
- global showdebug, autoupgrader
- n := autoupgrader.Next()
- if (false && showdebug) {
- nextAction := autoupgrader.GetNextActionRelative()
- if nextAction {
- t := "Next action in " . FormatTime(nextAction.time) . " (" . nextAction.keys . ")" . (nextAction.comment ? " - " . nextAction.comment : "")
- } else {
- t := "No next action found"
- }
- ToolTip, % "[AutoupgraderTimer] " . t, 50, 0, 2
- SetTimer, tooltipDoff, -1250 ; higher than timer's 1000ms to avoid flickering
- }
- if (!n) {
- ; all scheduled actions finished, why didn't autoupgrader autorestart? Are there any actions scheduled at all?
- MsgBox, [AutoupgraderTimer] No next action found`, are there any actions scheduled at all?
- }
- }
- autoupgraderTimer:
- AutoupgraderTimer()
- return
- ;
- ;
- ; Scheduler control
- ;
- ;
- RestartScheduler() {
- global scheduler
- SetAutoupgrade(false, false)
- scheduler.Start()
- SetTimer, schedulerTimer, 1000
- ToolTip, % "Scheduler restarted - " . scheduler.GetDescription(), 50, 50
- SetTimer, tooltipoff, % -10000
- }
- ; start scheduler
- ^!s:: ; Ctrl+Alt+S
- SetAutoupgrade(false, false)
- scheduler.Start()
- SetTimer, schedulerTimer, 1000
- ToolTip, % "Scheduler started - " . scheduler.GetDescription(), 50, 50
- SetTimer, tooltipoff, % -10000
- return
- SchedulerTimer() {
- global showdebug, scheduler
- n := scheduler.Next()
- if (showdebug) {
- nextAction := scheduler.GetNextActionRelative()
- if nextAction {
- t := "Next action in " . FormatTime(nextAction.time) . " (" . nextAction.keys . ")" . (nextAction.comment ? " - " . nextAction.comment : "")
- } else {
- t := "No next action found"
- }
- ToolTip, % "[SchedulerTimer] " . t, 50, 0, 2
- SetTimer, tooltipDoff, -1250 ; higher than timer's 1000ms to avoid flickering
- }
- if (!n) {
- ; all scheduled actions finished
- SetTimer, schedulerTimer, Off
- ToolTip, Scheduler finished`, enabling autoupgrade and autoclick, 50, 50
- SetTimer, tooltipoff, -5000
- ; enable autoclick
- SetAutoclick(true, false)
- ; enable autoupgrader
- SetAutoupgrade(true, false)
- }
- }
- schedulerTimer:
- SchedulerTimer()
- return
- ; shift scheduler time, add time for subsequent action
- #NumpadAdd:: ; Win+NumpadPlus
- scheduler.ShiftTime(5*1000) ; 5s
- ToolTip, % "Scheduler's time shifted +5s, total of " . FormatTime(scheduler.GetShiftTime()), 50, 50
- SetTimer, tooltipoff, -2000
- return
- ; shift scheduler time, subtract time for subsequent action
- #NumpadSub:: ; Win+NumpadMinus
- scheduler.ShiftTime(-5*1000) ; 5s
- ToolTip, % "Scheduler's time shifted -5s, total of " . FormatTime(scheduler.GetShiftTime()), 50, 50
- SetTimer, tooltipoff, -2000
- return
- ; shift scheduler time, add more time for subsequent action
- #+NumpadAdd:: ; Win+Shift+NumpadPlus
- scheduler.ShiftTime(60*1000) ; 60s
- ToolTip, % "Scheduler's time shifted +60s, total of " . FormatTime(scheduler.GetShiftTime()), 50, 50
- SetTimer, tooltipoff, -2000
- return
- ; shift scheduler time, subtract more time for subsequent action
- #+NumpadSub:: ; Win+Shift+NumpadMinus
- scheduler.ShiftTime(-60*1000) ; 60s
- ToolTip, % "Scheduler's time shifted -60s, total of " . FormatTime(scheduler.GetShiftTime()), 50, 50
- SetTimer, tooltipoff, -2000
- return
- ;
- ;
- ; Start scheduler from index stuff
- ;
- ;
- #NumpadMult:: ; Win+NumpadAsterisk
- if (StartFromIdxWindowActive) {
- ; window is already active, wait till it's closed
- ToolTip, Start scheduler from index window is already active, 50, 50
- SetTimer, tooltipoff, -2000
- } else {
- StartFromIdxWindowActive := 1
- Gui, Add, Text,, Select first action
- Gui, Add, ListBox, AltSubmit vFirstActionListBox R30 W400 gListBoxClicked,
- Gui, Add, Button, Default, OK
- Gui, +Delimiter`n
- ;GuiControl, -Redraw, FirstActionListBox
- scheduler.AddListBoxItems("FirstActionListBox")
- ;GuiControl, +Redraw, FirstActionListBox
- Gui, Show
- }
- return
- GuiClose:
- GuiEscape:
- Gui, Cancel
- Gui, Destroy
- StartFromIdxWindowActive := 0
- return
- ButtonOK:
- Gui, Submit
- Gui, Destroy
- StartFromIdxWindowActive := 0
- SetAutoupgrade(false, false)
- scheduler.StartFromIndex(FirstActionListBox)
- SetTimer, schedulerTimer, 1000
- ToolTip, % "Scheduler started at index " . FirstActionListBox . " - " . scheduler.GetDescription(), 50, 50
- SetTimer, tooltipoff, % -10000
- return
- ListBoxClicked:
- if (A_GuiEvent = "DoubleClick") {
- ; ToolTip, double click, 50, 50
- ; SetTimer, tooltipoff, -2000
- GoSub, ButtonOK
- ; doubleclick seems to get through to the underlying window after the list window closes, didn't investigate further
- ;} else {
- ; ToolTip, normal click, 50, 50
- ; SetTimer, tooltipoff, -2000
- }
- return
- ;
- ;
- ; Other control
- ;
- ;
- #r::Reload ; Win+R
- ^!p::Pause ; Ctrl+Alt+P
- #w:: ; Win+W
- WinMinimize, %winName%
- return
- #q:: ; Win+Q
- WinActivate, %winName%
- return
- #d:: ; Win+D
- showdebug := !showdebug
- ToolTip, % "Debug info " . (showdebug ? "enabled" : "disabled"), 50, 50
- SetTimer, tooltipoff, -2000
- return
- #a:: ; Win+A
- reqActiveWindow := !reqActiveWindow
- ToolTip, % "Active window switching " . (reqActiveWindow ? "enabled" : "disabled"), 50, 50
- SetTimer, tooltipoff, -2000
- return
- ; @return string
- GetStatusInfo() {
- global autoclick, reqActiveWindow, showdebug, autoupgrader, scheduler
- s := "Autoclick is " . (autoclick ? "enabled" : "disabled")
- s .= "`nActive window switching is " . (reqActiveWindow ? "enabled" : "disabled")
- s .= "`nDebug info is " . (showdebug ? "enabled" : "disabled")
- if autoupgrader.started {
- s .= "`nAutoupgrader started " . FormatTime(autoupgrader.GetElapsedTime()) . " ago"
- remTime := autoupgrader.GetRemainingTime()
- if (remTime >= 0) {
- s .= ", wraps around in " . FormatTime(remTime)
- } else {
- s .= ", ended " . FormatTime(Abs(remTime)) . " ago" ; happens when time for the last scheduled action already passed, but action is yet to be executed
- }
- if (autoupgrader.getShiftTime() != 0) {
- s .= "`nAutoupgrader's time shift is " . FormatTime(autoupgrader.GetShiftTime())
- }
- nextAction := autoupgrader.GetNextActionRelative()
- if nextAction {
- s .= "`nNext scheduled autoupgrade action in " . FormatTime(nextAction.time) . " (" . nextAction.keys . ")" . (nextAction.comment ? " - " . nextAction.comment : "")
- } else {
- s .= "`nNo next scheduled autoupgrade action found"
- }
- } else {
- s .= "`nAutoupgrader is disabled"
- }
- if scheduler.started {
- s .= "`nScheduler started " . FormatTime(scheduler.GetElapsedTime()) . " ago"
- remTime := scheduler.GetRemainingTime()
- if (remTime >= 0) {
- s .= ", ends in " . FormatTime(remTime)
- } else {
- s .= ", ended " . FormatTime(Abs(remTime)) . " ago"
- }
- if (scheduler.getShiftTime() != 0) {
- s .= "`nScheduler's time shift is " . FormatTime(scheduler.GetShiftTime())
- }
- nextAction := scheduler.GetNextActionRelative()
- if nextAction {
- s .= "`nNext scheduled action in " . FormatTime(nextAction.time) . " (" . nextAction.keys . ")" . (nextAction.comment ? " - " . nextAction.comment : "")
- } else {
- s .= "`nNo next scheduled action found"
- }
- }
- return s
- }
- ; show status info
- #s:: ; Win+S
- ToolTip, % GetStatusInfo(), 50, 50
- SetTimer, tooltipoff, -5000
- return
- #z:: ; Win+Z
- ; name of this (global) variable is _s, not s, so functions using s don't complain due to Warn,LocalSameAsGlobal
- _s := "Priority actions & colors:`n"
- _s .= autoupgrader.GetPriorityActionsStatus()
- _s .= "`nDelay coordinates & colors:`n"
- _s .= autoupgrader.GetDelayStatus()
- ToolTip, %_s%, 50, 0, 2
- SetTimer, tooltipDoff, -15000
- ; copy information into Windows clipboard, so the colors could be pasted and used for configuration
- clipboard := _s
- return
- #u:: ; Win+U
- ClickBuyMode()
- return
- ; Warp
- ^!w:: ; Ctrl+Alt+W
- Warp(true)
- return
- ;
- ;
- ; Click into non-active window
- ; by DevourlordGig
- ; see http://pastebin.com/raw.php?i=JNthRMMf
- ; see https://www.reddit.com/r/TimeClickers/comments/3hhfvm/my_tc_script/cumtv85
- ;
- ;
- ; Retrieves the control at the specified point.
- ; X [in] X-coordinate relative to the top-left of the window.
- ; Y [in] Y-coordinate relative to the top-left of the window.
- ; WinTitle [in] Title of the window whose controls will be searched.
- ; WinText [in]
- ; cX [out] X-coordinate relative to the top-left of the control.
- ; cY [out] Y-coordinate relative to the top-left of the control.
- ; ExcludeTitle [in]
- ; ExcludeText [in]
- ; Return Value: The hwnd of the control if found, otherwise the hwnd of the window.
- ControlFromPoint(X, Y, WinTitle="", WinText="", ByRef cX="", ByRef cY="", ExcludeTitle="", ExcludeText="")
- {
- static EnumChildFindPointProc = 0
- if !EnumChildFindPointProc
- EnumChildFindPointProc := RegisterCallback("EnumChildFindPoint", "Fast")
- if !(target_window := WinExist(WinTitle, WinText, ExcludeTitle, ExcludeText))
- return false
- VarSetCapacity(rect, 16)
- DllCall("GetWindowRect", "uint", target_window, "uint", &rect)
- VarSetCapacity(pah, 36, 0)
- NumPut(X + NumGet(rect,0,"int"), pah, 0, "int")
- NumPut(Y + NumGet(rect,4,"int"), pah, 4, "int")
- DllCall("EnumChildWindows", "uint", target_window, "uint", EnumChildFindPointProc, "uint", &pah)
- control_window := NumGet(pah,24) ? NumGet(pah,24) : target_window
- DllCall("ScreenToClient", "uint", control_window, "uint", &pah)
- cX := NumGet(pah,0,"int"), cY := NumGet(pah,4,"int")
- return control_window
- }
- ; Ported from AutoHotkey::script2.cpp::EnumChildFindPoint()
- EnumChildFindPoint(aWnd, lParam) {
- if !DllCall("IsWindowVisible", "uint", aWnd)
- return true
- VarSetCapacity(rect, 16)
- if !DllCall("GetWindowRect", "uint", aWnd, "uint", &rect)
- return true
- pt_x := NumGet(lParam+0,0,"int"), pt_y := NumGet(lParam+0,4,"int")
- rect_left := NumGet(rect,0,"int"), rect_right := NumGet(rect,8,"int")
- rect_top := NumGet(rect,4,"int"), rect_bottom := NumGet(rect,12,"int")
- if (pt_x >= rect_left && pt_x <= rect_right && pt_y >= rect_top && pt_y <= rect_bottom) {
- center_x := rect_left + (rect_right - rect_left) / 2
- center_y := rect_top + (rect_bottom - rect_top) / 2
- distance := Sqrt((pt_x-center_x)**2 + (pt_y-center_y)**2)
- update_it := !NumGet(lParam+24)
- if (!update_it) {
- rect_found_left := NumGet(lParam+8,0,"int"), rect_found_right := NumGet(lParam+8,8,"int")
- rect_found_top := NumGet(lParam+8,4,"int"), rect_found_bottom := NumGet(lParam+8,12,"int")
- if (rect_left >= rect_found_left && rect_right <= rect_found_right
- && rect_top >= rect_found_top && rect_bottom <= rect_found_bottom)
- update_it := true
- else if (distance < NumGet(lParam+28,0,"double")
- && (rect_found_left < rect_left || rect_found_right > rect_right
- | rect_found_top < rect_top || rect_found_bottom > rect_bottom))
- update_it := true
- }
- if (update_it) {
- NumPut(aWnd, lParam+24)
- DllCall("RtlMoveMemory","uint",lParam+8,"uint",&rect,"uint",16)
- NumPut(distance, lParam+28, 0, "double")
- }
- }
- return true
- }
- ; X and Y use CoordMode,Mouse,Window not CoordMode,Mouse,Client
- ControlClick2(X, Y, WinTitle="", WinText="", ExcludeTitle="", ExcludeText="") {
- global showdebug
- hwnd := ControlFromPoint(X, Y, WinTitle, WinText, cX, cY, ExcludeTitle, ExcludeText)
- PostMessage, 0x200, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_MOUSEMOVE
- if (showdebug && ErrorLevel) {
- ToolTip, [ControlClick2]#1 ErrorLevel=%ErrorLevel%, 50, 0, 2
- SetTimer, tooltipDoff, -5000
- Sleep, 500
- }
- PostMessage, 0x2A1, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_MOUSEHOVER
- if (showdebug && ErrorLevel) {
- ToolTip, [ControlClick2]#2 ErrorLevel=%ErrorLevel%, 50, 0, 2
- SetTimer, tooltipDoff, -5000
- Sleep, 500
- }
- PostMessage, 0x201, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONDOWN
- if (showdebug && ErrorLevel) {
- ToolTip, [ControlClick2]#3 ErrorLevel=%ErrorLevel%, 50, 0, 2
- SetTimer, tooltipDoff, -5000
- Sleep, 500
- }
- PostMessage, 0x202, 0, cX&0xFFFF | cY<<16,, ahk_id %hwnd% ; WM_LBUTTONUP
- if (showdebug && ErrorLevel) {
- ToolTip, [ControlClick2]#4 ErrorLevel=%ErrorLevel%, 50, 0, 2
- SetTimer, tooltipDoff, -5000
- Sleep, 500
- }
- }
- ;
- ;
- ;
- ;
- ;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement