AceCooper

Mining 0.6.1 with Ratting 0.1.3a

Jul 16th, 2017
229
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 30.64 KB | None | 0 0
  1. //    Mining 0.6.1 with Ratting 0.1.3b
  2. //
  3. //    This script mines ore from asteroids.
  4. //    before running this script, make sure to prepare as follows:
  5. //    +enter bookmark for mining site and bookmark for station in the configuration section below.
  6. //    +in the Overview create a preset which includes asteroids and rats and enter the name of that preset in the configuration section below at 'OverviewPreset'. The bot will make sure this preset is loaded when it needs to use the overview.
  7. //    +set Overview to sort by distance with the nearest entry at the top.
  8. //    +in the Inventory select the 'List' view.
  9. //    +set the UI language to english.
  10. //    +use a ship with an ore hold.
  11. //    +put some light drones into your ships' drone bay. The bot will make use of them to attack rats when HP are too low (configurable) or it gets jammed.
  12. //    +enable the info panel 'System info'. The bot will use the button in there to access bookmarks and asteroid belts.
  13. //    +arrange windows to not occlude modules or info panels.
  14. //    +in the ship UI, disable "Display Passive Modules" and disable "Display Empty Slots" and enable "Display Module Tooltips". The bot uses the module tooltips to automatically identify the properties of the modules.
  15. //
  16. //    for optional features (such as warp to safe on hostile in local) see the configuration section below.
  17.  
  18. using BotSharp.ToScript.Extension;
  19. using Parse = Sanderling.Parse;
  20.  
  21. //    begin of configuration section ->
  22.  
  23. //    The bot uses the bookmarks from the menu which is opened from the button in the 'System info' panel.
  24.  
  25. //    Bookmarks of places to mine. Add additional bookmarks separated by comma.
  26. string[] SetMiningSiteBookmark = new[] {
  27.     "1",
  28.     "2",
  29.     "3",
  30.     "4",
  31.     "5",
  32.     };
  33.  
  34. //    Bookmark of location where ore should be unloaded.
  35. string[] UnloadBookmark = new[] {
  36.     "HOME",
  37.     "HOME1",
  38.     "HOME2",
  39.     "HOME3",
  40.     };
  41.  
  42. // Emergency Warpout station name (not bookmark!)
  43. string RetreatStation = "JK-Q77 - Shiva's Grind and Go";
  44.  
  45. //    Name of the container to unload to as shown in inventory.
  46. string UnloadDestContainerName = "Ice";
  47.  
  48. // Maximum number of targets you can target at once
  49. int MaxActiveTargets = 5;
  50.  
  51. //    when this is set to true, the bot will try to unload when undocked.
  52. bool UnloadInSpace = false;
  53.  
  54. //    Bookmark of place to retreat to to prevent ship loss.
  55. string[] RetreatBookmark = UnloadBookmark;
  56.  
  57. //    The bot loads this preset to the active tab.
  58. string OverviewPreset = null;
  59.  
  60. var ActivateHardener = true; // activate shield hardener.
  61. var ActivateBooster = true; // activate shield booster.
  62.  
  63. //    bot will start fighting (and stop mining) when hitpoints are lower.
  64. var DefenseEnterHitpointThresholdPercent = 50;
  65. var DefenseExitHitpointThresholdPercent = 99;
  66.  
  67. var EmergencyWarpOutHitpointPercent = 30;
  68.  
  69. var FightAllRats = false;    //    when this is set to true, the bot will attack rats independent of shield hp.
  70.  
  71. var EnterOffloadOreHoldFillPercent = 93;    //    percentage of ore hold fill level at which to enter the offload process.
  72.  
  73. var RetreatOnNeutralOrHostileInLocal = true;   // warp to RetreatBookmark when a neutral or hostile is visible in local.
  74.  
  75. //    <- end of configuration section
  76.  
  77.  
  78. Func<object> BotStopActivity = () => null;
  79.  
  80. Func<object> NextActivity = MainStep;
  81.  
  82. for(;;)
  83. {
  84.     MemoryUpdate();
  85.  
  86.     Host.Log(
  87.         "ore hold fill: " + OreHoldFillPercent + "%" +
  88.         ", mining range: " + MiningRange +
  89.         ", mining modules (inactive): " + SetModuleMiner?.Length + "(" + SetModuleMinerInactive?.Length + ")" +
  90.         ", shield.hp: " + ShieldHpPercent + "%" +
  91.         ", retreat: " + RetreatReason +
  92.         ", JLA: " + JammedLastAge +
  93.         ", overview.rats: " + ListRatOverviewEntry?.Length +
  94.         ", overview.roids: " + ListAsteroidOverviewEntry?.Length +
  95.         ", offload count: " + OffloadCount +
  96.         ", nextAct: " + NextActivity?.Method?.Name);
  97.  
  98.     CloseModalUIElement();
  99.  
  100.     if(0 < RetreatReason?.Length && !(Measurement?.IsDocked ?? false))
  101.     {
  102.          EmergencyWarpout();
  103.         InitiateDockToOrWarpToBookmark(RandomElement(RetreatBookmark));
  104.         continue;
  105.     }
  106.  
  107.     NextActivity = NextActivity?.Invoke() as Func<object>;
  108.  
  109.     if(BotStopActivity == NextActivity)
  110.         break;
  111.    
  112.     if(null == NextActivity)
  113.         NextActivity = MainStep;
  114.    
  115.     Host.Delay(1111);
  116. }
  117.  
  118. //    seconds since ship was jammed.
  119. long? JammedLastAge => Jammed ? 0 : (Host.GetTimeContinuousMilli() - JammedLastTime) / 1000;
  120.  
  121. int?    ShieldHpPercent => ShipUi?.HitpointsAndEnergy?.Shield / 10;
  122. int?    ArmorHpPercent => ShipUi?.HitpointsAndEnergy?.Armor / 10;
  123. int?    StructHpPercent => ShipUi?.HitpointsAndEnergy?.Struct / 10;
  124.  
  125. bool    DefenseExit =>
  126.     (Measurement?.IsDocked ?? false) ||
  127.     (DefenseExitHitpointThresholdPercent < ShieldHpPercent && !(JammedLastAge < 40)) ||
  128.     (OreHoldFilledForOffload);
  129.  
  130. bool    DefenseEnter =>
  131.     !DefenseExit    ||
  132.     !(DefenseEnterHitpointThresholdPercent < ShieldHpPercent) || JammedLastAge < 10;
  133.    
  134. bool    ShipRepair => ArmorHpPercent < 99 || StructHpPercent < 99;
  135.  
  136. bool    OreHoldFilledForOffload => Math.Max(0, Math.Min(100, EnterOffloadOreHoldFillPercent)) <= OreHoldFillPercent;
  137.  
  138. Int64?    JammedLastTime = null;
  139. string RetreatReasonTemporary = null;
  140. string RetreatReasonPermanent = null;
  141. string RetreatReason => RetreatReasonPermanent ?? RetreatReasonTemporary;
  142. int? LastCheckOreHoldFillPercent = null;
  143.  
  144. int OffloadCount = 0;
  145.  
  146. Func<object>    MainStep()
  147. {
  148.     if(Measurement?.IsDocked ?? false)
  149.     {
  150.         InInventoryUnloadItems();
  151.  
  152.         if (0 < RetreatReasonPermanent?.Length)
  153.             return BotStopActivity;
  154.  
  155.         if (0 < RetreatReason?.Length)
  156.             return MainStep;
  157.  
  158.         Undock();
  159.     }
  160.    
  161.     if(0 < ListRatsOverviewEntry?.Length) {
  162.         Host.Log("ListRatsOverviewEntry?.Length = "+ListRatsOverviewEntry?.Length);
  163.         Ratting();
  164.         }
  165.        
  166.     if((0 == ListRatsOverviewEntry?.Length)&&(0 < DronesInSpaceCount)) {
  167.         Sanderling.KeyboardPressCombined(new[] {VirtualKeyCode.SHIFT, VirtualKeyCode.VK_R});
  168.     }    
  169.    
  170.     /*
  171.     if(DefenseEnter)
  172.     {
  173.         Host.Log("enter defense");
  174.         DroneEnsureInBay();
  175.         return DefenseStep;
  176.     }
  177.    
  178.     if(ShipRepair)
  179.     {
  180.         Host.Log("waiting for repairs");
  181.         Host.Delay(4444);
  182.         return MainStep;
  183.     }
  184.     */
  185.  
  186.     EnsureOverviewTypeSelectionLoaded();
  187.  
  188.     EnsureWindowInventoryOpenOreHold();
  189.  
  190.     if(ReadyForManeuver)
  191.     {
  192.         //DroneEnsureInBay();
  193.  
  194.         if(OreHoldFilledForOffload)
  195.         {
  196.  
  197.     Sanderling.WindowToForeground();
  198.  
  199.             if (UnloadInSpace)
  200.             {
  201.                 Host.Delay(4444);
  202.                 InInventoryUnloadItems();
  203.             } else if (ReadyForManeuver)
  204.             {
  205.                 EmergencyWarpout();
  206.                 InitiateDockToOrWarpToBookmark(RandomElement(UnloadBookmark));
  207.             }
  208.             return MainStep;
  209.         }
  210.        
  211.         if(!(0 < ListAsteroidOverviewEntry?.Length))
  212.             InitiateWarpToRandomMiningSite();
  213.     }
  214.  
  215.     ModuleMeasureAllTooltip();
  216.  
  217.     if(ActivateHardener)
  218.         ActivateHardenerExecute();
  219.        
  220.     if(ActivateBooster)
  221.         ActivateBoosterExecute();
  222.  
  223.     return InBeltMineStep;
  224. }
  225.  
  226. int RandomInt() => new Random((int)Host.GetTimeContinuousMilli()).Next();
  227.  
  228. T RandomElement<T>(IEnumerable<T> sequence)
  229. {
  230.     var array = (sequence as T[]) ?? sequence?.ToArray();
  231.  
  232.     if (!(0 < array?.Length))
  233.         return default(T);
  234.  
  235.     return array[RandomInt() % array.Length];
  236. }
  237.  
  238. void CloseModalUIElement()
  239. {
  240.     var    ButtonClose =
  241.         ModalUIElement?.ButtonText?.FirstOrDefault(button => (button?.Text).RegexMatchSuccessIgnoreCase("close|no|ok"));
  242.        
  243.     Sanderling.MouseClickLeft(ButtonClose);
  244. }
  245.  
  246. void DroneLaunch()
  247. {
  248.     Host.Log("launch drones.");
  249.     Sanderling.MouseClickRight(DronesInBayListEntry);
  250.     Sanderling.MouseClickLeft(Menu?.FirstOrDefault()?.EntryFirstMatchingRegexPattern("launch", RegexOptions.IgnoreCase));
  251. }
  252.  
  253. void DroneEnsureInBay()
  254. {
  255.     if(0 == DronesInSpaceCount)
  256.         return;
  257.  
  258.     DroneReturnToBay();
  259.    
  260.     Host.Delay(5555);
  261. }
  262.  
  263. void DroneReturnToBay()
  264. {
  265.     Host.Log("return drones to bay.");
  266.     Sanderling.MouseClickRight(DronesInSpaceListEntry);
  267.     Sanderling.MouseClickLeft(Menu?.FirstOrDefault()?.EntryFirstMatchingRegexPattern("return.*bay", RegexOptions.IgnoreCase));
  268. }
  269.  
  270. /*
  271. Func<object>    DefenseStep()
  272. {
  273.     if(DefenseExit)
  274.     {
  275.         Host.Log("exit defense.");
  276.         return null;
  277.     }
  278.  
  279.     if (!(0 < DronesInSpaceCount))
  280.       {
  281.         Sanderling.KeyboardPress(VirtualKeyCode.VK_L);
  282.         DroneLaunch();
  283.       }
  284.     EnsureOverviewTypeSelectionLoaded();
  285.  
  286.     var SetRatName =
  287.         ListRatOverviewEntry?.Select(entry => Regex.Split(entry?.Name ?? "", @"\s+")?.FirstOrDefault())
  288.         ?.Distinct()
  289.         ?.ToArray();
  290.    
  291.     var SetRatTarget = Measurement?.Target?.Where(target =>
  292.         SetRatName?.Any(ratName => target?.TextRow?.Any(row => row.RegexMatchSuccessIgnoreCase(ratName)) ?? false) ?? false);
  293.    
  294.     var RatTargetNext = SetRatTarget?.OrderBy(target => target?.DistanceMax ?? int.MaxValue)?.FirstOrDefault();
  295.    
  296.     if(null == RatTargetNext)
  297.     {
  298.         Host.Log("no rat targeted.");
  299.         ClickMenuEntryQuickTargeting(ListRatOverviewEntry?.FirstOrDefault());
  300.     }
  301.     else
  302.     {
  303.        Host.Log("rat targeted. sending drones.");
  304.        Sanderling.MouseClickLeft(RatTargetNext);
  305.        Sanderling.MouseClickRight(DronesInSpaceListEntry);
  306.        Sanderling.MouseClickLeft(Menu?.FirstOrDefault()?.EntryFirstMatchingRegexPattern("engage", RegexOptions.IgnoreCase));
  307.     }
  308.    
  309.     return DefenseStep;
  310. }
  311. */
  312.  
  313.  
  314. Func<object> InBeltMineStep()
  315. {
  316. /*
  317.     if (DefenseEnter)
  318.     {
  319.         Host.Log("enter defense.");
  320.         return DefenseStep;
  321.     }
  322. */
  323.  
  324.     EnsureWindowInventoryOpenOreHold();
  325.  
  326.     EnsureOverviewTypeSelectionLoaded();
  327.  
  328.     if(OreHoldFilledForOffload)
  329.         return null;
  330.  
  331.     var moduleMinerInactive = SetModuleMinerInactive?.FirstOrDefault();
  332.  
  333.     if (null == moduleMinerInactive)
  334.     {
  335.         Host.Delay(3333);
  336.         return InBeltMineStep;
  337.     }
  338.    
  339.     var    setTargetAsteroidInRange    =
  340.         SetTargetAsteroid?.Where(target => target?.DistanceMax <= MiningRange)?.ToArray();
  341.  
  342.     var setTargetAsteroidInRangeNotAssigned =
  343.         setTargetAsteroidInRange?.Where(target => !(0 < target?.Assigned?.Length))?.ToArray();
  344.  
  345.     Host.Log("targeted asteroids in range (without assignment): " + setTargetAsteroidInRange?.Length + " (" + setTargetAsteroidInRangeNotAssigned?.Length + ")");
  346.  
  347.     if(0 < setTargetAsteroidInRangeNotAssigned?.Length)
  348.     {
  349.         var targetAsteroidInputFocus    =
  350.             setTargetAsteroidInRangeNotAssigned?.FirstOrDefault(target => target?.IsSelected ?? false);
  351.  
  352.         if(null == targetAsteroidInputFocus)
  353.             Sanderling.MouseClickLeft(setTargetAsteroidInRangeNotAssigned?.FirstOrDefault());
  354.  
  355.     Sanderling.KeyDown(VirtualKeyCode.VK_W);
  356.     Sanderling.MouseClickLeft(targetAsteroidInputFocus);
  357.     Sanderling.KeyUp(VirtualKeyCode.VK_W);
  358.  
  359.         //ModuleToggle(moduleMinerInactive);
  360.         ActivateHarvesters();
  361.        
  362.         //Sanderling.KeyboardPress(VirtualKeyCode.VK_L);
  363.  
  364.         return InBeltMineStep;
  365.     }
  366.  
  367.     var asteroidOverviewEntryNext = ListAsteroidOverviewEntry?.FirstOrDefault();
  368.     var asteroidOverviewEntryNextNotTargeted = ListAsteroidOverviewEntry?.FirstOrDefault(entry => !((entry?.MeTargeted ?? false) || (entry?.MeTargeting ?? false)));
  369.  
  370.     Host.Log("next asteroid: (" + asteroidOverviewEntryNext?.Name + " , distance: " + asteroidOverviewEntryNext?.DistanceMax + ")" +
  371.         ", next asteroid not targeted: (" + asteroidOverviewEntryNext?.Name + " , distance: " + asteroidOverviewEntryNext?.DistanceMax + ")");
  372.  
  373.     if(null == asteroidOverviewEntryNext)
  374.     {
  375.         Host.Log("no asteroid available");
  376.         return null;
  377.     }
  378.  
  379.     if(null == asteroidOverviewEntryNextNotTargeted)
  380.     {
  381.         Host.Log("all asteroids targeted");
  382.         return null;
  383.     }
  384.  
  385.     if (!(asteroidOverviewEntryNextNotTargeted.DistanceMax < MiningRange))
  386.     {
  387.         if(!(1111 < asteroidOverviewEntryNext?.DistanceMin))
  388.         {
  389.             Host.Log("distance between asteroids too large");
  390.             return null;
  391.         }
  392.  
  393.         Host.Log("out of range, approaching");
  394.         ClickMenuEntryOnMenuRoot(asteroidOverviewEntryNext, "approach");
  395.     }
  396.     else
  397.     {
  398.         Host.Log("initiate lock asteroid");
  399.         ClickMenuEntryQuickTargeting(asteroidOverviewEntryNextNotTargeted);
  400.     }
  401.    
  402.     return InBeltMineStep;
  403. }
  404.  
  405.  
  406. Sanderling.Parse.IMemoryMeasurement    Measurement    =>
  407.     Sanderling?.MemoryMeasurementParsed?.Value;
  408.  
  409. IWindow ModalUIElement =>
  410.     Measurement?.EnumerateReferencedUIElementTransitive()?.OfType<IWindow>()?.Where(window => window?.isModal ?? false)
  411.     ?.OrderByDescending(window => window?.InTreeIndex ?? int.MinValue)
  412.     ?.FirstOrDefault();    
  413.  
  414. IEnumerable<Parse.IMenu> Menu => Measurement?.Menu;
  415.  
  416. Parse.IShipUi ShipUi => Measurement?.ShipUi;
  417.  
  418. bool Jammed => ShipUi?.EWarElement?.Any(EwarElement => (EwarElement?.EWarType).RegexMatchSuccess("electronic")) ?? false;
  419.  
  420. Sanderling.Interface.MemoryStruct.IMenuEntry MenuEntryLockTarget =>
  421.     Menu?.FirstOrDefault()?.Entry?.FirstOrDefault(entry => entry.Text.RegexMatchSuccessIgnoreCase("^lock"));
  422.  
  423. Sanderling.Parse.IWindowOverview    WindowOverview    =>
  424.     Measurement?.WindowOverview?.FirstOrDefault();
  425.  
  426. Sanderling.Parse.IWindowInventory    WindowInventory    =>
  427.     Measurement?.WindowInventory?.FirstOrDefault();
  428.  
  429. IWindowDroneView    WindowDrones    =>
  430.     Measurement?.WindowDroneView?.FirstOrDefault();
  431.  
  432. ITreeViewEntry InventoryActiveShipOreHold =>
  433.     WindowInventory?.ActiveShipEntry?.TreeEntryFromCargoSpaceType(ShipCargoSpaceTypeEnum.OreHold);
  434.  
  435. IInventoryCapacityGauge OreHoldCapacityMilli =>
  436.     (InventoryActiveShipOreHold?.IsSelected ?? false) ? WindowInventory?.SelectedRightInventoryCapacityMilli : null;
  437.  
  438. int? OreHoldFillPercent => (int?)((OreHoldCapacityMilli?.Used * 100) / OreHoldCapacityMilli?.Max);
  439.  
  440. Tab OverviewPresetTabActive =>
  441.     WindowOverview?.PresetTab
  442.     ?.OrderByDescending(tab => tab?.LabelColorOpacityMilli ?? 0)
  443.     ?.FirstOrDefault();
  444.  
  445. string OverviewTypeSelectionName =>
  446.     WindowOverview?.Caption?.RegexMatchIfSuccess(@"\(([^\)]*)\)")?.Groups?[1]?.Value;
  447.  
  448. Parse.IOverviewEntry[] ListRatOverviewEntry => WindowOverview?.ListView?.Entry?.Where(entry =>
  449.         (entry?.MainIconIsRed ?? false)    && (entry?.IsAttackingMe ?? false))
  450.         ?.OrderBy(entry => entry?.CellValueFromColumnHeader("Size").TryParseInt() ?? int.MaxValue)
  451.         ?.ToArray();
  452.  
  453. Parse.IOverviewEntry[] ListAsteroidOverviewEntry =>
  454.     WindowOverview?.ListView?.Entry
  455.     ?.Where(entry => null != OreTypeFromAsteroidName(entry?.Name))
  456.     ?.OrderBy(entry => entry.DistanceMax ?? int.MaxValue)
  457.     ?.ToArray();
  458.    
  459.  
  460. DroneViewEntryGroup DronesInBayListEntry =>
  461.     WindowDrones?.ListView?.Entry?.OfType<DroneViewEntryGroup>()?.FirstOrDefault(Entry => null != Entry?.Caption?.Text?.RegexMatchIfSuccess(@"Drones in bay", RegexOptions.IgnoreCase));
  462.  
  463. DroneViewEntryGroup DronesInSpaceListEntry =>
  464.     WindowDrones?.ListView?.Entry?.OfType<DroneViewEntryGroup>()?.FirstOrDefault(Entry => null != Entry?.Caption?.Text?.RegexMatchIfSuccess(@"Drones in Local Space", RegexOptions.IgnoreCase));
  465.  
  466. int?    DronesInSpaceCount => DronesInSpaceListEntry?.Caption?.Text?.AsDroneLabel()?.Status?.TryParseInt();
  467.  
  468. bool ReadyForManeuverNot =>
  469.     Measurement?.ShipUi?.Indication?.LabelText?.Any(indicationLabel =>
  470.         (indicationLabel?.Text).RegexMatchSuccessIgnoreCase("warp|docking")) ?? false;
  471.  
  472. bool ReadyForManeuver => !ReadyForManeuverNot && !(Measurement?.IsDocked ?? true);
  473.  
  474. Sanderling.Parse.IShipUiTarget[] SetTargetAsteroid =>
  475.     Measurement?.Target?.Where(target =>
  476.         target?.TextRow?.Any(textRow => textRow.RegexMatchSuccessIgnoreCase("asteroid")) ?? false)?.ToArray();
  477.  
  478. Sanderling.Interface.MemoryStruct.IListEntry    WindowInventoryItem    =>
  479.     WindowInventory?.SelectedRightInventory?.ListView?.Entry?.FirstOrDefault();
  480.  
  481. Sanderling.Accumulation.IShipUiModule[] SetModuleMiner =>
  482. Sanderling.MemoryMeasurementAccu?.Value?.ShipUiModule?.Where(module =>
  483. (module?.TooltipLast?.Value?.IsIceHarvester  ?? false) || (module?.TooltipLast?.Value?.IsMiner ?? false))?.ToArray();
  484.  
  485. Sanderling.Accumulation.IShipUiModule[] SetModuleMinerInactive     =>
  486.     SetModuleMiner?.Where(module => !(module?.RampActive ?? false))?.ToArray();
  487.  
  488. int?    MiningRange => SetModuleMiner?.Select(module =>
  489.     module?.TooltipLast?.Value?.RangeOptimal ?? module?.TooltipLast?.Value?.RangeMax ?? module?.TooltipLast?.Value?.RangeWithin ?? 0)?.DefaultIfEmpty(0)?.Min();;
  490.  
  491. WindowChatChannel chatLocal =>
  492.      Sanderling.MemoryMeasurementParsed?.Value?.WindowChatChannel
  493.      ?.FirstOrDefault(windowChat => windowChat?.Caption?.RegexMatchSuccessIgnoreCase("local") ?? false);
  494.  
  495. //    assuming that own character is always visible in local
  496. bool hostileOrNeutralsInLocal => 1 != chatLocal?.ParticipantView?.Entry?.Count(IsNeutralOrEnemy);
  497.  
  498. //    extract the ore type from the name as seen in overview. "Asteroid (Plagioclase)"
  499. string OreTypeFromAsteroidName(string AsteroidName)    =>
  500.     AsteroidName.ValueFromRegexMatchGroupAtIndex(@"Asteroid \(([^\)]+)", 0);
  501.  
  502. void ClickMenuEntryOnMenuRoot(IUIElement MenuRoot, string MenuEntryRegexPattern)
  503. {
  504.     Sanderling.MouseClickRight(MenuRoot);
  505.    
  506.     var Menu = Measurement?.Menu?.FirstOrDefault();
  507.    
  508.     var    MenuEntry = Menu?.EntryFirstMatchingRegexPattern(MenuEntryRegexPattern, RegexOptions.IgnoreCase);
  509.    
  510.     Sanderling.MouseClickLeft(MenuEntry);
  511. }
  512.  
  513. //  Haven Rattings v.0.1.3
  514. Parse.IOverviewEntry[] ListRatsOverviewEntry =>
  515.     WindowOverview?.ListView?.Entry
  516.     ?.Where(entry => (entry?.MainIconIsRed ?? true) )
  517.     ?.OrderBy(entry => (entry?.CellValueFromColumnHeader("Size").DistanceParseMin() ?? int.MaxValue) )
  518.     ?.ToArray();
  519.    
  520. //    Parsing all targeted rats from overview into an array
  521. Parse.IOverviewEntry[] ListTotalRatTargets =>
  522.     WindowOverview?.ListView?.Entry
  523.     ?.Where(entry => (entry?.MeTargeted ?? true)&&(entry?.MainIconIsRed ?? true) )
  524.     ?.OrderBy(entry => (entry?.CellValueFromColumnHeader("Size").DistanceParseMin() ?? int.MaxValue) )
  525.     ?.ToArray();
  526.    
  527. int TotalTargets = 0;
  528.    
  529. //    Ratting Workhorse
  530. void Ratting()
  531. {
  532.     var ratOverviewEntryNextNotTargeted = ListRatsOverviewEntry?.FirstOrDefault(entry => ( (entry?.MainIconIsRed ?? false) && !( (entry?.MeTargeted ?? false) || (entry?.MeTargeting ?? false) ) ) );
  533.     var ratOverviewEntryRatTargeted = ListRatsOverviewEntry?.LastOrDefault(entry => !((entry?.MeTargeted ?? false) && (entry?.MeActiveTarget ?? false)) );
  534.     int Smaller = Math.Min(ListRatsOverviewEntry.Length, MaxActiveTargets);
  535.  
  536.     if((0 < ListRatsOverviewEntry?.Length) && (0 == DronesInSpaceCount)) {
  537.         Sanderling.KeyboardPress(VirtualKeyCode.VK_L);
  538.         Host.Log("Launching drones");
  539.     }
  540.    
  541.     if((0 < ListTotalRatTargets?.Length)&&(TotalTargets != ListTotalRatTargets.Length)) {
  542.      var target = ListTotalRatTargets?.FirstOrDefault();
  543.         Sanderling.MouseClickLeft(target);
  544.         Host.Delay(111);
  545.         Sanderling.KeyboardPress(VirtualKeyCode.VK_F);
  546.         Host.Log("Attacking: " + target.Name + " (" + target.CellValueFromColumnHeader("Size").DistanceParseMin() + ")" );
  547.         TotalTargets = ListTotalRatTargets.Length;
  548.    }
  549.    
  550.     if((ListTotalRatTargets?.Length < ListRatsOverviewEntry?.Length) && (7 > TotalTargets)) {
  551.         var target = ratOverviewEntryNextNotTargeted;
  552.         if (null != target) {
  553.             ClickMenuEntryQuickTargeting(target);
  554.             Host.Log("Targeting: " + target.Name + " (" + target.CellValueFromColumnHeader("Size").DistanceParseMin() + ")" );
  555.             }
  556.     }
  557. }
  558.  
  559. //    Fast targeting: Ctrl+LMB
  560. void ClickMenuEntryQuickTargeting(IUIElement MenuRoot)
  561. {
  562.     Sanderling.KeyDown(VirtualKeyCode.LCONTROL);
  563.     Sanderling.MouseClickLeft(MenuRoot);
  564.     Sanderling.KeyUp(VirtualKeyCode.LCONTROL);
  565. }
  566.  
  567. void EnsureWindowInventoryOpen()
  568. {
  569.     if (null != WindowInventory)
  570.         return;
  571.  
  572.     Host.Log("open Inventory.");
  573.     Sanderling.MouseClickLeft(Measurement?.Neocom?.InventoryButton);
  574. }
  575.  
  576. void EnsureWindowInventoryOpenOreHold()
  577. {
  578.     EnsureWindowInventoryOpen();
  579.  
  580.     var inventoryActiveShip = WindowInventory?.ActiveShipEntry;
  581.  
  582.     if(InventoryActiveShipOreHold == null && !(inventoryActiveShip?.IsExpanded ?? false))
  583.         Sanderling.MouseClickLeft(inventoryActiveShip?.ExpandToggleButton);
  584.  
  585.     if(!(InventoryActiveShipOreHold?.IsSelected ?? false))
  586.         Sanderling.MouseClickLeft(InventoryActiveShipOreHold);
  587. }
  588.  
  589. //    sample label text: Intensive Reprocessing Array <color=#66FFFFFF>1,123 m</color>
  590. string InventoryContainerLabelRegexPatternFromContainerName(string containerName) =>
  591.     @"^\s*" + Regex.Escape(containerName) + @"\s*($|\<)";
  592.  
  593. void InInventoryUnloadItems() => InInventoryUnloadItemsTo(UnloadDestContainerName);
  594.  
  595. void InInventoryUnloadItemsTo(string DestinationContainerName)
  596. {
  597.     Host.Log("unload items to '" + DestinationContainerName + "'.");
  598.  
  599.     EnsureWindowInventoryOpenOreHold();
  600.  
  601.     for (;;)
  602.     {
  603.         var oreHoldListItem = WindowInventory?.SelectedRightInventory?.ListView?.Entry?.ToArray();
  604.  
  605.         var oreHoldItem = oreHoldListItem?.FirstOrDefault();
  606.  
  607.         if(null == oreHoldItem)
  608.             break;    //    0 items in OreHold
  609.  
  610.         if(1 < oreHoldListItem?.Length)
  611.             ClickMenuEntryOnMenuRoot(oreHoldItem, @"select\s*all");
  612.  
  613.         var DestinationContainerLabelRegexPattern =
  614.             InventoryContainerLabelRegexPatternFromContainerName(DestinationContainerName);
  615.  
  616.         var DestinationContainer =
  617.             WindowInventory?.LeftTreeListEntry?.SelectMany(entry => new[] { entry }.Concat(entry.EnumerateChildNodeTransitive()))
  618.             ?.FirstOrDefault(entry => entry?.Text?.RegexMatchSuccessIgnoreCase(DestinationContainerLabelRegexPattern) ?? false);
  619.  
  620.         if (null == DestinationContainer)
  621.             Host.Log("error: Inventory entry labeled '" + DestinationContainerName + "' not found");
  622.  
  623.         Sanderling.MouseDragAndDrop(oreHoldItem, DestinationContainer);
  624.     }
  625. }
  626.  
  627. bool InitiateWarpToRandomMiningSite()    =>
  628.     InitiateDockToOrWarpToBookmark(RandomElement(SetMiningSiteBookmark));
  629.  
  630. bool InitiateDockToOrWarpToBookmark(string bookmarkOrFolder)
  631. {
  632.     Host.Log("dock to or warp to bookmark or random bookmark in folder: '" + bookmarkOrFolder + "'");
  633.    
  634.     Sanderling.WindowToForeground();
  635.    
  636.     var listSurroundingsButton = Measurement?.InfoPanelCurrentSystem?.ListSurroundingsButton;
  637.    
  638.     Sanderling.MouseClickRight(listSurroundingsButton);
  639.    
  640.     var bookmarkMenuEntry = Measurement?.Menu?.FirstOrDefault()?.EntryFirstMatchingRegexPattern("^" + bookmarkOrFolder + "$", RegexOptions.IgnoreCase);
  641.  
  642.     if(null == bookmarkMenuEntry)
  643.     {
  644.         Host.Log("menu entry not found for bookmark or folder: '" + bookmarkOrFolder + "'");
  645.         return true;
  646.     }
  647.  
  648.     var currentLevelMenuEntry = bookmarkMenuEntry;
  649.  
  650.     for (var menuLevel = 1; ; ++menuLevel)
  651.     {
  652.         Sanderling.MouseClickLeft(currentLevelMenuEntry);
  653.  
  654.         var menu = Measurement?.Menu?.ElementAtOrDefault(menuLevel);
  655.         var dockMenuEntry = menu?.EntryFirstMatchingRegexPattern("dock", RegexOptions.IgnoreCase);
  656.         var warpMenuEntry = menu?.EntryFirstMatchingRegexPattern(@"warp.*within\s*0", RegexOptions.IgnoreCase);
  657.         var approachEntry = menu?.EntryFirstMatchingRegexPattern(@"approach", RegexOptions.IgnoreCase);
  658.  
  659.         var maneuverMenuEntry = dockMenuEntry ?? warpMenuEntry;
  660.  
  661.         if (null != maneuverMenuEntry)
  662.         {
  663.             Host.Log("initiating '" + maneuverMenuEntry.Text + "' on entry '" + currentLevelMenuEntry?.Text + "'");
  664.             Sanderling.MouseClickLeft(maneuverMenuEntry);
  665.             return false;
  666.         }
  667.  
  668.         if (null != approachEntry)
  669.         {
  670.             Host.Log("found menu entry '" + approachEntry.Text + "'. Assuming we are already there.");
  671.             return false;
  672.         }
  673.  
  674.         var setBookmarkOrFolderMenuEntry =
  675.             menu?.Entry;    //    assume that each entry on the current menu level is a bookmark or a bookmark folder.
  676.  
  677.         var nextLevelMenuEntry = RandomElement(setBookmarkOrFolderMenuEntry);
  678.  
  679.         if(null == nextLevelMenuEntry)
  680.         {
  681.             Host.Log("no suitable menu entry found");
  682.             return true;
  683.         }
  684.  
  685.         currentLevelMenuEntry = nextLevelMenuEntry;
  686.     }
  687. }
  688.  
  689. void Undock()
  690. {
  691.     while(Measurement?.IsDocked ?? true)
  692.     {
  693.         Sanderling.MouseClickLeft(Measurement?.WindowStation?.FirstOrDefault()?.UndockButton);
  694.         Host.Log("waiting for undocking to complete.");
  695.         Host.Delay(8000);
  696.     }
  697.  
  698.     Host.Delay(4444);
  699.     Sanderling.InvalidateMeasurement();
  700. }
  701.  
  702. void ModuleMeasureAllTooltip()
  703. {
  704.     Host.Log("measure tooltips of all modules.");
  705.  
  706.     for (;;)
  707.     {
  708.         var NextModule = Sanderling.MemoryMeasurementAccu?.Value?.ShipUiModule?.FirstOrDefault(m => null == m?.TooltipLast);
  709.  
  710.         if(null == NextModule)
  711.             break;
  712.  
  713.         Host.Log("measure module.");
  714.         //    take multiple measurements of module tooltip to reduce risk to keep bad read tooltip.
  715.         Sanderling.MouseMove(NextModule);
  716.         Sanderling.WaitForMeasurement();
  717.         Sanderling.MouseMove(NextModule);
  718.     }
  719. }
  720.  
  721. void ActivateHardenerExecute()
  722. {
  723.     var    SubsetModuleHardener =
  724.         Sanderling.MemoryMeasurementAccu?.Value?.ShipUiModule
  725.         ?.Where(module => module?.TooltipLast?.Value?.IsHardener ?? false);
  726.  
  727.     var    SubsetModuleToToggle =
  728.         SubsetModuleHardener
  729.         ?.Where(module => !(module?.RampActive ?? false));
  730.  
  731.     foreach (var Module in SubsetModuleToToggle.EmptyIfNull())
  732.         ModuleToggle(Module);
  733. }
  734.  
  735. void ActivateBoosterExecute()
  736. {
  737.     var    SubsetModuleBooster =
  738.         Sanderling.MemoryMeasurementAccu?.Value?.ShipUiModule
  739.         ?.Where(module => module?.TooltipLast?.Value?.IsShieldBooster?? false);
  740.  
  741.     var    SubsetModuleToToggle =
  742.         SubsetModuleBooster
  743.         ?.Where(module => !(module?.RampActive ?? false));
  744.  
  745.     foreach (var Module in SubsetModuleToToggle.EmptyIfNull())
  746.         ModuleToggle(Module);
  747. }
  748.  
  749. void ActivateHarvesters()
  750. {
  751.     Sanderling.KeyboardPressCombined(new[]{ VirtualKeyCode.F1, VirtualKeyCode.F2, VirtualKeyCode.F3});
  752. }
  753.  
  754. void ModuleToggle(Sanderling.Accumulation.IShipUiModule Module)
  755. {
  756.     var ToggleKey = Module?.TooltipLast?.Value?.ToggleKey;
  757.  
  758.     Host.Log("toggle module using " + (null == ToggleKey ? "mouse" : Module?.TooltipLast?.Value?.ToggleKeyTextLabel?.Text));
  759.  
  760.     if(null == ToggleKey)
  761.         Sanderling.MouseClickLeft(Module);
  762.     else
  763.         Sanderling.KeyboardPressCombined(ToggleKey);
  764. }
  765.  
  766. void EnsureOverviewTypeSelectionLoaded()
  767. {
  768.     if(null == OverviewPresetTabActive || null == WindowOverview || null == OverviewPreset)
  769.         return;
  770.  
  771.     if(string.Equals(OverviewTypeSelectionName, OverviewPreset, StringComparison.OrdinalIgnoreCase))
  772.         return;
  773.  
  774.     Host.Log("loading preset '" + OverviewPreset + "' to overview (current selection is '" + OverviewTypeSelectionName + "').");
  775.     Sanderling.MouseClickRight(OverviewPresetTabActive);
  776.     Sanderling.MouseClickLeft(Menu?.FirstOrDefault()?.EntryFirstMatchingRegexPattern("load.*preset", RegexOptions.IgnoreCase));
  777.     var PresetMenuEntry = Menu?.ElementAtOrDefault(1)?.EntryFirstMatchingRegexPattern(@"^\s*" + Regex.Escape(OverviewPreset) + @"\s*$", RegexOptions.IgnoreCase);
  778.  
  779.     if(null == PresetMenuEntry)
  780.     {
  781.         Host.Log("error: menu entry '" + OverviewPreset + "' not found");
  782.         return;
  783.     }
  784.  
  785.     Sanderling.MouseClickLeft(PresetMenuEntry);
  786. }
  787.  
  788. void MemoryUpdate()
  789. {
  790.     RetreatUpdate();
  791.     JammedLastTimeUpdate();
  792.     OffloadCountUpdate();
  793. }
  794.  
  795. void JammedLastTimeUpdate()
  796. {
  797.     if(Jammed)
  798.         JammedLastTime    = Host.GetTimeContinuousMilli();
  799. }
  800.  
  801. bool MeasurementEmergencyWarpOutEnter =>
  802.     !(Measurement?.IsDocked ?? false) && !(EmergencyWarpOutHitpointPercent < ShieldHpPercent);
  803.  
  804. void RetreatUpdate()
  805. {
  806.  
  807.     if(hostileOrNeutralsInLocal)
  808.     {
  809.         System.Media.SoundPlayer simpleSound = new System.Media.SoundPlayer(@"C:\Windows\Media\tada.wav");
  810.          simpleSound.Play();
  811.     }
  812.     RetreatReasonTemporary = (RetreatOnNeutralOrHostileInLocal && hostileOrNeutralsInLocal)    ? "hostile or neutral in local" : null;
  813.  
  814.     if (!MeasurementEmergencyWarpOutEnter)
  815.         return;
  816.  
  817.     //    measure multiple times to avoid being scared off by noise from a single measurement.
  818.     Sanderling.InvalidateMeasurement();
  819.  
  820.     if (!MeasurementEmergencyWarpOutEnter)
  821.         return;
  822.  
  823.     RetreatReasonTemporary = "shield hp";
  824.  
  825. }
  826.  
  827. void OffloadCountUpdate()
  828. {
  829.     var    OreHoldFillPercentSynced    = OreHoldFillPercent;
  830.  
  831.     if(!OreHoldFillPercentSynced.HasValue)
  832.         return;
  833.  
  834.     if(0 == OreHoldFillPercentSynced && OreHoldFillPercentSynced < LastCheckOreHoldFillPercent)
  835.         ++OffloadCount;
  836.  
  837.     LastCheckOreHoldFillPercent = OreHoldFillPercentSynced;
  838. }
  839.  
  840. bool IsNeutralOrEnemy(IChatParticipantEntry participantEntry) =>
  841.    !(participantEntry?.FlagIcon?.Any(flagIcon =>
  842.      new[] { "good standing", "excellent standing", "Pilot is in your (fleet|corporation|alliance)", }
  843.      .Any(goodStandingText =>
  844.         flagIcon?.HintText?.RegexMatchSuccessIgnoreCase(goodStandingText) ?? false)) ?? false);
  845.        
  846. // Emergency Warpout v.0.1
  847. void EmergencyWarpout()
  848. {
  849.         var OverviewRetreatStation = WindowOverview?.ListView?.Entry?.Where(entry => entry.Name == RetreatStation);
  850.         var OverviewResortDistance = WindowOverview?.ListView?.ColumnHeader?.Where(entry => entry.Text == "Distance");
  851.         if (null != OverviewRetreatStation?.FirstOrDefault())
  852.         {
  853.         Sanderling.KeyboardPressCombined(new[]{ VirtualKeyCode.SHIFT, VirtualKeyCode.VK_R });
  854.             Sanderling.MouseClickLeft(OverviewRetreatStation?.FirstOrDefault());
  855.             Host.Log(OverviewRetreatStation?.FirstOrDefault()?.Name);
  856.             Sanderling.KeyboardPress(VirtualKeyCode.VK_D);
  857.         }
  858.         else
  859.         {    
  860.             Sanderling.KeyboardPressCombined(new[]{ VirtualKeyCode.SHIFT, VirtualKeyCode.VK_R });
  861.             Sanderling.MouseClickLeft(OverviewResortDistance?.FirstOrDefault());
  862.             Sanderling.MouseClickLeft(OverviewRetreatStation?.FirstOrDefault());
  863.             Host.Log(OverviewRetreatStation?.FirstOrDefault()?.Name);
  864.             Sanderling.KeyboardPress(VirtualKeyCode.VK_D);
  865.             Sanderling.MouseClickLeft(OverviewResortDistance?.FirstOrDefault());
  866.         }
  867.         Sanderling.KeyboardPress(VirtualKeyCode.VK_D);
  868. Host.Delay(222);
  869. Sanderling.MouseClickLeft(OverviewResortDistance?.FirstOrDefault());
  870. }
Advertisement
Add Comment
Please, Sign In to add comment