Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

A Starcraft Broodwar Script V1.3b


  • Please log in to reply
42 replies to this topic
000sixzeros000
  • Members
  • 43 posts
  • Last active: Apr 23 2011 08:11 AM
  • Joined: 17 Oct 2009
[Last Update: June/01/2010]
Here's a starcraft script...to play around with.. hopefully someone out there gets inspired to add to it..

I once wrote a very elaborate script for SC but lost the code.. I was just wishing that I'd posted it here so I'd have a copy again..

recently I powered up SC and was goofing off a little and decided to make another one just for kicks... I rewrote the most useful functions from the original.


********** MICRO MANAGEMENT HOTKEYS **********
Mass spell casting.. Ever wish you could just grab a group of units and then cycle through them 1 by 1 to cast spells? This macro will do that for you...it lets you do massive multi lock downs, multi psi storms, irradiate, matrix's, yamatos, mineral assignments, etc...

Mouse wheel up: Assigns all selected units to a group (Uses hotkey #7 ), then selects the first unit for use.
Mouse wheel down: Selects next unit of the group.
This is great for performing mass micro tasks like.. massive spell casts, lockdowns or massive psi storms.. It auto cycles through the whole group then loops over and starts again at unit 1, if any units die then the group is automatically reduced to the new count.
It can also be used for placing hatches, or units to mineral patches, is great for fast money maps where you need to send 3 units to gas, for example.
1. Select a group of 12 workers.
2. Push the wheel forward to assign them to a group, the script will auto select the first unit.
3. right click the gas.
4. pull the wheel back.
5. right click on the gas.
6. pull the wheel back.
7. right click on the gas.

You can rapidly execute up to 24 spells, for example, to perform mass lockdowns...
1. Select a group of 12 ghosts (ctrl click a ghost)
2. mouse wheel forward to assign all ghosts to the group, a single ghost will be selected.
3. [L]ockdown an enemy.
4. mouse wheel backwards to select the next unit.
5. [L] lock down the next unit.
6. mouse wheel backwards for next ghost.. etc.

'P'ylon short cut key. Allows you to use a single keystroke to place a pylon, without needing the B key, speeds up your initial base setup.
'G'ate short cut key. Allows you to use a single keystroke to place a gate.
'F'orge short cut key. Allows you to use a single keystroke to place a forge when protoss.
'C'annon short cut key. Allows you to use a single keystroke to place a cannon when protoss.

sound up/down Sets latency settings to high / low. In theory, handy if right before the battle you expect lots of micro and need accuracy, during initial game you set to extra high, then just before you need to throw lots of psi storms and lockdowns you hit low latency and attack.
pause keya pause short cut
[`] key.. performs a clone command, good for assigning workers to minerals on low money maps.. just select all units then hit the [`] key over each mineral patch, for the perfect split. You can use the same idea to spread units out and send multi units to scout. There's many uses.

********** MASS ATTACK MACROS **********
CTRL numpad keys
The script has predefined a number of hot spots around the map, and you can attack them quickly by using the keys of the Numpad. You can also create a dynamic hotpoint and assign it to the numpad[0] key. You can use this to rapidly attack multiple points on the map, to retreat rapidly to home base, assist an ally, or mass attack a single point.
   (10)  (12)  (2) 
     \    |    / 
      [7][8][9] 
 (9)--[4][5][6]--(3) 
      [1][2][3] 
     /    |    \ 
   (7)   (6)   (5) 

.. this is especially nasty when zerg, although it works with any race, for example, to use it effectively...
1. CTRL click a unit to group them
2. press CTRL numpad 8 to attack the 12oclock position.. cntrl-5 for mid map, etc..
You can send an insane amount of units very quickly across the map.
3. CTRL click a different type of unit, hydras then lings for example...
4. Press CTRL numpad to attack position.
5. CTRL click larvae, then click icon to train new units
6. CTRL click lords, then move them off map.
7. CTRL+H / CTRL+Z initiates mass build sequences.... (see mass train)
8. CTRL+ {Rbutton} sets a global Attack Hotpoint and makes it active on numpad 0
9. CTRL+A activates all assigned hotkey groups to attack the Hotpoint.

CTRL R-Click Assigns a global attack hot point, for the other automated functions to use. Lets say you set the point in the heart of the enemy base first by right clicking in the mini map, and then....

CTRL numpad 0 CTRL r-click in the minimap and you will setup an attack point that will be assigned to numpad 0. It almost makes the other numpad keys obsolete. just select a group and hit numpad 0 and it will attack your hotspot.

CTRL A / ALT-A Tells all hotkey groups to attack the hotspot at once. This is a really evil mass attack option..
1. Assign all your armies to hotkeyed groups,
2. CTRL+ R-click in the minimap to set the hot point.
3. Now hit CTRL-A and all the groups attacks at once or retreats at once, it will look like your whole army is moving as 1 group.

********** BASE MANAGEMENT MACROS **********
A trick to manage your base more easily is to use the F2,F3,F4 keys to create work areas. You assign F2 to the mineral area, F3 to the military production area, and F3 to the upgrades area, then you can jump to each area rapidly by using the Function keys and effectively do 3 things at once, you're never behind on upgrades when you do this and you can reassign the work areas as the game progresses. To assist with this idea...

Tab ignores the minimap toggle and cycles through the SHIFT F2, F3, F4 assigned locations.. Now you can hit tab or Mbutton to check minerals then army production then upgrades locations. note that the normal behaviour of F1,f2,f3,f4 have been replaced with other functions in this script, but you can still assign the locations by using the shift+f2/f3/f4 keys, its just that to bring them up you need to use the tab key which cycles through them, this is more efficient and easier to manage.

F5 = roller ball building control This is a shortcut that lets you set a default building for the F5 key. For example, have you ever got confused about which hotkey to use to create a gas mine?
1. Select a worker,
2. click F5,
3. Use the roller ball to change the default building for F5 to extractor/assimilator/refinary.
4. the next time you hit F5 it will be pre-ready to build a gas extractor.

When used in conjunction with the other mouse roller functions, to build mass buildings.. for example a zerg that needs to make 8 hatches..
1. Ctrl click drones.
2. push mouse roller forward to assign group
3. Hit F5
4. push mouse roller to set to hatch.
5. place the building
6. pull back on the mouse roller.
7. Hit F5
8. place the next hatch..
9 repeat from step 6...

[f8] Tries to perform upgrades universally with 1 key. Ever click on a building and scratch your head trying to remember the correct hotkey for the upgrade, this key does the guess work for you...
1. Click an upgrade building.
2. Click f8..

[f9] universal depot key. Makes a depot / pylon / overlord.
[f10] universal miltary building key. barracks / gate / hatch
[f11] universal extractor / gas key refinary / assimilator / extractor
[f12] universal main building key. Command Center/ nexus / hatch


********** MASS TRAINING MACROS **********
Introducing Zones....
Zones are areas that you can jump to by using the ALT+number keys, and just like the standard F2 - F3 - F4 keys allow you to navigate multiple work areas of focus, but with some key differences.
Zones can have a sequence of buildings assigned to them, which can then have macro sequences executed on them, like you can tell all buildings in the zone to rally to the global rally point, or mass train.
you can assign/unassign zones by using the SHIFT+number keys, and recall the zones using the ALT+number keys. You can also cycle through the zones using the [<] [>] keys and by using the [CTRL+Mbutton].
For example when used with the mass attack macros, you can do things like this..
1. Align your screen position to see as many buildings as possible.
2. Press Shift 1 to assign zone 1.
3. You have 2 seconds now to shift R-click on buildings, each click will assign a building to the zone.
4. Pause 2 seconds and a message 'record mode off' will appear. The building assignment phase is now over. If you have messed up you'll need to press shift 1 again to unassign the zone and then again to reassign it.
5. Align your screen position to see another group of buildings
6. Press shift 2 to assign zone 2.
7. you have 2 seconds to assign buildings by using shift+Rclicks.
8. pause 2 seconds for the 'record mode off' message.
9. CTRL Mbutton will move between zones.. or press the [<] and [>] keys to switch zones.
10. Select a building and press F3 and the building will produce a unit.
11. Press CTRL F3 and all the buildings of the currently active zone will produce units. Note that it doesnt matter where on the map you press CTRL F3, as the script will move to the zone, perform the commands and then return to your original position.
12. Press CTRL Mbutton to switch zones.
13. Press CTRL F3 and the other group of buildings will go to work.

Assigning and recalling zones....
SHIFT+0..9 keys, To assign zone 1, hit shift+1 then you have 2 seconds to assign the buildings. Use shift and Rclick to assign the buildings. Press shift+1 again and the zone will be removed and the building count reset.
ALT+0..9 keys, Will recall the zone and locate it on your screen, and inform you of the number of assigned buildings in the zone.

ALT {R-button} in minimap sets a global rally point This can be used to assign rally points to buildings individually or to a whole zone. Now ALT+{Lbutton} on a building and it will automatically set that rally point to the building. Or CTRL+R will assign rally points very quickly for all the buildings in the zone. This can be handy for directing your armies into a choke point, into the map center, or into an enemy base.

CTL-R rally all buildings in the zone to the global rally point that you created with your ALT+{Rbutton} click in the mini map.

The Basic Training macros... F1 ... F4 on their own will train a single unit, while the CTTL+F1 ... CTRL+F4 will execute mass build sequences on a zone. You can also try the unit hotkey, like CTRL+H will mass build hydras while you are zerg or CTRL+Z will mass zealots or zerglings, etc..

F1 Train A default Unit - a universal key for default units, just click the building and hit F1 and if it is an upgrade it will be triggered, if a barracks it will make marines, a command center scvs', etc. the script will remember the last unit you tried to make and use that as the default, so you can switch from mellee to ranged units.
F2 train base military unit - a universal key for attacking units.. terran makes marines, zerg=zerglings, protoss=zealots
F3 train secondary miltary unit - terran makes tanks, protoss=dragoons,zerg=hydra
F4 train support unit - goliath/ghost/battle cruiser/templar/overlord.

CTRL+F1 Mass Train default units - checks all queued buildings to see if they can make workers, and tries to make workers, or military units, or upgrades. the script remembers the last unit you tried to make and uses that as a default, so you can switch between mellee and ranged units.
CTRL+F2 Mass Train base military unit - a universal key for attacking units.. terran makes marines, zerg=zerglings, protoss=zealots
CTRL+F3 Mass Train secondary miltary unit - terran makes tanks, protoss=dragoons,zerg=hydra
CTRL+F4 Mass Train support unit - goliath/ghost/battle cruiser/templar/overlord.

CTRL H mass build hydras
CTRL+H / M / T / G / Z / W / O / D / S ctrl key + hotkey will mass build hydra,muta,marines, tanks, templar, ghost, goliaths,dragoons,zealots,zerglings,overlords,etc..

Mbutton on it's own, will cycle through the activated hotkeyed units and automatically trigger work on them, for example.. hotkey a command center, 2 workers, 2 barracks and an engineering bay, and then cycle through them with the Mbutton, the script will automatically produce workers and marines, and check the upgrades on the ebay, and pass control between your 2 workers and the buildings.

In the original I had a lot of auto stuff, a lot of setTimer functions, image and pixel scans, and arrays for tracking building and minimap locations.

to be honest though, although those things were cool to mess with, they werent often practical because timed interuptions will really screw you up, so I found that the current set of macros here, were the most often used.

The best I ever managed to get out of it, was about 20 actions per second...

You might still need to edit the F8 key here.. I havent rigorously tested the hotkey lists under all races...


Version notes ...
V1.1b
- Modified ^f1 to build default units
- added %lastUnit% to remember last unit as the default unit -allows auto train functions to switch from mellee to ranged units by hitting the units training hotkey.
- added auto upgrade to ^f1,^f2^f3^f4 hotkey sequences, if notRally()=true then assume to be a building requiring upgrades.
- added option to cycle hotkeys 0..9 via the Mbutton
- Hotkeyed buildings will autobuild and auto upgrade if in the mbutton cycle
- patched F8's protoss and terran upgrade options
- CTL Mbutton rotates zones
- MButton rotates the hotkeys
- rearranged code so that functions are in alphabetical order.
- added / to the start of messages so in event of failure they wont flash bogus messages to your allies.
v1.2b
-patched the mouse forward to debounce a little.. slowing it down to stop accidental assignments
- you now dont need to hold CTRL (its optional) to get the numpad buttons to work, and numlock is ignored.
V1.3b
-Patched the pixel search functions for unit count and race detection, to allow for gamma variance.

For the code.. see the post below...

000sixzeros000
  • Members
  • 43 posts
  • Last active: Apr 23 2011 08:11 AM
  • Joined: 17 Oct 2009
Oh make sure your gamma video setting is set to notch#6 .. select.. menu-> options -> video ->gamma correction to notch #6, so that the pixel search can find the right values.. (see post below about checking your gamma settings by using CNTL V)

PS: Note also, Im an original starcraft player, so you might need to tweak this a bit to add the broodwar hotkeys like for medics and such...

Update: A potential problem when using the sciTe editor is a conflict with the CNTL keys used by starcraft.. it appears that the toolBar properties in the bottom right corner of the editor are conflicting, so to fix, locate the icons in the editor, then right click and edit the properties, then remove the hotkey settings that look like ^1,^2, etc.. then you will be able to use the scite editor at the same time as starcraft is running..

The code is here....
#IfWinActive ahk_class SWarClass
attackPointX:=65
attackPointY:=408
rallyPointX:=65
rallyPointY:=408
Debug:=False
checkRace(1)
if(isTerran()){
  lastUnit:="m"
}
if(isZerg()){
  lastUnit:="z"
}
if(isProtoss()){
  lastUnit:="z"
}

;******* utility functions ****************
;******* utility functions ****************
;******* utility functions ****************

;------------------------------------------
canAttack(){  ;//can the selected unit attack?
;------------------------------------------
  if(isTerran() || isProtoss()){
    if( (checkPixelColor(0xc6c244,603,365,10) &&  checkPixelColor(0xfcd43b,612,374,10)) || (checkPixelColor(0xd4e5d7,603,365,10) &&  checkPixelColor(0xf2f2f2,612,374,10)) ){
      return 1 
    }else{
      return 0
    }
  }else{
    if( (checkPixelColor(0xc6c244,598,368,10) &&  checkPixelColor(0xfcd43b,607,377,10)) || (checkPixelColor(0xd4e5d7,598,368,10) &&  checkPixelColor(0xf2f2f2,607,377,10)) ){     
      return 1 
    }else{
      return 0
    }
  }
}

;------------------------------------------
checkColor(RGBValue,RGBTarget,vRange){    ;//make sure pixels are within a range to compensate for gamma
;------------------------------------------
 vRed:=0
 vGreen:=0
 vBlue:=0
 tRed:=0
 tGreen:=0
 tBlue:=0
 SplitRGBColor(RGBValue,vRed,vGreen,vBlue)
 SplitRGBColor(RGBTarget,tRed,tGreen,tBlue)
 if(vRed>tRed+vRange || vRed<(tRed-vRange)){
    return 0  
 }
 if(vBlue>tBlue+vRange || vBlue<tBlue-vRange){
    return 0  
}
if(vGreen>tGreen+vRange || vGreen<(tGreen-vRange)){
    return 0  
}
return 1
}
;------------------------------------------
checkPixelColor(targetPixelColor,xpos,ypos,vRange=0){
;------------------------------------------
   PixelGetColor, pixelColor, xpos, ypos,RGB
   if(checkColor(pixelColor,targetPixelColor,vRange)){
      return 1
   }else{
      return 0
   }   
}
;------------------------------------------
checkRace(forced=0){
;------------------------------------------
 global raceType
 if(raceType=="" || forced){
 ;//is protoss 3bbfa2 
  if(isProtoss()){
    showMessage("/Found Protoss")
    raceType:="Protoss"
  }
 ;//is terran 36363f
  if(isTerran()){
    showMessage("/Found Terran")
    raceType:="Terran"
  }
;//is zerg 797979
  if(isZerg()){
    showMessage("/Found Zerg")
    raceType:="Zerg"
  }
 }
 if(raceType==""){
   showMessage("/nothing detected")  
 }

 return raceType
}
;------------------------------------------
clearMessage:
;------------------------------------------
 setTimer clearMessage,OFF
 if (msgActive && isActive()){
	msgActive:=0
    sendInput {esc}
 }
return
;------------------------------------------
clearRoller:
;------------------------------------------
  setTimer clearRoller,off
  wheelRolling:=0
return
;------------------------------------------
clickStage(stageNum){
;------------------------------------------
    blockInput on
    saveMousePos()
    if(stageNum>7){
      stage:=stageNum-8
      sendInput v
      sleep 50
    }else{
       stage:=stageNum
       sendInput b
       sleep 50
    } 
    x:=mod(stage,3)
    y:=floor(stage/3)
    xpos:=505+20+(x*47)
    ypos:=356+(y*40)+20
    MouseMove,target(xpos),target(ypos),0
    sleep 50
    sendInput {click}
    sleep 50
    restoreMousePos()
    blockInput off
}

;------------------------------------------
countUnits(){
;------------------------------------------
    xSrch:=169
    ySrch:=398
    XW:=36
    YH:=37
    pColor:=0x1459d4   
   ;}
  total:=0  
  
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch:=169
  YSrch+=YH
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
  XSrch+=XW
  if( checkPixelColor(pColor,XSrch,YSrch,10) ) {
    total++
  }
 return total
}
;------------------------------------------
deSelectUnit(){
;------------------------------------------
 saveMousePos()
 xpos:=169+15
 ypos:=398+15
 MouseMove,xpos,ypos,0
 sleep 30
 sendInput {shift down}{click}{shift up}
 sleep 30
 restoreMousePos()
}
;------------------------------------------
getMiniMapPosition(){
;------------------------------------------
 global miniMapX,miniMapY
 PixelSearch miniMapX,miniMapY, 5,348,133,477,0xffffff,1
 if(errorLevel==0){
   miniMapX:=miniMapX+10
   miniMapY:=miniMapY+6
  return 1
 }else{
   ;//sendMessage("ERROR no mini map located")
   return 0
 }
}
;------------------------------------------
isActive(){  ;//are we in game or in lobby? lobby=not true in game=true
;------------------------------------------
   global Debug
   return Debug or checkPixelColor(0x2d23c2, 436, 3,10)
}
;------------------------------------------
isRally(){  ;//does unit have a rally point option?
;------------------------------------------
  if(!isZerg()){
    if (checkPixelColor(0xfcd43b, 623, 423,10) && checkPixelColor(0xfcd43b, 604, 404,3)){    
      return 1
    }else{
      return 0 
    }
  }else{
    if (checkPixelColor(0xfcd43b, 553, 367,10) && checkPixelColor(0xfcd43b, 572, 387,3)){    
      return 1
    }else{
      return 0    
    }
  }
}

