Avoiding to struggle - a guide for beginers

For more than 1 month i struggle with the bot, and i still have to learn many things, but i like to share with you my … experience. All of them are variants of what you find on this forum and i tested and re-tested ( lose ships, i died etc).
First of all you have to remember this is a bot, he read ( some) of data’s memory from game interface and you will use this to give some commands. So, if somebody , cloaked look at you he ( CCP) can ban you. Also CCP can look at some data ( i just imagine what: login/logout, activities, money balance etc and also one of them can look at you and measure your mouvements - i know that from other games); So keep in mind that, and avoid botting too much, make too many isk/day .
Also customise your bot: one day make an system with one char, another day , another system, another ship, , one day forbiden hub, another day haven, etc. Even in the same system, change your retreat bookmark from time to time. Personally I botting only with one char at time. sometime i let the drones aggresives, other time on passive, etc, and I keep an eye on him ( is on another computer, near me)
Second, try to use sanderling. he is updated, reworked, and also more reliable. is easier to change inside a script than recompile abot.
I always start to script in sanderling and after that i test in abot, because sanderling is more comprehensible for me ( I’m not an programmer/coder);
So… keep in mind , my code is not clean, ergonomic etc; but he is doing his job:

  1. anomaly enter: you don’t need another skip anomaly class, is enough to add this to your anomalyenter.cs:
		static public bool IgnoreAnomaly(Interface.MemoryStruct.IListEntry scanResult) => scanResult?.CellValueFromColumnHeader("Name")?.RegexMatchSuccessIgnoreCase("asteroid|drone|forlorn|rally|sanctum|blood hub|serpentis hub|hidden|haven") ?? false;
		static public bool ActuallyAnomaly(Interface.MemoryStruct.IListEntry scanResult) =>
		scanResult?.CellValueFromColumnHeader("Distance")?.RegexMatchSuccessIgnoreCase("km") ?? false;

Sorry, i tried to change (“asteroid|drone|forlorn|rally|sanctum|blood hub|serpentis hub|hidden|haven”) with an string to use bot;conf, but It didn’t work; maybe a pro could help??
And once you get out from warp, this will work like a charm ( in 3 sec you are in another warp, with an vni):

				if (null != scanActuallyAnomaly)
					yield return scanActuallyAnomaly.ClickMenuEntryByRegexPattern(bot, "Ignore Result");
 or before any warp using bool ignoreAnomaly

				if (null != UndesiredAnomaly)

					yield return UndesiredAnomaly.ClickMenuEntryByRegexPattern(bot, "Ignore Result");

So , In the end, you can let him ingore ALL undesired anomaly to have a clean window and later ignore only one with “km” and the new ones…also , ensure your probewindow is open will help you later when you have to ignore occupied anomaly, because you have to refresh the window :

				if (probeScannerWindow == null)
					
					
					yield return new BotTask //open windowprobes
					{
						Effects = new[] { MotionParamExtension.KeyboardPressCombined(new[] 
						{
								   VirtualKeyCode.LMENU, VirtualKeyCode.VK_P
						}) }

					};
  1. Next, i created a new task, who close the windows, dialogues etc ( remember to put this new task in bot.cs)
    I will offfer you only telecomwindow, to close the window from forsaken hubs. you can develop and apply to any other window,( thx Viir, for helping me)
				var WindowTelecom = memoryMeasurement?.WindowTelecom?.FirstOrDefault(w => (w?.Caption.RegexMatchSuccessIgnoreCase("Information") ?? false));
				var CloseButton = WindowTelecom?.ButtonText?.FirstOrDefault(text => text.Text.RegexMatchSuccessIgnoreCase("Close"));
				if (CloseButton != null)
					yield return new BotTask { Effects = new[] { CloseButton.MouseClick(BotEngine.Motor.MouseButtonIdEnum.Left) } };

	//		and, here you can refresh the probes window, because you can stick that at warp state( yes the 
			if (ShipManeuverStatus == ShipManeuverTypeEnum.Warp)
					yield return new BotTask
					{
						Effects = new[] { MotionParamExtension.KeyboardPressCombined(new[] {
								   VirtualKeyCode.LMENU, VirtualKeyCode.VK_P
									}) }

					};
