#include "Main.h" void ProgramGasWorker::Init(UINT ExtractorIndex) { _ExtractorIndex = ExtractorIndex; _CurState = ProgGasWorkerSelectExtractorGroup; Name = "GasWorker"; } ProgramResultType ProgramGasWorker::ExecuteStep() { const ControlGroupManager &ControlGroup = g_Context->Managers.ControlGroup; KnowledgeManager &Knowledge = g_Context->Managers.Knowledge; const FrameHUDManager &FrameHUD = g_Context->Managers.FrameHUD; const FrameUnitManager &FrameUnit = g_Context->Managers.FrameUnit; if(_CurState == ProgGasWorkerSelectExtractorGroup) { Vector &Extractors = Knowledge.Extractors(); if(_ExtractorIndex >= Extractors.Length()) { LogThreadEvent("ExtractorIndex >= Extractors.Length()", LogError); return ProgramResultFail; } Extractors[_ExtractorIndex].NextCheckTime = GameTime() + 20.0; LogThreadEvent("Selecting Extractor Group", LogStep); //UINT ControlGroupIndex = ControlGroup.GasControlGroupIndexFromGasIndex(_ExtractorIndex); g_Context->Managers.KeyboardMouse.SendKey(KEY_0 + ControlGroup.FindControlGroupIndex(ControlGroupBuildingSupport)); _CurState = ProgGasWorkerSelectExtractor; return ProgramResultStillExecuting; } if(_CurState == ProgGasWorkerSelectExtractor) { if(FrameHUD.SoloPortrait() != NULL) { LogThreadEvent("Single unit selected", LogError); return ProgramResultFail; } Vector ValidIndices; for(UINT Index = 0; Index < BubblePortraitCount; Index++) { Texture *CurTexture = FrameHUD.BubblePortraits(Index).Tex; if(CurTexture != NULL && CurTexture->ID() == Knowledge.ExtractorUnit()->Name) { ValidIndices.PushEnd(Index); } } if(ValidIndices.Length() <= _ExtractorIndex) { LogThreadEvent("Not enough extractors found", LogError); return ProgramResultFail; } Vec2i ScreenCoord = FrameHUD.ScreenCoordFromBubblePortraitIndex(ValidIndices[_ExtractorIndex]); LogThreadEvent(String("Left Click: ") + ScreenCoord.CommaSeparatedString(), LogStep); g_Context->Managers.KeyboardMouse.Click(ScreenCoord, MouseButtonLeft, ModifierNone); _CurState = ProgGasWorkerCenterExtractor; return ProgramResultStillExecuting; } if(_CurState == ProgGasWorkerCenterExtractor) { if(FrameHUD.SoloPortrait() == NULL || FrameHUD.SoloPortrait()->ID() != Knowledge.ExtractorUnit()->Name) { LogThreadEvent("Extractor not selected", LogError); return ProgramResultFail; } g_Context->Managers.KeyboardMouse.SendCtrlKey(KEY_F); LogThreadEvent("Centering on extractor", LogStep); _CurState = ProgGasWorkerSelectGasDrones; return ProgramResultStillExecuting; } if(_CurState == ProgGasWorkerSelectGasDrones) { LogThreadEvent("Selecting Gas Group", LogStep); UINT GasControlGroupIndex = ControlGroup.GasControlGroupIndexFromGasIndex(_ExtractorIndex); g_Context->Managers.KeyboardMouse.SendKey(KEY_0 + ControlGroup.FindControlGroupIndex(ControlGroupBuildingMain)); g_Context->Managers.KeyboardMouse.SendKey(KEY_0 + GasControlGroupIndex); _CurState = ProgGasWorkerOrderGasDrones; return ProgramResultStillExecuting; } if(_CurState == ProgGasWorkerOrderGasDrones) { Vector AllClickableExtractors; for(UINT UnitIndex = 0; UnitIndex < FrameUnit.UnitsThisFrame().Length(); UnitIndex++) { const FrameUnitInfo &CurUnit = *FrameUnit.UnitsThisFrame()[UnitIndex]; if(CurUnit.Owner == PlayerSelf && CurUnit.Entry->SecondaryType == UnitSecondaryExtractor && CurUnit.Clickable()) { AllClickableExtractors.PushEnd(&CurUnit); } } if(AllClickableExtractors.Length() == 0) { LogThreadEvent("No clickable extractors", LogError); return ProgramResultFail; } struct ExtractorSorter { __forceinline bool operator()(const FrameUnitInfo *Left, const FrameUnitInfo *Right) { float LeftDistSq = Vec2f::DistSq(Left->ScreenBound.Center(), ScreenCenter); float RightDistSq = Vec2f::DistSq(Right->ScreenBound.Center(), ScreenCenter); return (LeftDistSq < RightDistSq); } Vec2f ScreenCenter; }; ExtractorSorter Sorter; Sorter.ScreenCenter = Vec2f(g_Context->Constants.GetRectangle2iConstant(ScreenConstantRectangle2iClickableRegion).Center()); AllClickableExtractors.Sort(Sorter); Vec2i ClickPos = AllClickableExtractors[0]->ScreenBound.Center().RoundToVec2i(); g_Context->Managers.KeyboardMouse.SendKey(KEY_G); g_Context->Managers.KeyboardMouse.Click(ClickPos, MouseButtonLeft, ModifierNone); LogThreadEvent("Ordering Gas Group", LogDone); return ProgramResultSuccess; } HANDLE_CRITICAL_FAILURE; }