;------------------------------------------
isTerran(){
;------------------------------------------
  if (checkPixelColor(0x36363f, 5, 317,10)){
    return 1
  } else {
    return 0
  }
}
;------------------------------------------
isZerg(){
;------------------------------------------
  if (checkPixelColor(0x797979, 5, 317,10)){
    return 1
  } else {
    return 0
  }
}
;------------------------------------------
isProtoss(){
;------------------------------------------
  if (checkPixelColor(0x3bbfa2, 5, 317,10)){
	return 1
   }else{
     return 0
   }
}


;------------------------------------------
processSelection(){
;------------------------------------------
  if(isProtoss()){
    if(isRally()){
      sendInput zps
    }else{
      sendInput SWAPHKI
    }
  }
  if(isTerran()){
    if(isRally()){ ;//make a unit
      sendInput mtsv
    }else{
      sendInput wasphlcomeitn
    }
  }
  if(isZerg()){
    if(isRally()){
      sendInput shzdo
    }else{
      sendInput VPMWAEGBCSHKL
    }
  }
}

;------------------------------------------
rand(min,max){
;------------------------------------------
 random value,min,max
 return value
}

;------------------------------------------
recordModeOff:
;------------------------------------------
 setTimer recordModeOff,off
 recordMode:=0
 showMessage("/Record Mode off")
Return
;------------------------------------------
activateZone:
;------------------------------------------
 currentZone:=thisKey
;------------------------------------------
setCurrentZone:
;------------------------------------------
  if(MM_%currentZone%){
    setMiniMapPosition(MM_%currentZone%_Xpos,MM_%currentZone%_Ypos)
    showMessage("/Zone [" . currentZone . "] Activated (" . MM_%currentZone%_Xpos . "," . MM_%currentZone%_Ypos . ") ")
  }
Return 
;------------------------------------------
recordZone:
;------------------------------------------
  currentZone:=thisKey
  if(!MM_%currentZone%){
    MM_%currentZone%:=1
    if(getMiniMapPosition()){
      showMessage("/Zone " . currentZone . " (" . miniMapX . "," . miniMapY . ") Now set buildings")
      MM_%currentZone%_Xpos:=miniMapX
      MM_%currentZone%_Ypos:=miniMapY     
      setTimer recordModeOff,2000
      recordMode:=1
      total_%currentZone%:=0
    }else{
      showMessage("/Error Bad MiniMap") 
    }
  }else{
      MM_%currentZone%:=0
      showMessage("/Zone #" . currentZone . " removed") 
  }
return
;------------------------------------------
restoreMiniMapPos(){
;------------------------------------------
 global gMMX,gMMY
 setMiniMapPosition(gMMX,gMMY)
}
;------------------------------------------
restoreMousePos(){
;------------------------------------------
 global mouseX,mouseY
 MouseMove,mouseX,mouseY,0
}
;------------------------------------------
saveMiniMapPos(){
;------------------------------------------
 global gMMX,gMMY,miniMapX,miniMapY
 getMiniMapPosition()
 gMMX:=miniMapX
 gMMY:=miniMapY
}
;------------------------------------------
saveMousePos(){
;------------------------------------------
 global mouseX,mouseY
 MouseGetPos mouseX,mouseY
}
;------------------------------------------
selectNothing(){ ;//stops detect errors when mouse is in the select area.
;------------------------------------------
 MouseGetPos xp,yp
 if(yp>370){
  MouseMove ,148,372,0
  sleep 30
 }
}
;------------------------------------------
selectUnit(unitNum){
;------------------------------------------
  y:=mod(unitNum,2)
  x:=floor(unitNum/2)
  xpos:=169+15+(x*36)
  ypos:=398+(y*37)+15
  MouseMove,xpos,ypos,0
  sleep 30
  sendInput {click}
  sleep 30
}
;------------------------------------------
sendMessage(msg){  ;//sends a message out rather than just show personal messages, mainly used for debugging
;------------------------------------------   
 global msgActive
 gosub clearMessage
 if(isActive()){
   setTimer clearMessage,500
   msgActive:=1
   sendInput {enter}%msg%{enter}
 }
}
;------------------------------------------
sendR(strData,delay=30){ ;//send string with delay
;------------------------------------------
  loop, Parse, strData
  {
    sendInput %A_LoopField%
    sleep delay
  }
}
;------------------------------------------
setMiniMapPosition(xp,yp){
;------------------------------------------
  MouseMove xp,yp,0
  sleep 30
  sendInput {lbutton}
  sleep 30
}
;------------------------------------------
showMessage(msg){
;------------------------------------------   
 global msgActive
 gosub clearMessage
 if(isActive()){
   setTimer clearMessage,500
   msgActive:=1
   sendInput {enter}%msg%
 }
}

;------------------------------------------
SplitRGBColor(RGBColor, ByRef Red, ByRef Green, ByRef Blue) 
;------------------------------------------
{ 
    Red := RGBColor >> 16 & 0xFF 
    Green := RGBColor >> 8 & 0xFF 
    Blue := RGBColor & 0xFF 
}

;------------------------------------------
target(axis,jitter=3){  ;//randomize the target locations
;------------------------------------------
 Random target,axis-jitter,axis+jitter
 return target
}





;******* Hot Keys ****************

;------------------------------------------
`::   ;//basic clone technique.. will R-CLICK assign all units to mouse location then drop 1 unit.. 
      ;//can be used to send all workers to unique mineral patches or to send units to different map locations
;------------------------------------------
 sendInput {rbutton}
 deSelectUnit()
return
;------------------------------------------
?::  ;//a test function to see if the script is working..
;------------------------------------------
 checkRace(1)
 if(isActive()){
   showMessage("/Is active ok")  
 }
 Return

;------------------------------------------
,:: ;//cycle through the zones
;------------------------------------------
  gosub clearMessage
  foundZone:=0
  loop, 10
  {
    currentZone:=currentZone-1
    if(currentZone<0){
      currentZone:=9
    }
    thisKey = %currentZone%
    if(MM_%currentZone%){
      foundZone:=1
      saveMousePos()
      setMiniMapPosition(MM_%currentZone%_Xpos,MM_%currentZone%_Ypos)
      restoreMousePos()
      buildingsAssigned:=total_%currentZone%
      showMessage("/Zone " . currentZone . ": TTL buildings=" . buildingsAssigned)      
    } 
    if(foundZone){
      break
    }
  }
return
;------------------------------------------
.::  ;//cycles through the zones
;+mbutton::  ;//Mbutton will jump to next area
^mbutton::  ;CTL Mbutton
;!mbutton::
;------------------------------------------
 gosub clearMessage
 foundZone:=0
  loop, 10
  {
    currentZone:=currentZone+1
    if(currentZone>9){
      currentZone:=0
    }
    thisKey = %currentZone%
    if(MM_%currentZone%){
      foundZone:=1
      saveMousePos()
      setMiniMapPosition(MM_%currentZone%_Xpos,MM_%currentZone%_Ypos)
      restoreMousePos()
      buildingsAssigned:=total_%currentZone%
      showMessage("/Zone " . currentZone . ": TTL buildings=" . buildingsAssigned)      
    } 
    if(foundZone){
      break
    }
  }
return
;------------------------------------------
+0::  ;//save minimap position
;------------------------------------------
 thisKey=0
 gosub recordZone
Return
;------------------------------------------
!0::  ;//restore minimap position
;------------------------------------------
 thisKey=0
 gosub activateZone
Return
;------------------------------------------
^0::  ;//assign a hotkey
;------------------------------------------
  if(hotKey0){
      hotKey0:=0
      showMessage("/Hotkey 0 removed from Mbutton")      
  }else{
      hotKey0:=1
      showMessage("/Hotkey 0 added to Mbutton")      
  }
  sendInput {ctrl down}0{ctrl up}` 
