#include "Main.h"
void ProgramChronoBoost::Init()
{
_CurState = ProgramChronoBoostSelectSupportBuildings;
_ChosenBuilding = NULL;
Name = String("ChronoBoost");
}
bool IsBoostableBuilding(const String &S)
{
return ( S == "Nexus" ||
S == "RoboticsFacility" ||
S == "RoboticsBay" ||
S == "Forge" ||
S == "CyberneticsCore" ||
S == "Stargate" ||
S == "DarkShrine" ||
S == "FleetBeacon" ||
S == "TwilightCouncil" ||
S == "TemplarArchives");
}
ProgramResultType ProgramChronoBoost::ExecuteStep()
{
FrameHUDManager &FrameHUD = g_Context->Managers.FrameHUD;
FrameUnitManager &FrameUnit = g_Context->Managers.FrameUnit;
if(_CurState == ProgramChronoBoostSelectSupportBuildings)
{
LogThreadEvent("Selecting Support Buildings", LogStep);
g_Context->Managers.KeyboardMouse.SendKey(KEY_0 + g_Context->Managers.ControlGroup.FindControlGroupIndex(ControlGroupBuildingSupport));
_CurState = ProgramChronoBoostSelectSupportBuilding;
return ProgramResultStillExecuting;
}
if(_CurState == ProgramChronoBoostSelectSupportBuilding)
{
if(FrameHUD.SoloPortrait() != NULL)
{
if(FrameHUD.SoloPortrait()->ID() == "Nexus")
{
_ChosenBuilding = FrameHUD.SoloPortrait()->Unit();
_CurState = ProgramChronoBoostCenter;
return ProgramResultStillExecuting;
}
else
{
LogThreadEvent("Single non-nexus unit selected", LogError);
return ProgramResultFail;
}
}
Vector<UINT> ValidIndices;
for(UINT Index = 0; Index < BubblePortraitCount; Index++)
{
Texture *CurTexture = FrameHUD.BubblePortraits(Index).Tex;
if(CurTexture != NULL && IsBoostableBuilding(CurTexture->ID()))
{
ValidIndices.PushEnd(Index);
}
}
if(ValidIndices.Length() == 0)
{
LogThreadEvent("No boostable buildings found", LogError);
return ProgramResultFail;
}
UINT SelectedIndex = ValidIndices.RandomElement();
Vec2i ScreenCoord = FrameHUD.ScreenCoordFromBubblePortraitIndex(SelectedIndex);
_ChosenBuilding = FrameHUD.BubblePortraits(SelectedIndex).Tex->Unit();
if(_ChosenBuilding != NULL)
{
LogThreadEvent(String("Selecting ") + _ChosenBuilding->Name + String(": ") + ScreenCoord.CommaSeparatedString(), LogStep);
g_Context->Managers.KeyboardMouse.Click(ScreenCoord, MouseButtonLeft, ModifierNone);
}
_CurState = ProgramChronoBoostCenter;
return ProgramResultStillExecuting;
}
if(_CurState == ProgramChronoBoostCenter)
{
if(FrameHUD.SoloPortrait() == NULL || _ChosenBuilding == NULL || FrameHUD.SoloPortrait()->ID() != _ChosenBuilding->Name)
{
LogThreadEvent("Boostable building selection failed", LogError);
return ProgramResultFail;
}
if(!FrameHUD.BuildQueuePresent())
{
LogThreadEvent("Selected building has no build queue", LogError, RGBColor::Orange);
return ProgramResultFail;
}
g_Context->Managers.KeyboardMouse.SendCtrlKey(KEY_F);
LogThreadEvent("Centering on boostable building", LogStep);
_CurState = ProgramChronoBoostSelectNexuses;
return ProgramResultStillExecuting;
}
if(_CurState == ProgramChronoBoostSelectNexuses)
{
LogThreadEvent("Selecting Nexuses", LogStep);
g_Context->Managers.KeyboardMouse.SendKey(KEY_0 + g_Context->Managers.ControlGroup.FindControlGroupIndex(ControlGroupBuildingMain));
_CurState = ProgramChronoBoostCastChronoBoost;
return ProgramResultStillExecuting;
}
if(_CurState == ProgramChronoBoostCastChronoBoost)
{
ActionButtonStateType State;
if(!FrameHUD.ActionButtonPresent("ChronoBoost", State))
{
LogThreadEvent("Chrono Boost button not found", LogError);
return ProgramResultFail;
}
if(State != ActionButtonStateNormal)
{
LogThreadEvent("Not enough energy for Chrono Boost", LogError, RGBColor(Vec3f(0.462744f, 0.286274f, 0.901959f)));
return ProgramResultFail;
}
Vector<const FrameUnitInfo*> AllTargets;
for(UINT UnitIndex = 0; UnitIndex < FrameUnit.UnitsThisFrame().Length(); UnitIndex++)
{
const FrameUnitInfo &CurUnit = *FrameUnit.UnitsThisFrame()[UnitIndex];
if(CurUnit.Owner == PlayerSelf && CurUnit.Entry->Name == _ChosenBuilding->Name && CurUnit.Clickable())
{
AllTargets.PushEnd(&CurUnit);
}
}
if(AllTargets.Length() == 0)
{
LogThreadEvent(String("No Chrono Boost targets on-screen"), LogError);
return ProgramResultFail;
}
Vec2i ClickPos = AllTargets.RandomElement()->ScreenBound.Center().RoundToVec2i();
g_Context->ReportAction(String("Chrono Boost: ") + _ChosenBuilding->Name, RGBColor(20, 225, 225));
LogThreadEvent(String("Chrono Boost on ") + _ChosenBuilding->Name + String(" at ") + ClickPos.CommaSeparatedString(), LogDone, RGBColor(20, 225, 225));
g_Context->Managers.KeyboardMouse.SendKey(KEY_C);
g_Context->Managers.KeyboardMouse.Click(ClickPos, MouseButtonLeft, ModifierNone);
return ProgramResultSuccess;
}
HANDLE_CRITICAL_FAILURE;
}