#include "Main.h"
void ProgramBaseSearch::Init()
{
_CurState = ProgBaseSearchSelectRegion;
Name = String("BaseSearch");
}
double ProgramBaseSearch::ComputeUnitValue(const UnitEntry *Entry) const
{
ControlGroupManager &ControlGroup = g_Context->Managers.ControlGroup;
KnowledgeManager &Knowledge = g_Context->Managers.Knowledge;
GameLocalUnitInfo& GameLocalUnit = Knowledge.GetGameLocalUnitInfo(Entry);
float ScaleFactor = 5.0;
if(Entry->PrimaryType == UnitPrimaryBuilding)
{
UINT TotalCount = ControlGroup.FindControlGroup(ControlGroupBuildingSupport).CountPrerequisiteUnitsMatchingName(Entry->Name);
if(GameLocalUnit.TotalBuilt <= TotalCount)
{
ScaleFactor = 1.0;
}
}
return ScaleFactor * (GameTime() - GameLocalUnit.LastSelectionTime);
}
ProgramResultType ProgramBaseSearch::ExecuteStep()
{
ControlGroupManager &ControlGroup = g_Context->Managers.ControlGroup;
KnowledgeManager &Knowledge = g_Context->Managers.Knowledge;
if(_CurState == ProgBaseSearchSelectRegion)
{
if(g_Context->Managers.Minimap.SelfPixelCoordinates().Length() == 0)
{
LogThreadEvent("SelfPixelCoordinates empty", LogError);
return ProgramResultFail;
}
const Vec2f MinimapCoord = g_Context->Managers.Minimap.SelfPixelCoordinates().RandomElement();
const Vec2i ScreenCoord = g_Context->Constants.MinimapCoordToScreenCoord(MinimapCoord);
LogThreadEvent(String("SelectRegion: ") + ScreenCoord.CommaSeparatedString(), LogStep);
g_Context->Managers.KeyboardMouse.Click(ScreenCoord, MouseButtonLeft, ModifierNone);
_CurState = ProgBaseSearchSelectUnit;
return ProgramResultStillExecuting;
}
if(_CurState == ProgBaseSearchSelectUnit)
{
const FrameUnitManager &FrameUnit = g_Context->Managers.FrameUnit;
Vector<const FrameUnitInfo*> SelectableUnits;
for(UINT UnitIndex = 0; UnitIndex < FrameUnit.UnitsThisFrame().Length(); UnitIndex++)
{
const FrameUnitInfo &CurUnit = *FrameUnit.UnitsThisFrame()[UnitIndex];
if(CurUnit.Owner == PlayerSelf && CurUnit.Clickable() && CurUnit.Entry->SecondaryType != UnitSecondaryWorker)
{
SelectableUnits.PushEnd(&CurUnit);
}
}
if(SelectableUnits.Length() == 0)
{
LogThreadEvent("No units visible", LogError);
return ProgramResultFail;
}
SelectableUnits.Randomize();
const FrameUnitInfo *BestUnit = SelectableUnits[0];
double BestUnitValue = 0.0;
for(UINT Index = 0; Index < SelectableUnits.Length(); Index++)
{
double CurUnitValue = ComputeUnitValue(SelectableUnits[Index]->Entry);
if(CurUnitValue > BestUnitValue)
{
BestUnit = SelectableUnits[Index];
BestUnitValue = CurUnitValue;
}
}
Knowledge.GetGameLocalUnitInfo(BestUnit->Entry).LastSelectionTime = GameTime();
const Vec2i ScreenCoord = BestUnit->ScreenBound.Center().RoundToVec2i();
LogThreadEvent(String("SelectUnit: ") + ScreenCoord.CommaSeparatedString() + String("; ") + BestUnit->Entry->Name, LogStep);
ModifierType Modifier = ModifierCtrl;
g_Context->Managers.KeyboardMouse.Click(ScreenCoord, MouseButtonLeft, Modifier);
_CurState = ProgBaseSearchAddToControlGroup;
return ProgramResultStillExecuting;
}
if(_CurState == ProgBaseSearchAddToControlGroup)
{
bool AddUnits = false;
const FrameHUDManager &FrameHUD = g_Context->Managers.FrameHUD;
Texture *CurTexture = NULL;
if(FrameHUD.SoloPortrait() != NULL)
{
CurTexture = FrameHUD.SoloPortrait();
}
else
{
if(FrameHUD.SingleUnitTypeSelected())
{
CurTexture = FrameHUD.BubblePortraits(0).Tex;
}
}
if(CurTexture == NULL)
{
LogThreadEvent("No unit selected", LogError);
return ProgramResultFail;
}
if(CurTexture->Unit() == NULL)
{
LogThreadEvent(String("Unit has no entry: ") + String(CurTexture->ID()), LogError);
return ProgramResultFail;
}
UnitEntry &CurEntry = *CurTexture->Unit();
RaceType MyRace = g_Context->Managers.Knowledge.MyRace();
if(CurEntry.Race != MyRace)
{
LogThreadEvent("Unit race does not match", LogError);
return ProgramResultFail;
}
int ControlGroupIndex = g_Context->Managers.ControlGroup.FindControlGroupIndex(CurEntry);
if(ControlGroupIndex == -1)
{
LogThreadEvent("Unit has no control group", LogError);
return ProgramResultFail;
}
if(CurEntry.SecondaryType == UnitSecondaryBase)
{
LogThreadEvent(String("Adding ") + CurEntry.Name + String(" to all groups"), LogDone);
for(UINT ControlGroupIndex = 0; ControlGroupIndex < ControlGroupCount; ControlGroupIndex++)
{
g_Context->Managers.KeyboardMouse.SendShiftKey(KEY_0 + ControlGroupIndex);
}
}
else
{
if(FrameHUD.CurrentUnitUnderConstruction())
{
LogThreadEvent("Unit under construction", LogDone);
}
else
{
LogThreadEvent(String("Adding ") + CurEntry.Name + String(" to group ") + String(ControlGroupIndex), LogDone);
g_Context->Managers.KeyboardMouse.SendShiftKey(KEY_0 + ControlGroupIndex);
ControlGroupInfo &CurGroup = ControlGroup.ControlGroups(ControlGroupIndex);
if(CurGroup.CountUnitsMatchingName(CurEntry.Name) == 0)
{
CurGroup.InsertUnit(&CurEntry);
}
if(CurGroup.Type == ControlGroupCombatMicro)
{
UINT ArmyGroupIndex = ControlGroup.FindControlGroupIndex(ControlGroupCombatAll);
LogThreadEvent(String("Adding ") + CurEntry.Name + String(" to group ") + String(ArmyGroupIndex), LogDone);
g_Context->Managers.KeyboardMouse.SendShiftKey(KEY_0 + ArmyGroupIndex);
}
}
}
return ProgramResultSuccess;
}
HANDLE_CRITICAL_FAILURE;
}