Return
;------------------------------------------
+1::  ;//save minimap position
;------------------------------------------
 thisKey=1
 gosub recordZone
Return
;------------------------------------------
!1::  ;//restore minimap position
;------------------------------------------
 thisKey=1
 gosub activateZone
Return
;------------------------------------------
^1::  ;//assign a hotkey
;------------------------------------------
  if(hotKey1){
      hotKey1:=0
      showMessage("/Hotkey 1 removed from Mbutton")      
  }else{
      hotKey1:=1
      showMessage("/Hotkey 1 added to Mbutton")      
  }
  sendInput {ctrl down}1{ctrl up}` 
Return
;------------------------------------------
+2::  ;//save minimap position
;------------------------------------------
 thisKey=2
 gosub recordZone
Return
;------------------------------------------
!2::  ;//restore minimap position
;------------------------------------------
 thisKey=2
 gosub activateZone
Return
;------------------------------------------
^2::  ;//assign a hotkey
;------------------------------------------
  if(hotKey2){
      hotKey2:=0
      showMessage("/Hotkey 2 removed from Mbutton")      
  }else{
      hotKey2:=1
      showMessage("/Hotkey 2 added to Mbutton")      
  }
  sendInput {ctrl down}2{ctrl up}` 
Return
;------------------------------------------
+3::  ;//save minimap position
;------------------------------------------
 thisKey=3
 gosub recordZone
Return
;------------------------------------------
!3::  ;//restore minimap position
;------------------------------------------
 thisKey=3
 gosub activateZone
Return
;------------------------------------------
^3::  ;//assign a hotkey
;------------------------------------------
  if(hotKey3){
      hotKey3:=0
      showMessage("/Hotkey 3 removed from Mbutton")      
  }else{
      hotKey3:=1
      showMessage("/Hotkey 3 added to Mbutton")      
  }
  sendInput {ctrl down}3{ctrl up}` 
Return
;------------------------------------------
+4::  ;//save minimap position
;------------------------------------------
 thisKey=4
 gosub recordZone
Return
;------------------------------------------
!4::  ;//restore minimap position
;------------------------------------------
 thisKey=4
 gosub activateZone
Return
;------------------------------------------
^4::  ;//assign a hotkey
;------------------------------------------
  if(hotKey4){
      hotKey4:=0
      showMessage("/Hotkey 4 removed from Mbutton")      
  }else{
      hotKey4:=1
      showMessage("/Hotkey 4 added to Mbutton")      
  }
  sendInput {ctrl down}4{ctrl up}` 
Return
;------------------------------------------
+5::  ;//save minimap position
;------------------------------------------
 thisKey=5
 gosub recordZone
Return
;------------------------------------------
!5::  ;//restore minimap position
;------------------------------------------
 thisKey=5
 gosub activateZone
Return
;------------------------------------------
^5::  ;//assign a hotkey
;------------------------------------------
  if(hotKey5){
      hotKey5:=0
      showMessage("/Hotkey 5 removed from Mbutton")      
  }else{
      hotKey5:=1
      showMessage("/Hotkey 5 added to Mbutton")      
  }
  sendInput {ctrl down}5{ctrl up}` 
Return

;------------------------------------------
+6::  ;//save minimap position
;------------------------------------------
 thisKey=6
 gosub recordZone
Return
;------------------------------------------
!6::  ;//restore minimap position
;------------------------------------------
 thisKey=6
 gosub activateZone
Return
;------------------------------------------
^6::  ;//assign a hotkey
;------------------------------------------
  if(hotKey6){
      hotKey6:=0
      showMessage("/Hotkey 6 removed from Mbutton")      
  }else{
      hotKey6:=1
      showMessage("/Hotkey 6 added to Mbutton")      
  }
  sendInput {ctrl down}6{ctrl up}` 
Return
;------------------------------------------
+7::  ;//save minimap position
;------------------------------------------
 thisKey=7
 gosub recordZone
Return
;------------------------------------------
!7::  ;//restore minimap position
;------------------------------------------
 thisKey=7
 gosub activateZone
Return
;------------------------------------------
^7::  ;//assign a hotkey
;------------------------------------------
  if(hotKey7){
      hotKey7:=0
      showMessage("/Hotkey 7 removed from Mbutton")      
  }else{
      hotKey7:=1
      showMessage("/Hotkey 7 added to Mbutton")      
  }
  sendInput {ctrl down}7{ctrl up}` 
Return

;------------------------------------------
+8::  ;//save minimap position
;------------------------------------------
 thisKey=8
 gosub recordZone
Return
;------------------------------------------
!8::  ;//restore minimap position
;------------------------------------------
 thisKey=8
 gosub activateZone
Return
;------------------------------------------
^8::  ;//assign a hotkey
;------------------------------------------
  if(hotKey8){
      hotKey8:=0
      showMessage("/Hotkey 8 removed from Mbutton")      
  }else{
      hotKey1:=8
      showMessage("/Hotkey 8 added to Mbutton")      
  }
  sendInput {ctrl down}8{ctrl up}` 
Return
;------------------------------------------
+9::  ;//save minimap position
;------------------------------------------
 thisKey=9
 gosub recordZone
Return
;------------------------------------------
!9::  ;//restore minimap position
;------------------------------------------
 thisKey=9
 gosub activateZone
