#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 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; /*if(ChosenUnit.Entry->PrimaryType == UnitPrimaryBuilding) { Modifier = ModifierNone; }*/ 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 && CurTexture->Unit()->PrimaryType == UnitPrimaryBuilding) { LogThreadEvent("Multiple buildings selected", LogError); return ProgramResultFail; }*/ } 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; }