#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<ExtractorInfo> &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);
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<UINT> 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<const FrameUnitInfo*> 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;
}