Return
;------------------------------------------
^9::  ;//assign a hotkey
;------------------------------------------
  if(hotKey9){
      hotKey9:=0
      showMessage("/Hotkey 9 removed from Mbutton")      
  }else{
      hotKey9:=1
      showMessage("/Hotkey 9 added to Mbutton")      
  }
  sendInput {ctrl down}9{ctrl up}` 
Return



;------------------------------------------
; BUTTON FUNCTIONS
;------------------------------------------
;------------------------------------------
!LButton::        ;//assign rally target point to current unit
;------------------------------------------
  mouseGetPos tx,ty
  if(tx<135 && ty>345){  ;//in mini map
    sendInput {lbutton}
  }else{
      sendInput {lbutton}
      sleep 60
      if(isRally()){
        sendInput r
        sleep 30        
        blockInput on
        mouseGetPos tx,ty
        mouseMove,rallyPointX,rallyPointY,0
        ;//sleep 20
        sendInput {lbutton}
        sleep 10
        blockInput off
      }
      mouseMove,tx,ty,0      
  } 
return
;------------------------------------------
~lbutton::
;------------------------------------------
 if(buildMode){
    buildMode:=0
 }
Return
;------------------------------------------
~+lbutton::  ;//record mode records the actual building locations of a zone
;------------------------------------------
 if(recordMode){
   sendInput {lbutton}
   sleep 30
   total_%currentZone%++
   thisIndex:=total_%currentZone%
   mouseGetPos,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%   
   showMessage("/Zone[" . currentZone . "][" . thisIndex . "]=(" . xp_%currentZone%_%thisIndex% . "," . yp_%currentZone%_%thisIndex% . ")" )
   setTimer recordModeOff,2000
 }
Return

;;------------------------------------------
;mbutton::  ;//disable annoying mouse moves
;;------------------------------------------
; return

;------------------------------------------
mbutton:: ;//cycle through assigned hot keyed units
;------------------------------------------
  gosub clearMessage
  loop,10
  {
    hotkeyCycle++
    if(hotKeyCycle>9){
      hotkeyCycle:=0
    }
    if(hotkey%hotkeyCycle%){
      sendInput %hotkeyCycle%
      sendInput %hotkeyCycle%
      sleep 200
      if(canAttack()){ ;//dont do anything with this lot.
      }else{ ;//check for upgrades and unit production
        processSelection()
      }
      return
    }
  }
return

;------------------------------------------
!RButton::        ;//set rally target point
;------------------------------------------
  mouseGetPos tx,ty
   ;//if(tx<135 && ty>345){  ;//in mini map
      ;//set rally target point
      rallyPointX:=tx
      rallyPointY:=ty
      showMessage("/Rally Point (" . rallyPointX . "," . rallyPointY . ")")
   ;//} 
return

;------------------------------------------
^RButton::  ;//set dynamic attack point and assign this point to the CTRL NUMPAD-0 key / assign upgrades
;------------------------------------------
  gosub clearMessage
  mouseGetPos tx,ty
  if(tx<135 && ty>345){  ;//in mini map
      ;//set rally target point
      attackPointX:=tx
      attackPointY:=ty
      showMessage("/Attack Point (" . attackPointX . "," . attackPointY . ")")
  }else{ ;//group and attack the point
    BlockInput On
    sendInput {Ctrl Down}{lbutton}
    sleep 30
    sendInput {ctrl up}
    if(canAttack()){
      sendInput a
      sleep 30
      mouseMove,target(attackPointX),target(attackPointY),0
      sleep 30
      sendInput {click}
      sleep 30
      ;//showMessage("/Attack (" . attackPointX . "," . attackPointY . ")")
    }else{
      ;//showMessage("/Cant Attack")
      ;//CANT ATTACK SO try an upgrade or try to make a unit..
      processSelection()
    }
    blockInput off
  }
  mouseMove,tx,ty,0 
return

;------------------------------------------
^f1:: ;//Produce Base Units   ... checks the building to see if rally, then makes units otherwise it upgrades
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {click}
      sleep 50
      if(isRally()){
        ;//if(isActive()){
          if(isTerran()){
            sendInput %lastUnit%tsv
          }
          if(isProtoss()){
            sendInput %lastUnit%p
          }
          if(isZerg()){
            sendInput s
            sleep 100
            sendInput %lastunit%do
          } 
        ;//}
      }else{
        processSelection() ;//process for upgrades
      }
      sleep 30
    } 
  }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return

;------------------------------------------
f1:: ;//universal worker key
makeWorkerUnit:
;------------------------------------------
 gosub clearMessage
 if(isActive()){
    if(isTerran()){
      sendInput s
    }
    if(isProtoss()){
      sendInput p
    }
    if(isZerg()){
      sendInput s
      sleep 100
      sendInput d
    } 
  }
return

;------------------------------------------
^f2::  ;//mass universal base military unit
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {click}
      sleep 50
      if(isRally()){
        gosub makeMilitaryUnit      
      }else{
        processSelection()
      }
      sleep 30
    } 
  }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return
;------------------------------------------
f2:: ;//universal base military unit
makeMilitaryUnit:
;------------------------------------------
  gosub clearMessage
  if(isActive()){
    if(isTerran()){
      sendInput mtw
    }
    if(isProtoss()){
      sendInput z
    }
    if(isZerg()){
      sendInput s
      sleep 100
      sendInput z
    } 
  }
return
;------------------------------------------
^f3::  ;//mass universal secondary unit
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {click}
      sleep 50
      if(isRally()){
        gosub makeSecondaryUnit
      }else{
        processSelection()
      }
      sleep 30
    } 
  }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return

;------------------------------------------
f3:: ;//universal secondary unit
makeSecondaryUnit:
;------------------------------------------
  gosub clearMessage
  if(isActive()){
    if(isTerran()){
      sendInput fvb
    }
    if(isProtoss()){
      sendInput d
    }
    if(isZerg()){
      sendInput s
      sleep 100
      sendInput h
    } 
  }
return

;------------------------------------------
^f4:: ;//mass universal support unit
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {click}
      sleep 50
      if(isRally()){
        gosub makeSupportUnit
      }else{
        processSelection()
      }
      sleep 30
    } 
  }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return

;------------------------------------------
f4:: ;//universal support unit
makeSupportUnit:
;------------------------------------------
  gosub clearMessage
  if(isActive()){  
    if(isTerran()){
      sendInput gb
    }
    if(isProtoss()){
      sendInput t
    }
    if(isZerg()){
      sendInput s
      sleep 100
      sendInput o
    } 
  }
return

;------------------------------------------
f5::    ;//an experiment to allow building creation via the mouse wheel, so you can use say f5 to select depot/barrcks/factory/starport, etc..
;------------------------------------------
 gosub clearMessage
 if(!buildMode){
   buildMode:=1
   if(buildStage==""){
      buildStage:=2 
   }
   clickStage(buildStage)
 }else{
   buildMode:=0
   sendInput {esc}
}
Return


;------------------------------------------
f8::  ;//upgrade sequences.. (might need correction, I just guessed at them)
;------------------------------------------
gosub clearMessage
if(isProtoss()){
  sendInput WASPHKL
}
if(isTerran()){
  sendInput WASPHKI
}
if(isZerg()){
  sendInput VPMWAEGBCSHKL
}
return


;------------------------------------------
f9::   ;//pylon /depot /lord
;------------------------------------------
gosub clearMessage
if(isProtoss()){
  sendInput b
  sleep 50
  sendInput p
}
if(isTerran()){
  sendInput b
  sleep 50
  sendInput s
}
if(isZerg()){
  sendInput s
  sleep 50
  sendInput o
}
Return

;------------------------------------------
f10::  ;//build gate, barracks/hatch
;------------------------------------------
gosub clearMessage
if(isProtoss()){
  sendInput b
  sleep 50
  sendInput g
}
if(isTerran()){
  sendInput b
  sleep 50
  sendInput b
}
if(isZerg()){
  sendInput b
  sleep 50
  sendInput h
}
Return
;------------------------------------------
f11::  ;//assimilator/refinary/extractor
;------------------------------------------
gosub clearMessage
if(isProtoss()){
  sendInput b
  sleep 50
  sendInput a
}
if(isTerran()){
  sendInput b
  sleep 50
  sendInput r
}
if(isZerg()){
  sendInput b
  sleep 50
  sendInput e
}
Return
;------------------------------------------
f12::   ;//build nexus/CC/hatch
;------------------------------------------
gosub clearMessage
if(isProtoss()){
  sendInput b
  sleep 50
  sendInput n
}
if(isTerran()){
  sendInput b
  sleep 50
  sendInput c
}
if(isZerg()){
  sendInput b
  sleep 50
  sendInput h
}
Return


;------------------------------------------
^Numpad0::
Numpad0::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 50
  blockInput on
  saveMousePos()
  mouseMove,target(attackPointX),target(attackPointY),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 return


; Set up numpad attacks
;   (10)  (12)  (2) 
;     \    |    / 
;      [7][8][9] 
; (9)--[4][5][6]--(3) 
;      [1][2][3] 
;     /    |    \ 
;   (7)   (6)   (5) 
;
;------------------------------------------
^Numpad1::
Numpad1::
NumpadEnd::
^NumpadEnd::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  blockInput on
  saveMousePos()
  MouseMove,target(16),target(463),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return
 ;------------------------------------------
^Numpad2::
Numpad2::
NumpadDown::
^NumpadDown::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  blockInput on
  saveMousePos()
  MouseMove,target(65),target(463),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return
;------------------------------------------
^Numpad3:: ;//attack bottom right mini map location
Numpad3::
NumpadPgdn::
^NumpadPgdn::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  blockInput on
  saveMousePos()
  MouseMove,target(122),target(463),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return
;------------------------------------------
^Numpad4::
Numpad4::
Numpadleft::
^Numpadleft::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  saveMousePos()
  MouseMove,target(16),target(408),0
  sendInput a
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return
;------------------------------------------
^Numpad5::
Numpad5::
NumPadClear::
^NumPadClear::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  blockInput on
  saveMousePos()
  MouseMove,target(65),target(408),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return
;------------------------------------------
^Numpad6:: ;//attack right mid mini map location
Numpad6::
NumpadRight::
^NumpadRight::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  blockInput on
  saveMousePos()
  MouseMove,target(122),target(408),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return
;------------------------------------------
^Numpad7::
Numpad7::
numpadhome::
^numpadhome::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  blockInput on
  saveMousePos()
  MouseMove,target(16),target(362),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return
;------------------------------------------
^Numpad8::
Numpad8::
Numpadup::
^Numpadup::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  blockInput on
  saveMousePos()
  MouseMove,target(65),target(362),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return
;------------------------------------------
^Numpad9::   ;//attack top right map location
Numpad9::
NumpadPgup::
^NumpadPgup::
;------------------------------------------
  gosub clearMessage
  sendInput a
  sleep 60
  blockInput on
  saveMousePos()
  MouseMove,target(122),target(362),0
  sleep 30
  sendInput {lbutton}
  sleep 10
  restoreMousePos()
  blockInput off
 Return


;------------------------------------------
Pause::
;------------------------------------------
 ;//if(isActive()){
  sendInput  {f10}
  sleep 100
  sendR("pr",50)
  sleep 50
  sendInput {esc}
 ;//}
return

;------------------------------------------
tab:: ;//cycle through tab locations
+mbutton::
;------------------------------------------
  if(tabCycle<1){
   tabCycle:=1
   sendInput {f2}
   return
  }
  if(tabCycle==1){
   tabCycle:=2
   sendInput {f3}
   return
  }
  if(tabCycle>1){
   tabCycle:=0
   sendInput {f4}
   return
  }
return



;------------------------------------------
Volume_Down:: ;//set latency
;------------------------------------------
 ;//if(isActive()){
  sendInput  {f10}
  sleep 100
  sendR("onlo",100)
  sleep 100
  sendInput {esc}
 ;//}
return
;------------------------------------------
Volume_Up:: ;//set latency
;------------------------------------------
;// if(isActive()){
  sendInput  {f10}
  sleep 100
  sendR("oneo",100)
  sleep 100
  sendInput {esc}
 ;//}
return
 
;------------------------------------------
wheelDown::  ;//select the next unit in the current group
;------------------------------------------
 if(buildMode){
     buildStage--
    gosub clearMessage
    if(buildStage<0){
      buildStage:=11
    }
    sendInput {esc}
    sleep 50
    clickStage(buildStage)
    showMessage("/Stage " . buildStage)
}else{
  if(!wheelRolling){
    wheelRolling:=1
    setTimer clearRoller,50
    Gosub clearMessage
    sendInput 7
    sleep 50
    groupIndex++
    saveMousePos()
    selectNothing()
    totalUnits:=countUnits()
      if(groupIndex > totalUnits-1){ 
         groupIndex:=0
      }
   selectUnit(groupIndex)
   restoreMousePos()
   showMessage("/Unit #" . (groupIndex+1) . " of " . totalUnits)
  }
  wheelRolling:=1
  setTimer clearRoller,50 
}
return

;------------------------------------------
wheelUp::    ;//assign current selection to a group under hotkey #7, count units, and select first unit.
;------------------------------------------
 wheelRolling--   ;//debounce the wheel roll forward....
 setTimer clearWheel,150
 if(wheelRolling < -5 ){
   Return
 }
 if(wheelRolling > -5 ){
   Return
 }

if(buildMode){ ;//manage build mode (f5)
    buildStage++
    if(buildStage>11){
      buildStage:=0 
    }
    sendInput {esc}
    sleep 50
    clickStage(buildStage)
    showMessage("/Stage " . buildStage)
}else{ ;//manage spell caster mode.
    saveMousePos()
    selectNothing()

    sendInput {ctrl down}7{ctrl up} 
    
    groupSize:=countUnits()
    groupIndex:=0
    showMessage("/Total units=" . groupSize)
        
    selectUnit(0)
    restoreMousePos()
}
return


;------------------------------------------
^a:: ;//all points attack
;------------------------------------------
  gosub clearMessage
  blockInput on
  saveMousePos()
  mouseMove,target(attackPointX),target(attackPointY),0
  sleep 30
  Loop,10
  {
    theKey:=a_index-1
    sendInput %theKey%
    sleep 30
    sendInput A
    sleep 30
    sendInput {click}
    sleep 30
  }  
  restoreMousePos()
  blockInput off
 return

;------------------------------------------
^d:: ;//mass Dra goons ?/ drones
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(isProtoss()){
    lastUnit:="d"
  }
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {lbutton}
      sleep 50
      if(isTerran() || isProtoss()){
        sendInput d
        sleep 30        
      }
      if(isZerg()){
        sendInput s
        sleep 100        
        sendInput d
        sleep 50
      }
  }
 }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return
;------------------------------------------
^f:: ;//mass firebats... defiler?
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(isTerran()){
    lastUnit:="f"
  }
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {lbutton}
      sleep 50
      if(isTerran() || isProtoss()){
        sendInput f ;//firebat
        sleep 30        
    }
    if(isZerg()){ ;//defilers
       sendInput s
       sleep 100        
       sendInput f
       sleep 50
    }
  }
 }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return
;------------------------------------------
^g:: ;//mass goons ?/ goliath 
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(isTerran()){
    lastUnit:="g"
  
  }
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {lbutton}
      sleep 50
      if(isTerran() || isProtoss()){
        sendInput g
        sleep 30        
      }
      if(isZerg()){
        sendInput s
        sleep 100
        sendInput g
        sleep 50
      }
  }
 }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return
;------------------------------------------
^h:: ;//mass Hydra 
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(isZerg()){
    lastUnit:="h"
  }
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {lbutton}
      sleep 50
      if(isZerg()){
        sendInput s
        sleep 100        
        sendInput h
        sleep 50
      }
  }
 }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return
;------------------------------------------
^m:: ;//mass marines or mass mutas
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  lastUnit:="m"
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {lbutton}
      sleep 50
      if(isTerran() || isProtoss()){
        sendInput m
        sleep 30        
      }
      if(isZerg()){
       sendInput s
       sleep 100        
       sendInput m
       sleep 50
      }    
  }
 }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput off
return
;------------------------------------------
^o:: ;//overlords
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {lbutton}
      sleep 100
      if(isZerg()){
        sendInput s
        sleep 100        
        sendInput o
        sleep 50
      }
    }
 }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return
;------------------------------------------
^r::  ;//assign rally points to all buildings in the zone list
 ;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(MM_%currentZone%){
   loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sleep 20
      sendInput {lbutton}
      if(isRally()){                ;//if can rally then set it..
        sendInput r
        sleep 50
        mouseMove,rallyPointX,rallyPointY,0
        sleep 30
        sendInput {lbutton}
        sleep 30
      }else{
       ;//showMessage("/has no rally " . %A_Index%)
      }
    } 
  }else{
    ;//showMessage("/No zones???" . MM_%currentZone% . " curZone=" . currentzone )
  }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput, off
return
;------------------------------------------
^t:: ;//mass tanks / templar
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {lbutton}
      sleep 50
      if(isTerran() || isProtoss()){
        sendInput t
        sleep 30        
      }
  }
 }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return

;------------------------------------------
^v::  ;// video gamma report
;------------------------------------------
   PixelGetColor, pixelColor, 436, 3,RGB
   SetFormat, IntegerFast, hex           ; Convert a decimal integer to hexadecimal:
   pixelColor +=0
   pixelColor .= ""                             ; Necessary due to the "fast" mode.
   Debug:=true
   sendMessage("Target= 0x2d23c2 Actual=" . pixelColor  )
   SetFormat, IntegerFast, d
   Debug:=false
Return

;------------------------------------------
^z:: ;//mass zerglings / zealots 
;------------------------------------------
  blockInput,on
  saveMousePos()
  saveMiniMapPos()
  gosub setCurrentZone
  gosub clearMessage
  sleep 30
  if(!isTerran()){
    lastUnit:="z"
  
  } 
  if(MM_%currentZone%){
    loop, % total_%currentZone%
    { 
      ;//select building      
      thisIndex:=A_Index
      mouseMove,xp_%currentZone%_%thisIndex%,yp_%currentZone%_%thisIndex%,0   
      sendInput {lbutton}
      sleep 50
      if(isTerran() || isProtoss()){
        sendInput z
        sleep 30        
    }
    if(isZerg()){
       sendInput s
       sleep 100        
       sendInput z
       sleep 50
    }
   }
 }
  restoreMiniMapPos()
  restoreMousePos()
  blockInput Off
return

;------------------------------------------
~a::
;------------------------------------------
 gosub clearMessage
return 
;------------------------------------------
b::
;------------------------------------------
 gosub clearMessage
 sendInput b
return 
;------------------------------------------
c::
;------------------------------------------
 gosub clearMessage
 if(isProtoss()){
   sendInput b 
 }
 sendInput c
return 
;------------------------------------------
~d::
;------------------------------------------
  gosub clearMessage
  if(isProtoss()){
    lastUnit:="d"
  }
return 
;------------------------------------------
~e::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
f::
;------------------------------------------
  gosub clearMessage
  if(isTerran()){
    lastUnit:="f"
  
 }
 if(isProtoss()){
   sendInput b 
 }
 sendInput f
return 
;------------------------------------------
g::
;------------------------------------------
  gosub clearMessage
  if(isProtoss() && isActive()){   ;//if protoss then auto gate on the G key
    sendInput b
    sleep 50
  }
  if(isTerran()){
    lastUnit:="g"
  
  }
  sendInput g
return 
;------------------------------------------
~h::
;------------------------------------------
  if(isZerg()){
    lastUnit:="h"
  
  }
  gosub clearMessage
return 
;------------------------------------------
~i::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~j::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~k::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~l::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~m::
;------------------------------------------
  lastUnit:="m"
  gosub clearMessage
return 
;------------------------------------------
~n::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~o::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
p::     ;//if protoss then auto pylon on the P key
;------------------------------------------
  gosub clearMessage
  if(isProtoss() && isActive()){
    sendInput b
    sleep 50
  }
  sendInput p
return 
;------------------------------------------
~q::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~r::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~s::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~t::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~u::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~v::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~w::
;------------------------------------------
  lastUnit:="wm"
  gosub clearMessage
return 
;------------------------------------------
~x::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~y::
;------------------------------------------
  gosub clearMessage
return 
;------------------------------------------
~z::
;------------------------------------------
  gosub clearMessage
  lastUnit:="z"  
return 


 #IfWinActive


q335r49
  • Members
  • 28 posts
  • Last active: Mar 30 2010 04:05 AM
  • Joined: 26 Oct 2005
Dude... Flash or Jaedong? :shock: Finals are on in like 3 hours

000sixzeros000
  • Members
  • 43 posts
  • Last active: Apr 23 2011 08:11 AM
  • Joined: 17 Oct 2009
hmm, welll I was going to watch the Corus chess tourney, but the MSL Grand final is much more interesting.

Im rooting for the underdog..

thnx for the heads up.

tank
  • Administrators
  • 4345 posts
  • AutoHotkey Foundation
  • Last active: Feb 04 2019 09:54 PM
  • Joined: 21 Dec 2007
Nice script been a serious BW player since it was released in 97
Never lose.
WIN or LEARN.

kdoske
  • Members
  • 138 posts
  • Last active: Nov 06 2012 01:58 AM
  • Joined: 17 Dec 2008
i havn't test yet but this sounds fantastic!

Thanks so much

user_name_here
  • Guests
  • Last active:
  • Joined: --
Got an error message when trying to run your script:

Error: Target label does not exist.

Line#
        1504: showMessage("/Unit #"/(groupIndex+1)." of ".totalUnits)
        1505: }
        1506: wheelRolling :=1
        1507: SetTimer,clearRoller,50
        1508: }
        1509: Return
        1514: wheelRolling -=1
----> 1515: SetTimer,clearWheel,150
        1516: if (wheelRolling < -5)
        1516: {
        1517: Return
        1518: }
        1519: if (wheelRolling > -5)
        1519: {
        1520: Return

The program will exit.



000sixzeros000
  • Members
  • 43 posts
  • Last active: Apr 23 2011 08:11 AM
  • Joined: 17 Oct 2009
..oops patched.

accidently removed this function..

;------------------------------------------
clearWheel:
;------------------------------------------
  setTimer clearRoller,off
  wheelRolling:=0
return


clay1st
  • Guests
  • Last active:
  • Joined: --
It's a shame it doesn't work for brood war...

I was so excited when I saw this, may be worth cracking out SC original CD just to try this out.

anyone else had negative results for brood war?
(a couple of the macro's work e.g. the cloning one, but many e.g. zoning doesn't work for me.)

tank
  • Administrators
  • 4345 posts
  • AutoHotkey Foundation
  • Last active: Feb 04 2019 09:54 PM
  • Joined: 21 Dec 2007
what doesnt work for you the shortcuts havent changed?
Never lose.
WIN or LEARN.

clay1st
  • Guests
  • Last active:
  • Joined: --
checked on original SC, exactly the same problems.

for example, when I select a group, spin the mouse wheel up, then spin the mouse wheel down, it selects the same unit over and over again instead of cycling...

I can create building zones but when I try to use CTRL+F3/F2/F1 to build in one, or all of them at the same time it has no effect...

oh well...

000sixzeros000
  • Members
  • 43 posts
  • Last active: Apr 23 2011 08:11 AM
  • Joined: 17 Oct 2009
hi Clay.. there's a note up above about a potential problem that happens when the Autohotkey (scitex) editor is open at the same time.. seems that the editor also uses the Hotkeys CTRL 1.. CTRL 2, etc..

these conflict with starcraft, EVEN though the script is using
#ifwinactive ahk_class SWARClass

the problem you're describing is exactly how it manifests itself, causing the script to ignore the CNTL func keys, so it is unable to assign and recall groups.

I found the solution was to close the editor.. or to go into the editor and change it to remove the CNTL function keys, and it should all work again..

Edit.. **although I havent tested it.. there's another possible problem that comes to mind.. and that is one of speed, I did note that I had some issues with some instructions where I had to use sleeps to delay the hotkeys for as much as 100ms, because in some cases where you tell the script to set a hotkey SC needs a delay to actually set up the group, then the group becomes available a bit later.. there may be timing issues with some other hotkeys and instructions, you might look at the sleep commands around any keys that are failing and make them longer. It might be related to CPU speed, some might need more time. I figured though that most things within SC take less than 3 game cycles, and a game cycle is probably 20ms or so.

Enter_User_Name_Here
  • Members
  • 35 posts
  • Last active: Jan 19 2012 07:40 PM
  • Joined: 18 Apr 2010
@000sixzeros000: First off, thank you. I wouldn't have known where to begin on all the pixel searches. I imagine you put quite a bit of work into this. That said, I am having trouble getting any form of send or mouse control to function in game. I am unsure if this is due to the changes I have made -- although your original code does not work for me either. I wonder is this because I am running on Win7 in XP compatibility mode? Does your script really work for you? Mind testing mine if it does?

I have been able to test my changes to your coding in Notepad. Most notably, I changed the WheelUp & WheelDown to change between hotkey groups and SHIFT + WheelUp & SHIFT + WheelDown to change between Zones. MButton now cycles units in the current hotkey group (not just group 7). Seemed more natural to do this as you were only cycling one direction anyway.

I also condensed many of your hotkey commands, changed variable and function names to be a bit more descriptive, and added boolean variables instead of having to do 3 function calls every time you need to know which race the player is. Oh, I also added a function to replace all the sleep commands, WaitGameCycle() so that there is only 1 place you need to adjust (if need be) for timing.

EDIT: Around Line 967: NumberOfUnitsInGroup_%CurrentGroup% = CountUnits() should be :=
Same goes for line 1763.

EDIT: Removed "#" from Unit # and Zone # messages as it was sending the Win key (duh). Added ^v hotkey for checking brightness. Added SetKeyDelay and SetMouseDelay (just in case)

EDIT: Added DetermineHue to adjust for brightness differences (should work for any brightness setting -- tested most of them). Program now measures minimap box to determine proper offset to click the "center". Setting buildings in record mode is now triggered off of Shift + RButton as Shift + LButton would cancel buildings that were being built. Marked as v1.0 because I believe it is now fully functional.

Just a reminder if you are having trouble getting the program to respond in game, try running it as administrator.

; v1.0
#IfWinActive ahk_class SWarClass

#InstallKeybdHook
#InstallMouseHook
#SingleInstance

SendMode Input
SetKeyDelay, 50
SetMouseDelay, 50

DefineGlobals()

return
;==================================
; To reset boolean values after a game is played
;==================================
^+!z::
{
  DefineGlobals()
}
return

;==================================
;==================================
^+z::
{
  Force("Zerg")
}
return

;==================================
;==================================
^+p::
{
  Force("Protoss")
}
return

;==================================
;==================================
^+t::
{
  Force("Terran")
}
return

;==================================
;==================================
^+a::
{
  Force("Active")
}
return

;==================================
; Toggle auto-build
;==================================
^+b::
{
  AUTOBUILD_ENABLED := ~AUTOBUILD_ENABLED
}
return

;==================================
; Short-circuit the detection system for game active and player race
;==================================
Force(DoThis)
{ global PLAYER_IS_ZERG, PLAYER_IS_TERRAN, PLAYER_IS_PROTOSS, ForceActive
  if (DoThis = "Zerg") {
    PLAYER_IS_ZERG := TRUE
	PLAYER_IS_TERRAN := FALSE
	PLAYER_IS_PROTOSS := FALSE
    CheckRace()
	return
  }
  if (DoThis = "Terran") {
    PLAYER_IS_ZERG := FALSE
	PLAYER_IS_TERRAN := TRUE
	PLAYER_IS_PROTOSS := FALSE
    CheckRace()
	return
  }
  if (DoThis = "Protoss") {
    PLAYER_IS_ZERG := FALSE
	PLAYER_IS_TERRAN := FALSE
	PLAYER_IS_PROTOSS := TRUE
    CheckRace()
	return
  }
  if (DoThis = "Active") {
    ForceActive := ~ForceActive
    return
  }
}


;==================================
;==================================
DefineGlobals()
{ Global
  AttackPointX := 65
  AttackPointY := 408
  RallyPointX := 65
  RallyPointY := 408
  PLAYER_IS_PROTOSS := FALSE
  PLAYER_IS_TERRAN := FALSE
  PLAYER_IS_ZERG := FALSE
  GAME_CYCLE := 50
  SMALL_BOX_LENGTH := 10
  SMALL_OFFSET_X := 5
  SMALL_OFFSET_Y := 3
  LARGE_BOX_LENGTH := 20
  LARGE_OFFSET_X := 10
  LARGE_OFFSET_Y := 6
  LoopUntilActive()
  CheckRace()
  LastUnit := SetLastUnit()
  PlayerMessage := FALSE
  counter := 0
  Loop 10
  {
    Group_%counter% := 0
	NumberOfUnits_%counter% := 0
	counter += 1
  }

  ;####### Customize this section ###################
  AUTOBUILD_ENABLED := TRUE ;ie. for Protoss, p sends bp, g sends bg, c sends bc, f sends bf
  TerranPrimaryUnit := "mtw"
  TerranSecondaryUnit := "fvb"
  TerranSupportUnit := "gb"

  ProtossPrimaryUnit := "zso"
  ProtossSecondaryUnit := "d"
  ProtossSupportUnit := "t"

  ZergPrimaryUnit := "z"
  ZergSecondaryUnit := "h"
  ZergSupportUnit := "o"

  ProtossUgrades := "WASPHKL"
  TerranUpgrades := "WASPHKI"
  ZergUpgrades := "VPMWAEGBCSHKL"
  
}
return

;==================================
;==================================
LoopUntilActive()
{ global GPF_Loaded, MessageLineX, MessageLineY, YOffset  
  While ( Not(IsActive())) {
    WaitGameCycle()
  }
}
return

;==================================
;==================================
WaitGameCycle(NumberOfCycles=1)
{
  Global GAME_CYCLE
  Loop %NumberOfCycles%
  {
    Sleep %GAME_CYCLE%
  }
}
return
 
;==================================
;==================================
SetLastUnit()
{
  Global PLAYER_IS_TERRAN, PLAYER_IS_ZERG, PLAYER_IS_PROTOSS
  if ( PLAYER_IS_TERRAN ) {
    return "m"
  }
  if ( PLAYER_IS_ZERG ) {
    return "z"
  }
  if ( PLAYER_IS_PROTOSS ) {
    return "z"
  }
}
;##################################################

;==================================
;==================================
CanAttack()
{
  Global PLAYER_IS_TERRAN, PLAYER_IS_PROTOSS
  if ( PLAYER_IS_TERRAN OR PLAYER_IS_PROTOSS ) {
    return ( ( CheckPixelColor(0xc6c244,603,365,10) AND CheckPixelColor(0xfcd43b,612,374,10) ) OR ( CheckPixelColor(0xd4e5d7,603,365,10) AND CheckPixelColor(0xf2f2f2,612,374,10) ) )
  } else {
    return ( ( CheckPixelColor(0xc6c244,598,368,10) AND CheckPixelColor(0xfcd43b,607,377,10) ) OR ( CheckPixelColor(0xd4e5d7,598,368,10) AND CheckPixelColor(0xf2f2f2,607,377,10) ) )
  }
}

;==================================
;==================================
CheckColor(RGBValue,RGBTarget,vRange)    ; make sure pixels are within a range to compensate for gamma
{
  vHue := DetermineHue(RGBValue)
  tHue := DetermineHue(RGBTarget)
  if ( (vHue > (tHue + vRange)) OR (vHue < (tHue - vRange)) ) {
    return FALSE
  }
  return TRUE
}

;==================================
;==================================
DetermineHue(RGBValue)
{
  Red := 0
  Green := 0
  Blue := 0
  SplitRGBColor(RGBValue, Red, Green, Blue)
  if ( (Red >= Green) AND (Green >= Blue ) ) {
    Hue := 60 * (Green - Blue) / (Red - Blue)
  } else if ((Green > Red) AND (Red >= Blue)) {
    Hue := 60 * ( 2 - (Red - Blue) / (Green - Blue) )
  } else if ((Green >= Blue) AND (Blue > Red)) {
    Hue := 60 * ( 2 + (Blue - Red) / (Green - Red) )
  } else if ((Blue > Green) AND (Green > Red)) {
    Hue := 60 * ( 4 - (Green - Red) / (Blue - Red) )
  } else if ((Blue > Red) AND (Red >= Green )) {
    Hue := 60 * ( 4 + (Red - Green) / (Blue - Green) )
  } else if ((Red >= Blue) AND (Blue > Green)) {
    Hue := 60 * ( 6 - (Blue - Green) / (Red - Green) )
  } else {
    Hue := ""
  }
  return Hue
}

;==================================
;==================================
SplitRGBColor(RGBColor, ByRef Red, ByRef Green, ByRef Blue)
{
  Red := RGBColor >> 16 & 0xFF
  Green := RGBColor >> 8 & 0xFF
  Blue := RGBColor & 0xFF
}
return
  
;==================================
;==================================
CheckPixelColor(TargetPixelColor,xpos,ypos,vRange = 10)
{
  PixelGetColor, PixelColor, xpos, ypos,RGB
  return CheckColor(PixelColor,TargetPixelColor,vRange)
}

;==================================
;==================================
CheckRace()
{
  Global PLAYER_IS_PROTOSS, PLAYER_IS_TERRAN, PLAYER_IS_ZERG
 
  if (PLAYER_IS_PROTOSS OR PLAYER_IS_TERRAN OR PLAYER_IS_ZERG) {
    ShowMessage("/Race forced")
    return
  }
  
  ; is protoss 3bbfa2
  if (IsProtoss()) {
    ShowMessage("/Found Protoss")
    PLAYER_IS_PROTOSS := TRUE
    return "Protoss"
  }
 
  ; is terran 36363f
  if (IsTerran()) {
    ShowMessage("/Found Terran")
    PLAYER_IS_TERRAN := TRUE
    return "Terran"
  }
 
  ; is zerg 797979
  if (IsZerg()) {
    ShowMessage("/Found Zerg")
    PLAYER_IS_ZERG := TRUE
    return "Zerg"
  }

  ShowMessage("/nothing detected")
}
return

;==================================
;==================================
ClickStage(StageNum)
{
  BlockInput on
  SaveMousePosition()
  if (StageNum > 7) {
    Stage := StageNum - 8
    send v
    WaitGameCycle(2)
  } else {
     Stage := StageNum
     send b
     WaitGameCycle(2)
  }
 
  Column := mod(Stage,3)
  Row := floor(Stage/3)
 
  xpos:=505+20+(Column * 47)
  ypos:=356+20+(Row * 40)
 
  MouseMove, Target(xpos), Target(ypos), 0
  WaitGameCycle(2)
  send {click}
  WaitGameCycle(2)
  RestoreMousePosition()
  BlockInput off
}
return

;==================================
;==================================
CountUnits()
{
  SearchX := 169
  SearchY := 398
  ColumnOffset := 36
  RowOffset := 37
  pColor := 0x1459d4  
  total := 0
  Loop, 2
  {
    SearchX := 169
    Loop, 6
    {
      if (CheckPixelColor(pColor,SearchX,SearchY,10)) {
        total++
      }
      SearchX += ColumnOffset
    }
    SearchY += RowOffset
  }
  if (total = 0) {
    total := 1
  }
  return total
}

;==================================
;==================================
DeselectUnit()
{
 SaveMousePosition()
 xpos := 169 + 15
 ypos := 398 + 15
 MouseMove,%xpos%,%ypos%,0
 WaitGameCycle()
 send {shift down}{click}{shift up}
 WaitGameCycle()
 RestoreMousePosition()
}
return

;==================================
;==================================
GetMiniMapPosition()
{ 
  global MiniMapX, MiniMapY, SMALL_BOX_LENGTH, MEDIUM_BOX_LENGTH, LARGE_BOX_LENGTH
  global SMALL_OFFSET_X, SMALL_OFFSET_Y, MEDIUM_OFFSET_X, MEDIUM_OFFSET_Y, LARGE_OFFSET_X, LARGE_OFFSET_Y
  if (GetMiniMapCorner() ) {
    MiniMapBoxLength := GetLengthOfMiniMapBox(MiniMapX, MiniMapY)
    if (MiniMapBoxLength <= SMALL_BOX_LENGTH) {
      OffsetX := SMALL_OFFSET_X
      OffsetY := SMALL_OFFSET_Y
    } else if (MiniMapBoxLength <= LARGE_BOX_LENGTH) {
      OffsetX := LARGE_OFFSET_X
      OffsetY := LARGE_OFFSET_Y
    } else {
      return FALSE
    }
    MiniMapX += OffsetX
    MiniMapY += OffsetY
    return TRUE
  } else {
    return FALSE
  }
}


;==================================
;==================================
GetMiniMapCorner()
{
  global MiniMapX,MiniMapY
  PixelSearch MiniMapX,MiniMapY, 5,348,133,477,0xffffff,1
  if (ErrorLevel = 0) {
    return TRUE
  }
  return FALSE
}

;==================================
;==================================
GetLengthOfMiniMapBox(x, y)
{
  color := 0xFFFFFF
  End_X := x
  while (color = 0xFFFFFF) {
    End_X += 1
    PixelGetColor, color, End_X, y, RGB
  }
  return (End_X - x)
}

;==================================
;==================================
IsActive()   ; are we in game or in lobby? lobby=not true in game=true
{ global ForceActive  
  return ( ForceActive OR CheckPixelColor(0x2d23c2, 436, 3, 10) )
}

;==================================
;==================================
IsProtoss()
{
  return CheckPixelColor(0x3bbfa2, 5, 317, 10)
}

;==================================
;==================================
IsTerran()
{
  return CheckPixelColor(0x36363f, 5, 317, 10)
}

;==================================
;==================================
IsZerg()
{
  return CheckPixelColor(0x797979, 5, 317, 10)
}

;==================================
;==================================
IsRally() ; does unit have a rally point option?
{
  if (PLAYER_IS_ZERG) {
    return ( CheckPixelColor(0xfcd43b, 553, 367, 10) AND CheckPixelColor(0xfcd43b, 572, 387, 3) )
  } else {
    return ( CheckPixelColor(0xfcd43b, 623, 423, 10) AND CheckPixelColor(0xfcd43b, 604, 404, 3) )
  }
}

;==================================
;==================================
ProcessUpgrades()
{
  Global PLAYER_IS_PROTOSS, PLAYER_IS_TERRAN, PLAYER_IS_ZERG, ProtossUpgrades, TerranUpgrades, ZergUpgrades
  if (PLAYER_IS_PROTOSS) {
    send %ProtossUpgrades%
  }
  if (PLAYER_IS_TERRAN) {
    send %TerranUpgrades%
  }
  if (PLAYER_IS_ZERG) {
    send %ZergUpgrades%
  }
}
return

;==================================
;==================================
RestoreMiniMapPosition()
{
 Global Stored_MiniMap_X,Stored_MiniMap_Y
 SetMiniMapPosition(Stored_MiniMap_X,Stored_MiniMap_Y)
}
return

;==================================
;==================================
RestoreMousePosition()
{
 Global Stored_Mouse_X,Stored_Mouse_Y
 MouseMove,%Stored_Mouse_X%, %Stored_Mouse_Y%, 0
}
return

;==================================
;==================================
SaveMiniMapPosition()
{
  Global Stored_MiniMap_X,Stored_MiniMap_Y,MiniMapX,MiniMapY
  if (GetMiniMapPosition() ) {
    Stored_MiniMap_X := MiniMapX
    Stored_MiniMap_Y := MiniMapY
    return TRUE
  }
  return FALSE
}


;==================================
;==================================
SaveMousePosition()
{
  Global Stored_Mouse_X,Stored_Mouse_Y
  MouseGetPos Stored_Mouse_X, Stored_Mouse_Y
}
return

;==================================
;==================================
SelectNothing() ; stops detect errors when mouse is in the select area.
{
  MouseGetPos MouseX,MouseY
  if (MouseY > 370) {
    MouseMove, 148, 372, 0
    WaitGameCycle()
  }
}
return

;==================================
;==================================
SelectUnit(UnitNum)
{
  Column := floor(UnitNum/2)
  Row := mod(UnitNum,2)
 
  Xpos := 169+15+(Column * 36)
  Ypos := 398+15+(Row * 37)
 
  MouseMove, %xpos%, %ypos%, 0
  WaitGameCycle()
  send {click}
  WaitGameCycle()
}
return

;==================================
;==================================
ShowMessage(Message)
{
  Global MsgActive
  gosub ClearMessage
  if ( IsActive() ) {
    setTimer ClearMessage,500
    MsgActive := TRUE
    send {enter}%Message%
  }
}
return

;==================================
;==================================
SendMessage(Message) ; sends a message out rather than just show personal messages, mainly used for debugging
{
  Global MsgActive
  gosub ClearMessage
  if ( IsActive() ) {
    setTimer ClearMessage,500
    MsgActive := TRUE
    send {enter}%Message%{enter}
  }
}
return

;==================================
;==================================
sendR(strData, delay = 30) ; send string with delay
{
  loop, Parse, strData
  {
    send %A_LoopField%
    sleep delay
  }
}
return

;==================================
;==================================
SetMiniMapPosition(xp,yp)
{
  BlockInput On
  SaveMousePosition()
  MouseMove %xp%, %yp%, 0
  WaitGameCycle()
  send {click}
  WaitGameCycle()
  RestoreMousePosition()
  BlockInput Off
}
return

;==================================
;==================================
Target(Axis)   ; randomize the target locations
{
  random target, (Axis - 3), (Axis + 3)
  return target
}

;==================================
;==================================
RunForBuildingsInZone(TypeOfProduction)
{
  Global
  BlockInput,on
  SaveMousePosition()
  SaveMiniMapPosition()
  gosub SetCurrentZone
  gosub ClearMessage
  WaitGameCycle()
  if ( MiniMap_%CurrentZone% ) {
    loop, % Total_%CurrentZone%
    {
      ThisIndex := A_Index
      gosub SelectBuilding
      WaitGameCycle(2)
      gosub %TypeOfProduction%
      WaitGameCycle(2)
    }
  }
  RestoreMiniMapPosition()
  RestoreMousePosition()
  BlockInput Off
} 
return

;==================================
; SUBROUTINES
;==================================

;==================================
;==================================
ClearMessage:
  setTimer ClearMessage, Off
  if (MsgActive AND IsActive() ) {
    MsgActive := FALSE
    send {esc}
  }
return

;==================================
;==================================
ClearRoller:
  setTimer ClearRoller, Off
  WheelRolling := FALSE
return

;==================================
;==================================
RecordModeOff:
 setTimer RecordModeOff, Off
 RecordMode :=  FALSE
 ShowMessage("/Record Mode off")
return

;==================================
;==================================
ActivateZone:
 CurrentZone := ThisKey
; no return -- intentionally falling through to SetCurrentZone!

SetCurrentZone:
  if (MiniMap_%CurrentZone%) {
    SetMiniMapPosition( MiniMap_%CurrentZone%_Xpos, MiniMap_%CurrentZone%_Ypos )
    ShowMessage("/Zone [" . CurrentZone . "] Activated (" . MiniMap_%CurrentZone%_Xpos . " : " . MiniMap_%CurrentZone%_Ypos . ") ")
  }
return

;==================================
;==================================
RecordZone:
  CurrentZone := ThisKey
  if (MiniMap_%CurrentZone%) {
      MiniMap_%CurrentZone%:= FALSE
      ShowMessage("/Zone " . CurrentZone . " removed")
  } else {
    MiniMap_%CurrentZone% :=  TRUE
    if ( SaveMiniMapPosition() ) {
      RestoreMiniMapPosition()
      ShowMessage("/Zone " . CurrentZone . " (" . MiniMapX . " : " . MiniMapY . ") Now set buildings")
      MiniMap_%CurrentZone%_Xpos := MiniMapX
      MiniMap_%CurrentZone%_Ypos := MiniMapY    
      SetTimer RecordModeOff,2000
      RecordMode := TRUE
      Total_%CurrentZone% := 0
    } else {
      showMessage("/Error Bad MiniMap")
    }
  }
return

;==================================
;==================================
SelectBuilding:
{
  x := xp_%CurrentZone%_%ThisIndex%
  y := yp_%CurrentZone%_%ThisIndex%
  MouseMove, %x%, %y%, 0  
  send {click}
}
return

;==================================
;==================================
SetRallyPoint:
{
  send r
  WaitGameCycle(2)
  MouseMove, %RallyPointX%, %RallyPointY%, 0
  WaitGameCycle()
  send {click}
  WaitGameCycle()
}
return

;==================================
;==================================
MakeWorkerUnit:
{
  gosub ClearMessage
  if ( IsActive() ) {
    if (PLAYER_IS_TERRAN) {
      send s
    }
    if (PLAYER_IS_PROTOSS) {
      send p
    }
    if (PLAYER_IS_ZERG) {
      send s
      WaitGameCycle(3)
      send d
    }
  }
}
return

;==================================
;==================================
MakePrimaryUnit:
{
  gosub ClearMessage
  if ( IsActive() ) {
    if (PLAYER_IS_TERRAN) {
      send %TerranPrimaryUnit%
    }
    if (PLAYER_IS_PROTOSS) {
      send %ProtossPrimaryUnit%
    }
    if (PLAYER_IS_ZERG) {
      send s
      WaitGameCycle(3)
      send %ZergPrimaryUnit%
    }
  }
}
return

;==================================
;==================================
MakeSecondaryUnit:
{
  gosub ClearMessage
  if ( IsActive() ) {
    if (PLAYER_IS_TERRAN) {
      send %TerranSecondaryUnit%
    }
    if (PLAYER_IS_PROTOSS) {
      send %ProtossSecondaryUnit%
    }
    if (PLAYER_IS_ZERG) {
      send s
      WaitGameCycle(3)
      send %ZergSecondaryUnit%
    }
  }
}
return

;==================================
;==================================
MakeSupportUnit:
{
  gosub ClearMessage
  if ( IsActive() ) {
    if (PLAYER_IS_TERRAN) {
      send %TerranSupportUnit%
    }
    if (PLAYER_IS_PROTOSS) {
      send %ProtossSupportUnit%
    }
    if (PLAYER_IS_ZERG) {
      send s
      WaitGameCycle(3)
      send %ZerSupportUnit%
    }
  }
}
return

;==================================
;==================================
MakeDefiler:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send s
    WaitGameCycle(3)
    send f
  }
}
return

;==================================
;==================================
MakeCarrier:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send c
  }
}
return

;==================================
;==================================
MakeDarkTemplar:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send k
  }
}
return

;==================================
;==================================
MakeDragoon:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send d
  }
}
return

;==================================
;==================================
MakeFirebat:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send f
  }
}
return

;==================================
;==================================
MakeGoliath:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send g
  }
}
return

;==================================
;==================================
MakeHydra:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send s
    WaitGameCycle(3)
    send h
  }
}
return

;==================================
;==================================
MakeMarine:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send m
  }
}
return

;==================================
;==================================
MakeMedic:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send c
  }
}
return

;==================================
;==================================
MakeMuta:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send s
    WaitGameCycle(3)
    send m
  }
}
return

;==================================
;==================================
MakeObserver:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send o
  }
}
return

;==================================
;==================================
MakeOverlord:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send s
    WaitGameCycle(3)
    send o
  }
}
return

;==================================
;==================================
MakeScout:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send s
  }
}
return

;==================================
;==================================
MakeUltralisk:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send s
    WaitGameCycle(3)
    send u
  }
}
return

;==================================
;==================================
MakeReaver:
 ; Purposely falling through to MakeVulture
MakeVulture:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send v
  }
}
return

;==================================
;==================================
MakeHighTemplar:
; Purposely fall through to MakeTank
MakeTank:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send t
  }
}
return

;==================================
;==================================
MakeZergling:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send s
    WaitGameCycle(3)
    send z
  }
}
return

;==================================
;==================================
MakeZealot:
{
  gosub ClearMessage
  if ( IsActive() ) {
    send z
  }
}
return

;==================================
;==================================
NumPadAttackPoint:
{
  gosub ClearMessage
  BlockInput on
  SaveMousePosition()
  send a
  WaitGameCycle(2) 
  MouseMove, Target( AttackHere_X), Target(AttackHere_Y), 0
  WaitGameCycle()
  send {click}
  sleep 10
  RestoreMousePosition()
  BlockInput off
}
 return

;==================================
; Hot Keys
;==================================

;==================================
; basic clone technique.. will R-CLICK assign all units to mouse location then drop 1 unit..
; an be used to send all workers to unique mineral patches or to send units to different map locations
;==================================
`::
{
  send {click right}
  DeselectUnit()
}
return

;==================================
; a test function to see if the script is working..
;==================================
?:: 
{
  CheckRace()
  if ( IsActive() ) {
    ShowMessage("/Is active ok")
  }
}
return

;==================================
; cycle (backward) through the zones
;==================================
,::
+WheelUp::
{
  gosub ClearMessage
  FoundZone := FALSE
  loop, 10
  {
    CurrentZone += -1
    if (CurrentZone < 0 ) {
      CurrentZone := 9
    }
    ThisKey = %CurrentZone%
    if ( MiniMap_%CurrentZone% ) {
      FoundZone:= TRUE
      SaveMousePosition()
      SetMiniMapPosition( MiniMap_%CurrentZone%_Xpos, MiniMap_%CurrentZone%_Ypos )
      RestoreMousePosition()
      BuildingsAssigned := Total_%CurrentZone%
      ShowMessage("/Zone " . CurrentZone . ": total buildings = " . BuildingsAssigned)    
    }
    if (FoundZone) {
      break
    }
  }
}
return

;==================================
; cycle (forward) through the zones
;==================================
.::
+WheelDown::
{
  gosub ClearMessage
  FoundZone:= FALSE
  loop, 10
  {
    CurrentZone += 1
    if (CurrentZone > 9) {
      CurrentZone := 0
    }
    ThisKey = %CurrentZone%
   
    if (MiniMap_%CurrentZone%) {
      FoundZone:= TRUE
      SaveMousePosition()
      SetMiniMapPosition( MiniMap_%CurrentZone%_Xpos, MiniMap_%CurrentZone%_Ypos )
      RestoreMousePosition()
      BuildingsAssigned := Total_%CurrentZone%
      ShowMessage("/Zone " . CurrentZone . ": total buildings = " . BuildingsAssigned)    
    }
    if (FoundZone) {
      break
    }
  }
}
return