4 Likes
  1. And now we have to fight, isn’t? You already have from forum listOverviewEntryToAttack; checking for dread, but, marking the anomaly … ah , yes, this is enough( i will let the commented lines, because i tried all variants, and finally i used the trick with ignore in anomalyEnter … but you can try yourself):
				if (bot?.OwnAnomaly == false)
				{

					if ((listOverviewEntryToAttack.Count() > 100) || (listOverviewEntryFriends.Length > 0) || (listOverviewEntryCorp.Length>0) )
					{

					//	yield return new SkipAnomalyF { bot = bot };
						yield return new AnomalyEnter { bot = bot };
					//	yield return new RetreatTask { Bot = bot };


					}
					else
					
						bot?.SetOwnAnomaly(true);
/*						if (null != scanActuallyAnomaly)
						{
							yield return scanActuallyAnomaly.ClickMenuEntryByRegexPattern(bot, "save location");
						}
						//	yield return bot.LaunchFighters(memoryMeasurement?.ShipUi?.SquadronsUI);

*/
(the if ((listOverviewEntryToAttack.Count() > 100)  is from when i tested ignoring , but you can change from 100 to 10 and so you avoid the gas haven :d :)) or to be sure, you can put also the towers from gas havens, so you will take only rock ones )					
Yes, you can bookmark anomaly ( for salvaging? for taking  later your mtu??? )

You wanna take the loot from faction rats? take this:

				var listOverviewCommanderWreck = memoryMeasurement?.WindowOverview?.FirstOrDefault()?.ListView?.Entry?.Where(entry => entry?.Name?.RegexMatchSuccessIgnoreCase("Commander|Dark Blood|Shadow Serpentis|Dread Gurista|Domination Saint") ?? true)
				.ToList();
				var wreckCommander = listOverviewCommanderWreck?.FirstOrDefault(); // next lines are at the end when:  if (!(0 < listOverviewEntryToAttack?.Length))....
							if (wreckCommander != null)
								yield return wreckCommander.ClickMenuEntryByRegexPattern(bot, "open cargo");

Of course, you have to push the button “loot all” from window inventory. :slight_smile:

But in the end you have to be alive. be aware, sometimes the bot doesn’t read some window ( drones/probes etc and you have to restart the game) and sometimes he will alert you for nothing and try to save the ship. I concluded he is catch not only the flagicon but also the personal standings of one or another guy from local. If you have 300 on local… you are all time in saveship task because one or another guy just killed an enemy and he has bad standings ( ?? or he is read … with errors, maybe he is just entered in ally etc etc))even if he’s blue/green. I dont have a prove,( and believe-me, i tried to measure 3-4 days but nothing, and most of false alarms are from "excellent standings(.) ) so is just my conclusion . So another advice, avoid to bot in systems with more than 20 guys, in big ally.
4.
Staying alive, so saveship task for me is:
stop afterburner,
start armor repairer ( because some rats will hit you, or just because the reds could be on you )
align to retreatbookmark : you want to be far from theoretical point of reds warp AND also, if your drones struggle to get out from wrecks and rats is better to be a little far, and also you avoid the situation when your drones try and try and try for 20-30 seconds to enter in your ship.
retreat your drones ( for me it take 5-6 sec)

Also , if the reds come to you or you have in system more that 2 ( yes, the bot count you also) ( if you have a spike???) forget your drones AND ASAP warp retreat bookmark.
Another thing, dont chose a citadel home near of stargates, the rats near stargate will put you in combat mode)

In the end ( or at beginning) you can learn from sanderling scripts to: have more than one safespots ( unload your cargo full of faction loot, etc etc), warp to bookmark ( for salvaging?? or take the small and voluminous loot??). You’ll find invaluable infos and ways to do things( changing your system? :d)

2 Likes

how is asked in Pikacuq is tweaking A-Bot :), i will share parts of my combat.cs; but is always in dev. mode, so is not a clean code or even logical.
So for me, armor perma is off , because i fly an speed vni ( you can looking on forum to find him) and i dont need too much of him. Actually i think at some point I wil replace him with an drone damage2. So , when i need armor he will be later activated and deactivated.
NExt: later i change some tabs, and i have anchor var to make the difference between anomaly and near citadel position. Thats because sometime , its happens to be near citadel, and have some rats around and blues. Well, in my sense, the presence of anchor make the difference.

