Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- quickSelect(aDeselect)
- {
- global Sc2SelectArmy_Key, aAGHotkeys, Escape
- static getUnitPercentHPReference := Func("getUnitPercentHP"), getUnitPercentShieldReference := Func("getUnitPercentShield")
- if !getArmyUnitCount()
- return
- while (GetKeyState("Lbutton", "P") || GetKeyState("Rbutton", "P"))
- {
- sleep 1
- MouseDown := True
- }
- critical, 1000
- setLowLevelInputHooks(True)
- dsleep(30)
- input.pReleaseKeys(True)
- if MouseDown
- dSleep(15)
- aLookup := []
- for i, clickUnitType in aDeselect["Units"]
- aLookup[clickUnitType] := True
- ; This checks if one of the click unit types exist on the map
- ; Otherwise user presses hotkey and is left with all the army unit selection
- ; since when selecting unit types were are actually just removing all other types - selection will be left blank, which
- ; in most situations is probably worse
- ; This is a more complicated now by allowing on army, on screen, and control groups
- ; theres no protection fro control groups
- if aDeselect.SelectUnitTypes ;
- {
- unitTypesDoesntExist := True
- if aDeselect.BaseSelection = "Current Selection"
- {
- numGetUnitSelectionObject(aSelection)
- for i, unit in aSelection
- {
- if aLookup.hasKey(unit.type)
- {
- unitTypesDoesntExist := False
- break
- }
- }
- }
- else loop, % DumpUnitMemory(MemDump)
- {
- if !(numgetUnitTargetFilter(MemDump, unit := A_Index - 1) & DeadFilterFlag) && numgetUnitOwner(MemDump, Unit) = aLocalPlayer["Slot"]
- && aLookup.hasKey(numgetUnitModelType(numgetUnitModelPointer(MemDump, Unit)))
- {
- unitTypesDoesntExist := False
- break
- }
- }
- }
- if (unitTypesDoesntExist || (aDeselect.BaseSelection = "Army" && !getArmyUnitCount()))
- {
- input.RevertKeyState()
- setLowLevelInputHooks(False)
- critical, off
- sleep, -1
- Thread, Priority, -2147483648
- sleep, 20
- return
- }
- if isCastingReticleActive() ; so can deselect units if attacking/drop/rally reticle was present
- input.pSend(Escape) ; in ideal conditions a dsleep() >= 15 is performed after select army key is pressed this is not required - 12isnt enough
- ; as SC will have enough time to get rid of the selection reticle itself
- if(aDeselect.Filter && aDeselect.OnScreen)
- {
- aSelectUnits := []
- selectionCount := getSelectionCount()
- ReadRawMemory(B_SelectionStructure, GameIdentifier, MemDump, selectionCount * S_scStructure + O_scUnitIndex)
- loop, % selectionCount
- {
- unit := numget(MemDump,(A_Index-1) * S_scStructure + O_scUnitIndex , "Int") >> 18
- aSelectUnits[unit] := True
- }
- input.pSend("{click D " 0 " " 0 "}{Click U " A_ScreenWidth " " A_ScreenHeight "}") ; A_ScreenHeight-240 "}")
- dSleep(80)
- }
- else if aDeselect.BaseSelection != "Current Selection"
- {
- if aDeselect.BaseSelection = "Units On Screen"
- {
- ; If reticle was present, no delay is needed between sending escape and box dragging.
- ; Tested by lowering CPU speed to 1.6G Hz and running linx with this function
- input.pSend("{click D " 0 " " 0 "}{Click U " A_ScreenWidth " " A_ScreenHeight "}") ; A_ScreenHeight-240 "}")
- dSleep(80)
- }
- else if instr(aDeselect.BaseSelection, "Control Group")
- {
- input.pSend(aAGHotkeys.Invoke[Substr(aDeselect.BaseSelection, 0)]) ; substr() extract last character which is the control group number 1-9
- ; Need to add a decent method to reduce the sleep time here
- dSleep(80)
- }
- else ;if aDeselect.BaseSelection = "Army" ; Use as blank else
- {
- if (getArmyUnitCount() != getSelectionCount())
- {
- input.pSend(Sc2SelectArmy_Key)
- timerQuickID := stopwatch()
- ; waits for selection count to match army count
- ; times out after 50 ms - small static sleep afterwards
- ; A_Index check is just in case stopwatch fails (it should work on every computer) - get stuck in infinite loop with input blocked
- while (getSelectionCount() != getArmyUnitCount() && stopwatch(timerQuickID, False) < 70 && A_Index < 80)
- dsleep(1)
- stopwatch(timerQuickID)
- dsleep(20)
- }
- else
- {
- input.pSend(Sc2SelectArmy_Key)
- dSleep(40)
- }
- }
- }
- ; if on control-group/current selection remove any structures.
- ; Note if you box drag some units and structures at the same time - only units are selected
- ; however if you *Shift* box drag again (and don't select any currently unselected units) the structures will be selected.
- ; And overlords as zerg transports
- ; and fix GUI warning when no unit types selected
- numGetSelectionSorted(aSelected)
- clickPortraits := []
- if (aDeselect.DeselectXelnaga || aDeselect.DeselectPatrolling || aDeselect.DeselectHoldPosition || aDeselect.DeselectFollowing
- || aDeselect.DeselectIdle || aDeselect.DeselectLoadedTransport || aDeselect.DeselectEmptyTransport|| aDeselect.DeselectQueuedDrops
- || aDeselect.DeselectAttacking || aDeselect.DeselectLowHP || (aDeselect.DeselectHallucinations && aLocalPlayer["Race"] = "Protoss"))
- checkStates := True, healthFunc := aLocalPlayer["Race"] = "Protoss" ? getUnitPercentShieldReference : getUnitPercentHPReference ; faster than checking targ filter for has shield on each unit
- , checkTransportAttributes := (aDeselect.DeselectLoadedTransport || aDeselect.DeselectEmptyTransport || aDeselect.DeselectQueuedDrops)
- , checkHallucinations := (aDeselect.DeselectHallucinations && aLocalPlayer["Race"] = "Protoss")
- removeByAttribute := (aDeselect.AttributeMode != "Keep")
- removeStructures := (instr(aDeselect.BaseSelection, "Control") || aDeselect.BaseSelection = "Current Selection" )
- ; Could also add gameType != 1v1
- removeAllied := (removeStructures || aDeselect.BaseSelection = "Units On Screen")
- ; this is disabled until i fix the sort with units in same tab eg tanks/stanks + hellions/hellbats
- ; And also need to consider the consequence of hallucinations and the issues with tabSize/position in numgetSelectionSorted()
- if 0 && (aDeselect.Units.MaxIndex() = 1 && !checkStates)
- {
- clickUnitType := aDeselect["Units", 1]
- if aSelected.TabPositions.HasKey(clickUnitType)
- {
- for i, unit in aSelected.units
- {
- if (unit.unitId = clickUnitType)
- {
- clickPortraits.insert(unit.unitPortrait)
- break
- }
- }
- clickUnitPortraits(clickPortraits, "^")
- }
- }
- else
- {
- for i, unit in aSelected.units
- {
- ;if (unit.unitId = prevID)
- ; continue
- ;if (aDeselect.SelectUnitTypes && !aLookup.haskey(unit.unitId))
- ;|| (aDeselect.DeselectUnitTypes && aLookup.haskey(unit.unitId))
- ;{
- ; prevID := unit.unitId ; this is disabled until i fix the sort with units in same tab eg tanks/stanks + hellions/hellbats ; And also need to consider the consequence of hallucinations and the issues with tabSize/position in numgetSelectionSorted()
- ; clickPortraits.insert({ "portrait": unit.unitPortrait, "modifiers": "^+"})
- ; clickPortraits.insert({ "portrait": unit.unitPortrait, "modifiers": "+"})
- ;}
- if (aDeselect.SelectUnitTypes && !aLookup.haskey(unit.unitId))
- || (aDeselect.DeselectUnitTypes && aLookup.haskey(unit.unitId))
- || (removeStructures && unit.TargetFilter & aUnitTargetFilter.Structure)
- || (removeAllied && getUnitOwner(unit.unitIndex) != aLocalPlayer["Slot"])
- clickPortraits.insert( {"portrait": unit.unitPortrait, "modifiers": "+"})
- else if checkStates
- {
- commandString := getUnitQueuedCommandString(unit.unitIndex)
- if (aDeselect.DeselectXelnaga && isLocalUnitHoldingXelnaga(unit.unitIndex))
- || (aDeselect.DeselectPatrolling && InStr(commandString, "Patrol"))
- || (aDeselect.DeselectHoldPosition && InStr(commandString, "Hold"))
- || (aDeselect.DeselectAttacking && (InStr(commandString, "Attack") || InStr(commandString, "FNA")))
- || (aDeselect.DeselectFollowing && InStr(commandString, "Follow"))
- || (aDeselect.DeselectIdle && commandString = "")
- || (aDeselect.DeselectLowHP && healthFunc.(unit.unitIndex) < aDeselect.HPValue / 100) ; divide by 100 as it's not saved as a decimal ; Since aSelected now contains the units targFilter, could just check if has shields to determine which func to call
- || (checkHallucinations && unit.TargetFilter & aUnitTargetFilter.Hallucination)
- || ( checkTransportAttributes
- && (unit.unitId = aUnitId.Medivac || unit.unitId = aUnitID.WarpPrism || unit.unitId = aUnitID.WarpPrismPhasing) ; !removeByAttribute - if keeping
- && ( (aDeselect.DeselectLoadedTransport && getCargoCount(unit.unitIndex))
- || (aDeselect.DeselectEmptyTransport && !getCargoCount(unit.unitIndex))
- || (aDeselect.DeselectQueuedDrops && isTransportDropQueued(unit.unitIndex))))
- {
- if removeByAttribute
- clickPortraits.insert({ "portrait": unit.unitPortrait, "modifiers": "+"})
- ;else continue ; We wish to keep it. (the else if!removeByAttribute means we don't have to continue here) Due to function changes the attribute is labelled deselect even though we are keeping them
- }
- else if !removeByAttribute ; keeping units which have the above attributes - so remove any which do not have at least one
- clickPortraits.insert({ "portrait": unit.unitPortrait, "modifiers": "+"})
- }
- ; selectedCount += aSelected.TabSizes[unit.unitId]
- }
- ; reversing the array here (rather than via numgetselection function) allows the clicks to occur on the
- ; lowest portraits i.e. on the left side of a selection group
- if clickPortraits.MaxIndex()
- reverseArray(clickPortraits), clickUnitPortraitsWithModifiers(clickPortraits)
- clickSelectionPage(1) ; unconditionally click page 1
- }
- /*
- ; doing everything in one go now (not removed ctrl removing units then patrolling units)
- if (clickPortraits.MaxIndex() && (aDeselect.DeselectXelnaga || aDeselect.DeselectPatrolling || aDeselect.DeselectHoldPosition || aDeselect.DeselectFollowing
- || aDeselect.DeselectLoadedTransport|| aDeselect.DeselectQueuedDrops))
- {
- timerQuickID := stopwatch()
- while (getSelectionCount() != selectedCount && stopwatch(timerQuickID, False) < 70 && A_Index < 80)
- dsleep(1)
- stopwatch(timerQuickID) ; remove the timer
- dsleep(12)
- aUnitPortraitLocations := []
- aUnitPortraitLocations := findPortraitsToRemoveFromArmy("", aDeselect.DeselectXelnaga, aDeselect.DeselectPatrolling
- , aDeselect.DeselectHoldPosition, aDeselect.DeselectFollowing, aDeselect.DeselectLoadedTransport
- , aDeselect.DeselectQueuedDrops, "")
- clickUnitPortraits(aUnitPortraitLocations)
- }
- */
- if aDeselect.CreateControlGroup
- input.pSend(aAGHotkeys.Set[aDeselect.StoreSelection])
- else if aDeselect.AddToControlGroup
- input.pSend(aAGHotkeys.Add[aDeselect.StoreSelection])
- dsleep(15)
- input.RevertKeyState()
- setLowLevelInputHooks(False)
- critical, off
- sleep, -1
- Thread, Priority, -2147483648
- sleep, 20
- return
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement