#include "Main.h" void ProgramProduceUnitBuilding::Init(UnitEntry *Entry) { _CurState = ProgProduceUnitBuildingSelectWorkers; _Entry = Entry; _AttemptsMade = 0; Name = String("Building<") + Entry->Name + String(">"); } ProgramResultType ProgramProduceUnitBuilding::ExecuteStep() { FrameHUDManager &FrameHUD = g_Context->Managers.FrameHUD; const String ActionButtonName = GetRaceTypeString(_Entry->Race) + String("Build") + GetComplexityTypeString(_Entry->Complexity) + String("Structure"); if(_CurState == ProgProduceUnitBuildingSelectWorkers) { LogThreadEvent("Selecting Workers", LogStep); g_Context->Managers.KeyboardMouse.SendKey(KEY_0 + g_Context->Managers.ControlGroup.FindControlGroupIndex(ControlGroupWorkerMineral)); _CurState = ProgProduceUnitBuildingMoveToBuildingSite; return ProgramResultStillExecuting; } if(_CurState == ProgProduceUnitBuildingMoveToBuildingSite) { ActionButtonStateType State; if(!FrameHUD.ActionButtonPresent(ActionButtonName, State)) { LogThreadEvent("BuildStructure not present", LogError); return ProgramResultFail; } if(State != ActionButtonStateNormal) { LogThreadEvent("BuildStructure is in an invalid state", LogError); return ProgramResultFail; } const BaseInfo* TargetSite = g_Context->Managers.Knowledge.FindBuildSite(); if(TargetSite == NULL) { LogThreadEvent("TargetSite not found", LogError); return ProgramResultFail; } Vec2i ScreenCoord = g_Context->Constants.MinimapCoordToScreenCoord(TargetSite->BuildLocation); if(_Entry->Name == "Hatchery" || _Entry->Name == "SporeCrawler" || _Entry->Name == "SpineCrawler") { ScreenCoord = g_Context->Constants.MinimapCoordToScreenCoord(TargetSite->BaseLocation); } LogThreadEvent(String("MoveToBuildingSite: ") + ScreenCoord.CommaSeparatedString(), LogStep); g_Context->Managers.KeyboardMouse.Click(ScreenCoord, MouseButtonLeft, ModifierNone); _CurState = ProgProduceUnitBuildingSelectBuildStructure; return ProgramResultStillExecuting; } if(_CurState == ProgProduceUnitBuildingSelectBuildStructure) { ActionButtonStateType State; if(!FrameHUD.ActionButtonPresent(ActionButtonName, State)) { LogThreadEvent("BuildStructure not present", LogError); return ProgramResultFail; } if(State != ActionButtonStateNormal) { LogThreadEvent("BuildStructure is in an invalid state", LogError); return ProgramResultFail; } if(_Entry->Complexity == ComplexityBasic) { g_Context->Managers.KeyboardMouse.SendKey(KEY_B); } else { g_Context->Managers.KeyboardMouse.SendKey(KEY_V); } LogThreadEvent("Selecting BuildStructure", LogStep); _CurState = ProgProduceUnitBuildingSelectBuilding; return ProgramResultStillExecuting; } if(_CurState == ProgProduceUnitBuildingSelectBuilding) { 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 = ProgProduceUnitBuildingFindBuildingPlacement; _TimeoutTime0 = GameTime() + 2.5; } if(_CurState == ProgProduceUnitBuildingFindBuildingPlacement) { ActionButtonStateType State; if(FrameHUD.ActionButtonPresent(ActionButtonName, State)) { if(_AttemptsMade == 0) { LogThreadEvent("BuildStructure present but no attempts made", LogError); return ProgramResultFail; } _TimeoutTime1 = GameTime() + 1.5; _CurState = ProgProduceUnitBuildingWaitForSuccess; 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; } Vec2i ScreenCoord = g_Context->Constants.RandomClickablePoint(0.15f); LogThreadEvent(String("RandomBuildingPoint: ") + ScreenCoord.CommaSeparatedString(), LogStep); g_Context->Managers.KeyboardMouse.Click(ScreenCoord, MouseButtonLeft, ModifierNone); _AttemptsMade++; return ProgramResultStillExecuting; } if(_CurState == ProgProduceUnitBuildingWaitForSuccess) { if(GameTime() > _TimeoutTime1) { LogThreadEvent("Timed out waiting for building success", LogError); return ProgramResultFail; } ActionButtonStateType State; if(FrameHUD.ActionButtonPresent(ActionButtonName, State)) { if(State == ActionButtonStateSelected) { LogThreadEvent("BuildStructure selected, success", LogDone); g_Context->ReportAction(_Entry->Name, RGBColor::Green); g_Context->Managers.Knowledge.RecordUnitInProduction(_Entry, GameTime()); return ProgramResultSuccess; } else { LogThreadEvent("BuildStructure is in an invalid state", LogStep); return ProgramResultStillExecuting; } } } HANDLE_CRITICAL_FAILURE; }