public class CombatTask : IBotTask
	{
		const int TargetCountMax = 2;

		public Bot bot;
		public bool OwnAnomaly = false;
		//public bool Jammed => ShipUi?.EWarElement?.Any(EwarElement => (EwarElement?.EWarType).RegexMatchSuccess("electronic")) ?? false;
		//	public bool Jammed => bot?.MemoryMeasurementAtTime?.Value?.ShipUi?.EWarElement?.Any(EwarElement => (EwarElement?.EWarType).RegexMatchSuccess("electronic")) ?? false;
		static public bool ActuallyAnomaly(Interface.MemoryStruct.IListEntry scanResult) =>
scanResult?.CellValueFromColumnHeader("Distance")?.RegexMatchSuccessIgnoreCase("km|m") ?? false;

		public bool Completed { private set; get; }

		public IEnumerable<IBotTask> Component
		{
			get
			{

				var ArmorPERMATANK = false;


				var memoryMeasurementAtTime = bot?.MemoryMeasurementAtTime;
				var memoryMeasurementAccu = bot?.MemoryMeasurementAccu;

				var memoryMeasurement = memoryMeasurementAtTime?.Value;

				if (!memoryMeasurement.ManeuverStartPossible())
					yield break;
				Tab OverviewTabActive =
				memoryMeasurement.WindowOverview?.FirstOrDefault()?.PresetTab
				?.OrderByDescending(tab => tab?.LabelColorOpacityMilli ?? 1500)
				?.FirstOrDefault();

				var combatTab = memoryMeasurement.WindowOverview?.FirstOrDefault()?.PresetTab
				?.OrderByDescending(tab => tab?.Label.Text.RegexMatchSuccessIgnoreCase("combat"))
				?.FirstOrDefault();

				var salvageTab = memoryMeasurement.WindowOverview?.FirstOrDefault()?.PresetTab
				?.OrderByDescending(tab => tab?.Label.Text.RegexMatchSuccessIgnoreCase("misc"))
				?.FirstOrDefault();

				var Anchor = memoryMeasurement?.WindowOverview?.FirstOrDefault()?.ListView?.Entry
				?.Where(entry => entry?.Name?.RegexMatchSuccessIgnoreCase("broken|pirate gate") ?? false)
				?.OrderBy(entry => entry?.DistanceMax ?? int.MaxValue)
				?.ToList();

`Becasue haven sites are divided, and i dont like the gas ones, I avoid them using an separated list ( trust me I even dont know if the bot can work with so many var, lists, arrays etc and conditions, i supose he open a new thread for each one of them; but I’m happy he work, for now)
so how can I avoid an anomaly( occupied or not)? simple like that:

var listOverviewAvoidAnomalys = memoryMeasurement?.WindowOverview?.FirstOrDefault()?.ListView?.Entry?.Where(entry => entry?.Name?.RegexMatchSuccess("Chemical Factory") ?? true)
.ToList();
if (bot?.OwnAnomaly == false)
{

if ((listOverviewAvoidAnomalys.Count() > 0) || (listOverviewEntryFriends.Length > 0) || (listOverviewEntryCorp.Length > 0) || (listOverviewEntryToAttack.Count() > 100))
{
	yield return new AnomalyEnter { bot = bot };
}
else
{
bot?.SetOwnAnomaly(true);
if (null != scanActuallyAnomaly)
{
yield return scanActuallyAnomaly.ClickMenuEntryByRegexPattern(bot, "save location");
}

var Broken = memoryMeasurement?.WindowOverview?.FirstOrDefault()?.ListView?.Entry
?.Where(entry => entry?.Name?.RegexMatchSuccessIgnoreCase("broken|pirate gate") ?? false)
?.OrderBy(entry => entry?.DistanceMax ?? int.MaxValue)
?.ToArray();

var orbitKeyCode = (VirtualKeyCode)'W';
yield return bot?.EnsureIsActive(ab); //ACTIVE AF/MWD				

if (Anchor.Count > 0)
//yield return Broken.FirstOrDefault().ClickMenuEntryByRegexPattern(bot, "Orbit", "30 km"); Im not using this line just because i change sometime the orbit range, but is working
yield return new BotTask
{
Effects = new[]
{
														MotionParamExtension.KeyDown(orbitKeyCode),
														Broken.FirstOrDefault().MouseClick(MouseButtonIdEnum.Left),
														MotionParamExtension.KeyUp(orbitKeyCode)
}
};
yield return bot?.EnsureIsActive(ab); //ACTIVE AF/MWD
}
}

the last one for today, is the one to enter in combat. Actually, i put the condition of dread and reds only, because if i put the green ones, … well, the bot dont make the difference betwen a new anomaly and my own anomaly( they are before, to mark my own anomaly and to orbit for the first time, ( good for haven sites because you orbit and wait until the rats are coming) After that they are forgoten by bot.

if (listOverviewDreadCheck.Count() > 0 || (listOverviewEntryEnemy.Count() > 0))
{
yield return new RetreatTask { Bot = bot };
}
else
{
yield return bot?.EnsureIsActive(ab); //ACTIVE AF/MWD
if (combatTab != OverviewTabActive)
and    from here its starts the fight
if ((listOverviewEntryToAttack.Count() > 0)  && (Anchor.Count > 0))
{
if (ShipManeuverStatus != ShipManeuverTypeEnum.Orbit)
{
var Broken = memoryMeasurement?.WindowOverview?.FirstOrDefault()?.ListView?.Entry
?.Where(entry => entry?.Name?.RegexMatchSuccessIgnoreCase("broken|pirate gate") ?? false)
?.OrderBy(entry => entry?.DistanceMax ?? int.MaxValue)
?.ToArray();
var orbitKeyCode = (VirtualKeyCode)'W';

//yield return Broken.FirstOrDefault().ClickMenuEntryByRegexPattern(bot, "Orbit", "30 km");
yield return new BotTask
{
Effects = new[]
{
MotionParamExtension.KeyDown(orbitKeyCode),
										Broken.FirstOrDefault().MouseClick(MouseButtonIdEnum.Left),
MotionParamExtension.KeyUp(orbitKeyCode)
}
};
}

you ask yourself why i put the orbit again? me too, :)) i kidding . Well, an really fast ship can get in and out from you system before your drones, imbricated betwen rocks, other drones wrecks and rats to even start to come to you. So even if Im in fight, the red come and disapear, but Im aligned, my ab is off, my perma is on and … this lines put me again on orbit mode :d ( saveship is disapeared from savetask) and even if the drones get inside your ship in the same time, he will get them out and fight : :wink:
actually, if you ask me like a friend the trickery with anchor is from 3-4 days, before i used only this lines :))

good stuff, some nice ideas here and there. Thanks for inspiration indeed :slight_smile:

and our history keep going …; and keep :slight_smile:

you really want to take the faction loot, isn’t?
Well, i have for you something more : take the loot and salvage.
about salvage , i think you have to tweak a little more, to put the salvager in framework sanderling, compile and copy some dll into abot. i do that some time ago, and i don’t remember exactly how;
but you have another way to do: tooltip and caption for module
I suppose you know more than me to realize this stuff, but if you need, i can offer my help.
back to salvage and taking the loot. Once the rats are dead, you can change the tab to the one with wrecks.or not, how you want.
you can change the salvage range with 1000 , no problem, I think.

int? salvageRange = 500;
if (listOverviewCommanderWreck.Count > 0)
{

if (null == targetSelected)
{
if (!(wreckCommander.DistanceMax < salvageRange))
yield return wreckCommander.ClickMenuEntryByRegexPattern(bot, "open cargo");
else
yield return wreckCommander.ClickMenuEntryByRegexPattern(bot, @"^lock\s*target");
if (LootButton != null)
{
yield return new BotTask { Effects = new[] { LootButton.MouseClick(BotEngine.Motor.MouseButtonIdEnum.Left) } };
}
}
else
if (!(absalvager.IsActive(bot) ?? true))
								
yield return bot.EnsureIsActive(absalvager);
}

I wanna thanks to the real programmers and coders who made/contribute at the miner script. Without this script i could not accomplish all this stuff ( because Im null at programming, you see my coding style :d :)) )

And the bonus, traveling with A-bot

	var RouteElementMarkerNext =
	memoryMeasurement?.InfoPanelRoute?.RouteElementMarker
	?.OrderByCenterDistanceToPoint(new Vektor2DInt(0, 0))?.FirstOrDefault(); 

// you have to put the  using bib3geometry up on the head on file, VS help you :slight_smile:
//later, when you don't have any anomaly in you system,  this lines help you:
if (null == scanResultCombatSite)
if (null != RouteElementMarkerNext)
{
var MenuEntry =
	memoryMeasurement?.Menu?.FirstOrDefault()
	?.Entry?.FirstOrDefault(candidate => candidate.Text.RegexMatchSuccessIgnoreCase("dock|Jump through stargate"));
if (null != MenuEntry)
yield return new BotTask { Effects = new[] { MenuEntry.MouseClick(BotEngine.Motor.MouseButtonIdEnum.Left) } };

yield return new BotTask { Effects = new[] { RouteElementMarkerNext.MouseClick(BotEngine.Motor.MouseButtonIdEnum.Right) } };
} 
else
yield return new DiagnosticTask

{
MessageText = NoSuitableAnomalyFoundDiagnosticMessage,
};

Of course, you can improve this thing from Terpla’s adventures. Here you have the link: Terpla adventures or blog-style guide for begginers - #10 by kaboonus

may I ask you where you have this defined? thanks!

is defined "by default "
result from metadata search

public static IEnumerable<T> OrderByCenterDistanceToPoint<T>(this IEnumerable<T> sequence, Vektor2DInt point) where T : IUIElement;

select the text and press f12 of right click and go to definition in VS and you have the results from metatada

that’s strange, it’s not in my codebase which is sanderling 2018-04-04
hm

using Bib3.Geometrik;

maybe this is the secret? since this lines are from default script on sanderling framewok, it had to be present in your sanderling

this is why bib3.geomerik needs to be added, but the first think is not defined for me… ffs where is that bitch :wink:

ah it was

using Sanderling.Interface.MemoryStruct;

:))
you didnt have interface.memory.struct from

		static public bool AnomalySuitableGeneral(Interface.MemoryStruct.IListEntry scanResult) =>
			scanResult?.CellValueFromColumnHeader("Group")?.RegexMatchSuccessIgnoreCase("combat") ?? false;
??

am not putting all my code into one file, so i’ve created new task “travel” which is called upon configuration “autopilot: true”

:wink:

so i havent have all modules loaded in my new file

i’d like to know why Adaptive Invulnerability Field activate by himself, without any *.conf and even in “oficial” a-bot

it’s defined by

namespace Sanderling.Parse
{
    public interface IModuleButtonTooltip : IContainer, IUIElement, IObjectIdInMemory, IObjectIdInt64
    {
        bool? IsWeapon { get; }
        int? SignatureRadiusModifierMilli { get; }
        int? RangeWithin { get; }
        int? RangeFalloff { get; }
        int? RangeMax { get; }
        int? RangeOptimal { get; }
        bool? IsIceHarvester { get; }
        bool? IsSurveyScanner { get; }
        bool? IsMiner { get; }
        bool? IsHardener { get; }
        bool? IsArmorRepairer { get; }
        bool? IsShieldBooster { get; }
        bool? IsMicroJumpDrive { get; }
        bool? IsMicroWarpDrive { get; }
        bool? IsAfterburner { get; }
        bool? IsTargetPainter { get; }
        IUIElementText ToggleKeyTextLabel { get; }
        VirtualKeyCode[] ToggleKey { get; }
    }
}

I believe

p.s:
to your traveling part, just add

				var ShipManeuverStatus = memoryMeasurement.ShipUi?.Indication?.ManeuverType;

				if (ShipManeuverStatus != ShipManeuverTypeEnum.Warp)
				{
					if (null != RouteElementMarkerNext)
					{

so it will not be clicking on menu every second during warp… :wink:

mine doesn’t click on warp since is in anomaly enter and

		if (!memoryMeasurement.ManeuverStartPossible())
					yield break;


the invul field  doesn't matter where is defined; there is someting who activate him
maybe because of that:

static public bool ShouldBeActivePermanent(this Accumulation.IShipUiModule module, Bot bot) =>
			new[]
			{
				module?.TooltipLast?.Value?.IsHardener,
				bot?.ConfigSerialAndStruct.Value?.ModuleActivePermanentSetTitlePattern
					?.Any(activePermanentTitlePattern => module?.TooltipLast?.Value?.TitleElementText()?.Text?.RegexMatchSuccessIgnoreCase(activePermanentTitlePattern) ?? false),
			}
			.Any(sufficientCondition => sufficientCondition ?? false);

and module task, since is defined.
anyway; is just annoying if you use a gila/vni and you travel between systems, because afterwarp h try to activate him.

Btw about gila and drones number< 5; you can put that ( you need inventory window opened all time):

var ShipType = WindowInventory?.LabelText?.FirstOrDefault(text => (text.Text?.RegexMatchSuccessIgnoreCase("Gila") ?? true));
				if (null != ShipType)
				 DroneNumber = 2;
					else 
					DroneNumber= 5;

you can change Gila with any ship you need ( or even made some arrays from *.conf, how you like)

I can assume that this is due to the following code in the BotExtension.cs:

static public bool ShouldBeActivePermanent(this Accumulation.IShipUiModule module, Bot bot) =>
			new[]
			{
				module?.TooltipLast?.Value?.IsHardener??false,
				bot?.ConfigSerialAndStruct.Value?.ModuleActivePermanentSetTitlePattern
					?.Any(activePermanentTitlePattern => module?.TooltipLast?.Value?.TitleElementText()?.Text?.RegexMatchSuccessIgnoreCase(activePermanentTitlePattern) ?? false),
			}
			.Any(sufficientCondition => sufficientCondition ?? false);

thats sure, in meantime Im used with him :))