;==================================
; save minimap position
;==================================
$+0::
$+1::
$+2::
$+3::
$+4::
$+5::
$+6::
$+7::
$+8::
$+9::
{
  ThisKey := SubStr( A_ThisHotkey, 0)
  gosub RecordZone
}
return

;==================================
; restore minimap position
;==================================
$!0::
$!1::
$!2::
$!3::
$!4::
$!5::
$!6::
$!7::
$!8::
$!9::
{
  ThisKey := SubStr( A_ThisHotkey, 0)
  gosub ActivateZone
}
return

;==================================
; assign units to a hotkey
;==================================
$^0::
$^1::
$^2::
$^3::
$^4::
$^5::
$^6::
$^7::
$^8::
$^9::
{
  Hot_Key_Index := SubStr( A_ThisHotkey, 0)
  if ( HotKey_%Hot_Key_Index%_Set ) {
    HotKey_%Hot_Key_Index%_Set := FALSE
    ShowMessage("/Hotkey " . Hot_Key_Index . " removed from HotKey cycle")    
  } else {
    HotKey_%Hot_Key_Index%_Set := TRUE
    CurrentGroup := Hot_Key_Index
    NumberOfUnitsInGroup_%CurrentGroup% := CountUnits()
    Group_%CurrentGroup% := 0
    ShowMessage("/Hotkey " . Hot_Key_Index . " added to HotKey cycle. " . NumberOfUnitsInGroup_%Hot_Key_Index% . " units.")    
  }
  send {ctrl down}%Hot_Key_Index%{ctrl up}
}
return

