#include "Main.h" void ProgramProduceUnitExtractor::Init() { _CurState = ProgProduceUnitExtractorSelectWorkers; _AttemptsMade = 0; Name = "BuildingExtractor"; } ProgramResultType ProgramProduceUnitExtractor::ExecuteStep() { UnitEntry *Entry = g_Context->Managers.Knowledge.ExtractorUnit(); FrameHUDManager &FrameHUD = g_Context->Managers.FrameHUD; FrameUnitManager &FrameUnit = g_Context->Managers.FrameUnit; const String ActionButtonName = GetRaceTypeString(Entry->Race) + String("BuildBasicStructure"); if(_CurState == ProgProduceUnitExtractorSelectWorkers) { LogThreadEvent("Selecting Workers", LogStep); g_Context->Managers.KeyboardMouse.SendKey(KEY_0 + g_Context->Managers.ControlGroup.FindControlGroupIndex(ControlGroupWorkerMineral)); _CurState = ProgProduceUnitExtractorMoveToBuildingSite; return ProgramResultStillExecuting; } if(_CurState == ProgProduceUnitExtractorMoveToBuildingSite) { ActionButtonStateType State; if(!FrameHUD.ActionButtonPresent(ActionButtonName, State)) { LogThreadEvent("BuildBasicStructure not present", LogError); return ProgramResultFail; } if(State != ActionButtonStateNormal) { LogThreadEvent("BuildBasicStructure is in an invalid state", LogError); return ProgramResultFail; } Vec2f MinimapExtractorLocation; bool Success = g_Context->Managers.Knowledge.RandomExtractorSite(MinimapExtractorLocation); if(!Success) { LogThreadEvent("RandomExtractorSite failed", LogError); return ProgramResultFail; } const Vec2i ScreenCoord = g_Context->Constants.MinimapCoordToScreenCoord(MinimapExtractorLocation); LogThreadEvent(String("MoveToBuildingSite: ") + ScreenCoord.CommaSeparatedString(), LogStep); g_Context->Managers.KeyboardMouse.Click(ScreenCoord, MouseButtonLeft, ModifierNone); _CurState = ProgProduceUnitExtractorSelectBuildStructure; return ProgramResultStillExecuting; } if(_CurState == ProgProduceUnitExtractorSelectBuildStructure) { ActionButtonStateType State; if(!FrameHUD.ActionButtonPresent(ActionButtonName, State)) { LogThreadEvent("BuildBasicStructure not present", LogError); return ProgramResultFail; } if(State != ActionButtonStateNormal) { LogThreadEvent("BuildBasicStructure is in an invalid state", LogError); return ProgramResultFail; } g_Context->Managers.KeyboardMouse.SendKey(KEY_B); LogThreadEvent("Selecting BuildBasicStructure", LogStep); _CurState = ProgProduceUnitExtractorSelectBuilding; return ProgramResultStillExecuting; } if(_CurState == ProgProduceUnitExtractorSelectBuilding) { ActionButtonStateType State; if(!FrameHUD.ActionButtonPresent(Entry->Name, State)) { LogThreadEvent(Entry->Name + String(" not present"), LogError); return ProgramResultFail; } if(State != ActionButtonStateNormal) { LogThreadEvent(Entry->Name + String(" is in an invalid state"), LogError); return ProgramResultFail; } g_Context->Managers.KeyboardMouse.SendKey(KEY_A + (Entry->Hotkey - 'a')); LogThreadEvent(String("Selecting building: ") + String(Entry->Hotkey), LogStep); _CurState = ProgProduceUnitExtractorFindBuildingPlacement; _TimeoutTime0 = GameTime() + 1.0; } if(_CurState == ProgProduceUnitExtractorFindBuildingPlacement) { ActionButtonStateType State; if(FrameHUD.ActionButtonPresent(ActionButtonName, State)) { if(_AttemptsMade == 0) { LogThreadEvent("BuildBasicStructure present but no attempts made", LogError); return ProgramResultFail; } _TimeoutTime1 = GameTime() + 1.5; _CurState = ProgProduceUnitExtractorWaitForSuccess; return ProgramResultStillExecuting; } if(!FrameHUD.ActionButtonPresent("Cancel", State)) { LogThreadEvent("Cancel not present", LogError); return ProgramResultFail; } if(GameTime() > _TimeoutTime0) { LogThreadEvent("Timed out searching for building location", LogError); return ProgramResultFail; } Vector AllGeysers; for(UINT UnitIndex = 0; UnitIndex < FrameUnit.UnitsThisFrame().Length(); UnitIndex++) { const FrameUnitInfo &CurUnit = *FrameUnit.UnitsThisFrame()[UnitIndex]; if(CurUnit.Owner == PlayerInvalid && CurUnit.Entry->Name == "VespeneGeyser" && CurUnit.Clickable()) { AllGeysers.PushEnd(&CurUnit); } } if(AllGeysers.Length() == 0) { LogThreadEvent("No clickable geysers", LogError); return ProgramResultFail; } Vec2i ScreenCoord = AllGeysers.RandomElement()->ScreenBound.Center().RoundToVec2i(); LogThreadEvent(String("GeyserPoint: ") + ScreenCoord.CommaSeparatedString(), LogStep); g_Context->Managers.KeyboardMouse.Click(ScreenCoord, MouseButtonLeft, ModifierNone); _AttemptsMade++; return ProgramResultStillExecuting; } if(_CurState == ProgProduceUnitExtractorWaitForSuccess) { if(GameTime() > _TimeoutTime1) { LogThreadEvent("Timed out waiting for building success", LogError); return ProgramResultFail; } ActionButtonStateType State; if(FrameHUD.ActionButtonPresent(ActionButtonName, State)) { if(State == ActionButtonStateSelected) { LogThreadEvent("BuildBasicStructure selected, success", LogDone); g_Context->ReportAction(Entry->Name, RGBColor::Green); g_Context->Managers.Knowledge.RecordUnitInProduction(Entry, GameTime()); return ProgramResultSuccess; } else { LogThreadEvent("BuildBasicStructure is in an invalid state", LogStep); return ProgramResultStillExecuting; } } } HANDLE_CRITICAL_FAILURE; }