;==================================
; MOUSE BUTTON FUNCTIONS
;==================================

;==================================
; assign rally target point to current unit
;==================================
!LButton::
{
  MouseGetPos UserMousePosition_X, UserMousePosition_Y
  if ( (UserMousePosition_X < 135) AND (UserMousePosition_Y > 345) ) {  ; Mouse is in mini-map
    send {click}
  } else {
    send {click}
    WaitGameCycle(2)
    if ( IsRally() ) {
      send r
      WaitGameCycle()      
      BlockInput on
      MouseGetPos UserMousePosition_X, UserMousePosition_Y
      MouseMove,RallyPointX, RallyPointY ,0
      send {click}
      sleep 10
      BlockInput off
    }
    MouseMove, UserMousePosition_X, UserMousePosition_Y,0
  }
}
return

;==================================
; Exit Build Mode
;==================================
~Lbutton::
{
  if (BuildMode) {
    BuildMode:= FALSE
  }
}
return

;==================================
; record mode records the actual building locations of a zone
;==================================
~+RButton::
{
  if ( RecordMode ) {
    WaitGameCycle()
    Total_%CurrentZone% += 1
    ThisIndex := Total_%CurrentZone%
    MouseGetPos, xp_%CurrentZone%_%ThisIndex%, yp_%CurrentZone%_%ThisIndex%
    ShowMessage("/Zone[" . CurrentZone . "] Building[" . ThisIndex . "]=(" . xp_%CurrentZone%_%ThisIndex% . " : " . yp_%CurrentZone%_%ThisIndex% . ")" )
    setTimer RecordModeOff,2000
  } else {
    send {shift down}{click}{shift up}
  }
}
return

;==================================
; set rally target point
;==================================
!RButton::
{
  MouseGetPos UserMousePosition_X, UserMousePosition_Y
  RallyPointX := UserMousePosition_X
  RallyPointY := UserMousePosition_Y
  ShowMessage("/Rally Point ( " . RallyPointX . " : " . RallyPointY . " )")
}
return

;==================================
; set dynamic attack point and assign this point to the CTRL NUMPAD-0 key / assign upgrades
;==================================
^RButton::
{
  gosub ClearMessage
  MouseGetPos UserMousePosition_X,UserMousePosition_Y
  if ( (UserMousePosition_X < 135) AND (UserMousePosition_Y > 345) ) {  ; Cursor in mini-map
      ; set rally target point
      AttackPointX := UserMousePosition_X
      AttackPointY := UserMousePosition_Y
      ShowMessage("/Attack Point ( " . AttackPointX . " : " . AttackPointY . " )")
  } else {
    ; group and attack the point
    BlockInput On
    send {Ctrl Down}{Lbutton}
    WaitGameCycle()
    send {ctrl up}
    if ( CanAttack() ) {
      send a
      WaitGameCycle()
      MouseMove, Target(AttackPointX), Target(AttackPointY),0
      WaitGameCycle()
      send {click}
      WaitGameCycle()
    } else {
      ProcessUpgrades()
    }
    BlockInput off
  }
  MouseMove,UserMousePosition_X, UserMousePosition_Y, 0
}
return

;==================================
; Produce Worker Units
;==================================
^f1::
{
  RunForBuildingsInZone("MakeWorkerUnit")
}
return

;==================================
; universal worker key
;==================================
f1::
{
  gosub MakeWorkerUnit
}

;==================================
; Mass universal primary military unit
;==================================
^f2::
{
  RunForBuildingsInZone("MakePrimaryUnit")
}
return

;==================================
; universal primary military unit
;==================================
f2::
{
  gosub MakePrimaryUnit
}
return

;==================================
; Mass universal secondary unit
;==================================
^f3::
{
  RunForBuildingsInZone("MakeSecondaryUnit")
}
return

;==================================
; universal secondary unit
;==================================
f3::
{
  gosub MakeSecondaryUnit
}
return

;==================================
; Mass universal support unit
;==================================
^f4::
{
  RunForBuildingsInZone("MakeSupportUnit")
}
return

;==================================
; universal support unit
;==================================
f4::
{
  gosub MakeSupportUnit
}
return

;==================================
; an experiment to allow building creation via the mouse wheel,
; so you can use say f5 to select depot/barrcks/factory/starport, etc..
;==================================
f5::
{
  gosub ClearMessage
  if ( BuildMode ) {
    BuildMode := FALSE
    send {esc}
  } else {
    BuildMode := TRUE
    if (BuildStage = "") {
      BuildStage := 2
    }
    ClickStage( BuildStage )
  }
}
return

;==================================
; upgrade sequences..
;==================================
f8::
{
  gosub ClearMessage
  if (PLAYER_IS_PROTOSS) {
    send %ProtossUgrades%
  }
  if (PLAYER_IS_TERRAN) {
    send %TerranUpgrades%
  }
  if (PLAYER_IS_ZERG) {
    send %ZergUpgrades%
  }
}
return

;==================================
; pylon /depot /lord
;==================================
f9::
{
  gosub ClearMessage
  if (PLAYER_IS_PROTOSS) {
    send b
    WaitGameCycle(2)
    send p
  }
  if (PLAYER_IS_TERRAN) {
    send b
    WaitGameCycle(2)
    send s
  }
  if (PLAYER_IS_ZERG) {
    send s
    WaitGameCycle(2)
    send o
  }
}
return

;==================================
; build gate / barracks / hatch
;==================================
f10::
{
  gosub ClearMessage
  send b
  WaitGameCycle(2)
  if (PLAYER_IS_PROTOSS) {
    send g
  }
  if (PLAYER_IS_TERRAN) {
    send b
  }
  if (PLAYER_IS_ZERG) {
    send h
  }
}
return

;==================================
; assimilator/refinary/extractor
;==================================
f11::
{
  gosub ClearMessage
  send b
  WaitGameCycle(2)
  if (PLAYER_IS_PROTOSS) {
    send a
  }
  if (PLAYER_IS_TERRAN) {
    send r
  }
  if (PLAYER_IS_ZERG) {
    send e
  }
}
return

;==================================
; Build Nexus / Command Center / Hatchery
;==================================
f12::
{
  gosub ClearMessage
  send b
  WaitGameCycle(2)
  if (PLAYER_IS_PROTOSS) {
    send n
  }
  if (PLAYER_IS_TERRAN) {
    send c
  }
  if (PLAYER_IS_ZERG) {
    send h
  }
}
return

; Set up numpad attacks
;   (10)  (12)  (2)
;     \    |    /
;      [7][8][9]
; (9)--[4][5][6]--(3)
;      [1][2][3]
;     /    |    \
;   (7)   (6)   (5)
;

;==================================
^Numpad0::
Numpad0::
NumpadIns::
^NumpadIns::
;==================================
{
  AttackHere_X := AttackPointX
  AttackHere_Y := AttackPointY
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad1::
Numpad1::
NumpadEnd::
^NumpadEnd::
;==================================
{
  AttackHere_X := 16
  AttackHere_Y := 463
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad2::
Numpad2::
NumpadDown::
^NumpadDown::
;==================================
{
  AttackHere_X := 65
  AttackHere_Y := 463
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad3:: ; attack bottom right mini map location
Numpad3::
NumpadPgdn::
^NumpadPgdn::
;==================================
{
  AttackHere_X := 122
  AttackHere_Y := 463
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad4::
Numpad4::
Numpadleft::
^Numpadleft::
;==================================
{
  AttackHere_X := 16
  AttackHere_Y := 408
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad5::
Numpad5::
NumPadClear::
^NumPadClear::
;==================================
{
  AttackHere_X := 65
  AttackHere_Y := 408
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad6:: ; attack right mid mini map location
Numpad6::
NumpadRight::
^NumpadRight::
;==================================
{
  AttackHere_X := 122
  AttackHere_Y := 408
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad7::
Numpad7::
numpadhome::
^numpadhome::
;==================================
{
  AttackHere_X := 15
  AttackHere_Y := 362
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad8::
Numpad8::
Numpadup::
^Numpadup::
;==================================
{
  AttackHere_X := 65
  AttackHere_Y := 362
  gosub NumPadAttackPoint
}
return

;==================================
^Numpad9::   ; attack top right map location
Numpad9::
NumpadPgup::
^NumpadPgup::
;==================================
{
  AttackHere_X := 122
  AttackHere_Y := 362
  gosub NumPadAttackPoint
}
return

;==================================
; Pause the game
;==================================
Pause::
{
  if ( IsActive() ) {
    send  {f10}
    WaitGameCycle(3)
    sendR("pr",50)
    WaitGameCycle(2)
    send {esc}
  }
}
return

;==================================
; cycle through tab locations
;==================================
tab::
+Mbutton::
{
  if (tabCycle =) {
    tabCycle := 1
  }
  tabCycle += 1
  if (tabCycle > 4) {
    tabCycle = 2
  }
 
  send {f%tabCycle%}
}
return

;==================================
; increase latency
;==================================
NumpadSub::
{
  if ( IsActive() ) {
    send  {f10}
    WaitGameCycle(3)
    sendR("onlo",100)
    WaitGameCycle(3)
    send {esc}
  }
}
return
;==================================
; decrease latency
;==================================
NumpadAdd::
{
  if ( IsActive() ) {
    send  {f10}
    WaitGameCycle(3)
    sendR("oneo",100)
    WaitGameCycle(3)
    send {esc}
  }
}
return

;==================================
; select the next unit in the current group
;==================================
Mbutton::
{
  gosub ClearMessage
  send %CurrentGroup%
  WaitGameCycle(2)
  NumberOfUnits_%CurrentGroup% := CountUnits()
  if (Group_%CurrentGroup% < NumberOfUnits_%CurrentGroup%) {
    Group_%CurrentGroup%++
  } else {
    Group_%CurrentGroup% = 0
  }
   SaveMousePosition()
   SelectNothing()
   SelectUnit(Group_%CurrentGroup%)
   RestoreMousePosition()
   UnitNumber := Group_%CurrentGroup% + 1
   ShowMessage("/Unit " . UnitNumber . " of " . NumberOfUnits_%CurrentGroup%)
}
return

;==================================
; add the currently selected units to a new hotkey group
; will use the current group if all hotkeys are taken
;==================================
^Mbutton::
{
  gosub ClearMessage
  Loop 10
  {
    Group := A_Index - 1
    if (HotKey_%Group%_Set) {
      continue
    }
    CurrentGroup := Group
    HotKey_%CurrentGroup%_Set := TRUE
  }
  send {ctrl down}%CurrentGroup%{ctrl up}
  WaitGameCycle(2)
  NumberOfUnits_%CurrentGroup% := CountUnits()
  Group_%CurrentGroup% := 0
  ShowMessage("/Hotkey " . Hot_Key_Index . " added to HotKey cycle. " . NumberOfUnitsInGroup_%Hot_Key_Index% . " units.")    
}
return  

;==================================
; cycle (forwards) through hotkey groups
;==================================
WheelDown::
{
  if ( BuildMode ) {
    BuildStage--
    gosub ClearMessage
    if ( BuildStage < 0 ) {
      BuildStage := 11
    }
    send {esc}
    WaitGameCycle(2)
    ClickStage(BuildStage)
    ShowMessage("/Stage " . BuildStage)
  } else {
    if (!WheelRolling) {
      WheelRolling := TRUE
      setTimer ClearRoller,50
      gosub ClearMessage
      while (1) {
        HotkeyCycle++
        if (HotKeyCycle > 9) {
          HotkeyCycle := 0
        }
        if (HotKey_%HotKeyCycle%_Set) {
          CurrentGroup := HotKeyCycle
          send %CurrentGroup%
          send %CurrentGroup%
          WaitGameCycle(3)
          NumberOfUnitsInGroup_%CurrentGroup% := CountUnits()
          break
        }
      }
    }
    WheelRolling := TRUE
    setTimer ClearRoller,50
  }
}
return

;==================================
; cycle (backwards) through hotkey groups
;==================================
WheelUp::
{
  WheelRolling := FALSE
  setTimer ClearRoller,150

  if (BuildMode) { ; manage build mode (f5)
    BuildStage += 1
    if (BuildStage > 11) {
      BuildStage := 0
    }
    send {esc}
    WaitGameCycle(2)
    ClickStage(BuildStage)
    ShowMessage("/Stage " . BuildStage)
  } else { ; manage hotkey groups
    if (!WheelRolling) {
      WheelRolling := TRUE
      setTimer ClearRoller,50
      gosub ClearMessage
      while (1) {
        HotkeyCycle--
        if (HotKeyCycle < 0) {
          HotkeyCycle := 9
        }
        if (HotKey_%HotKeyCycle%_Set) {
          CurrentGroup := HotKeyCycle
          send %CurrentGroup%
          send %CurrentGroup%
          WaitGameCycle(3)
          NumberOfUnitsInGroup_%CurrentGroup% := CountUnits()
          break
        }
      }
    }
    WheelRolling := TRUE
    setTimer ClearRoller,50
  }
}
return

;==================================
; all points attack
;==================================
^a::
{
  gosub ClearMessage
  BlockInput on
  SaveMousePosition()
  MouseMove, Target(AttackPointX), Target(AttackPointY), 0
  WaitGameCycle()
  Loop,10
  {
    TheKey := A_Index - 1
    send %TheKey%
    WaitGameCycle()
    send a
    WaitGameCycle()
    send {click}
    WaitGameCycle()
  }
  RestoreMousePosition()
  BlockInput off
}
return

;==================================
; Mass Carries / Medics
;==================================
^c::
{
  if (PLAYER_IS_PROTOSS) {
    RunForBuildingsInZone("MakeCarrier")      
  }
  if (PLAYER_IS_TERRAN) {
    RunForBuildingsInZone("MakeMedic")
  }
}
return


;==================================
; Mass Dragoons / Drones
;==================================
^d::
{
  if (PLAYER_IS_PROTOSS) {
    RunForBuildingsInZone("MakeDragoon")      
  }
  if (PLAYER_IS_ZERG) {
    RunForBuildingsInZone("MakeWorkerUnit")
  }
}
return

;==================================
; Mass Firebats... Defiler
;==================================
^f::
{
  if (PLAYER_IS_TERRAN) {
    RunForBuildingsInZone("MakeFirebat")
  }
  if (PLAYER_IS_ZERG) {
    RunForBuildingsInZone("MakeDefiler")
  }
}
return
;==================================
; Mass Goliath / Ghost / Dragoons
;==================================
^g::
{
  if (PLAYER_IS_TERRAN) {
    RunForBuildingsInZone("MakeGoliath")
  }
  if (PLAYER_IS_PROTOSS) {
    RunForBuildingsInZone("MakeDragoon")      
  }
}
return

;==================================
; Mass Hydra
;==================================
^h::
{
  if (PLAYER_IS_ZERG) {
    RunForBuildingsInZone("MakeHydra")
  }
}
return

;==================================
; Mass Dark Templar
;==================================
^k::
{
  if (PLAYER_IS_PROTOSS) {
    RunForBuildingsInZone("MakeDarkTemplar")
  }
}
return

;==================================
; Mass Marines or Mass Mutas
;==================================
^m::
{
  if (PLAYER_IS_TERRAN) {
    RunForBuildingsInZone("MakeMarine")
  }
  if (PLAYER_IS_ZERG) {
    RunForBuildingsInZone("MakeMuta")
  }
}
return

;==================================
; Overlords / Observers
;==================================
^o::
{
  if (PLAYER_IS_ZERG) {
    RunForBuildingsInZone("MakeOverlord")
  }
  if (PLAYER_IS_PROTOSS) {
    RunForBuildingsInZone("MakeObserver")
  }
}
return

;==================================
; assign rally points to all buildings in the zone list
;==================================
^r::
{
  RunForBuildingsInZone("SetRallyPoint")
}
return

;==================================
; Mass scouts / shuttle
;==================================
^s::
{
  if ( PLAYER_IS_PROTOSS ) {
    RunForBuildingsInZone("MakeScout")
  }
}
return

;==================================
; Mass tanks / templar
;==================================
^t::
{
  if ( PLAYER_IS_TERRAN ) {
    RunForBuildingsInZone("MakeTank")
  }
  if ( PLAYER_IS_PROTOSS ) {
    RunForBuildingsInZone("MakeHighTemplar")
  }
}
return

;==================================
; Mass ultralisks
;==================================
^u::
{
  if ( PLAYER_IS_ZERG ) {
    RunForBuildingsInZone("MakeUltralisk")
  }
}
return

;==================================
; Mass reavers / vultures
;==================================
^v::
{
  if ( PLAYER_IS_TERRAN ) {
    RunForBuildingsInZone("MakeVulture")
  }  
  if ( PLAYER_IS_PROTOSS ) {
    RunForBuildingsInZone("MakeReaver")
  }
}
return

;==================================
; Mass zerglings / zealots
;==================================
^z::
{
  if ( PLAYER_IS_PROTOSS ) {
    RunForBuildingsInZone("MakeZealot")
  }
  if ( PLAYER_IS_ZERG ) {
    RunForBuildingsInZone("MakeZergling")
  }
}
return

;==================================
;==================================
$a::
$b::
$e::
$i::
$j::
$k::
$l::
$n::
$o::
$q::
$r::
$s::
$t::
$u::
$v::
$w::
$x::
$y::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
  }
  send % SubStr(A_ThisHotKey, 0)
}
return

$1::
$2::
$3::
$4::
$5::
$6::
$7::
$8::
$9::
$0::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    CurrentGroup := SubStr(A_ThisHotKey, 0)
    NumberOfUnitsInGroup_%CurrentGroup% := CountUnits()
  }
  send % SubStr(A_ThisHotKey, 0)
}
return

~Enter::
{
  PlayerMessage := !PlayerMessage
}
return 

~Esc::
{
  PlayerMessage := False
}
return

;==================================
;==================================
$c::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    if (PLAYER_IS_PROTOSS AND AUTOBUILD_ENABLED) {
      send b
      WaitGameCycle(2)
    } 
  }
  send c
}
return

;==================================
;==================================
$d::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    if (PLAYER_IS_PROTOSS) {
      LastUnit := "d"
    }
  }
  send d
}
return

;==================================
;==================================
$f::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    if (PLAYER_IS_TERRAN) {
      LastUnit := "f"
    }
    if (PLAYER_IS_PROTOSS AND AUTOBUILD_ENABLED) {
      send b
      WaitGameCycle(2)
    }
  }
  send f
}
return

;==================================
;==================================
$g::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    if (PLAYER_IS_PROTOSS AND AUTOBUILD_ENABLED) {   ; if protoss then auto gate on the G key
      send b
      WaitGameCycle(2)
    }
    if (PLAYER_IS_TERRAN) {
      LastUnit := "g"
    }
  }
  send g
}
return

;==================================
;==================================
$h::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    if ( PLAYER_IS_ZERG ) {
      LastUnit := "h"
    }
  }
  send h
}
return

;==================================
;==================================
$m::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    if ( PLAYER_IS_ZERG OR PLAYER_IS_TERRAN ) {
      LastUnit := "m"
    }
  }
  send m
}
return

;==================================
;==================================
$p::     ; if protoss then auto pylon on the P key
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    if ( PLAYER_IS_PROTOSS AND AUTOBUILD_ENABLED) {
      send b
      WaitGameCycle(2)
    }
  }
  send p
}
return

;==================================
;==================================
$z::
{
  if ( !PlayerMessage ) {
    gosub ClearMessage
    if (PLAYER_IS_ZERG OR PLAYER_IS_PROTOSS) {
      LastUnit := "z"
    }
  }
  send z
}
return

;==================================
;==================================

#IfWinActive


000sixzeros000
  • Members
  • 43 posts
  • Last active: Apr 23 2011 08:11 AM
  • Joined: 17 Oct 2009
Wow that's quite the facelift... I'll give your code a test and see what happens...

the orginal is still working fine on my system.. I just gave it another test whirl..

If its not sending anything... maybe its the sleep function? or possibly the sendmode?

I'll get back to you...

000sixzeros000
  • Members
  • 43 posts
  • Last active: Apr 23 2011 08:11 AM
  • Joined: 17 Oct 2009
Well i havent tested it all totally, but I can tell you that the sends seem to be working on my system.

I was able to set zones and recall them, so the mouse movements are working..

cycling of the units seems to be working.

sounds like a vista issue..
perhaps a different sendmode setting ? possibly different timing settings? or if there is an alternative to sleep?