I took some example code and patched together the following. I have never programmed in C# and my functional programming sucks. Can you optimize this for me? Returns “true” on hostile in local. Thanks!
bool hostilesInLocal() { string[] standings = { "Pilot has bad standing", "Pilot has terrible standing", "Pilot is a suspect" }; var listParticipantNameAndFlagText = Sanderling.MemoryMeasurement?.Value?.WindowChatChannel ?.SelectMany(windowChatChannel => windowChatChannel?.ParticipantView?.Entry ?.Select(participantEntry => new { name = participantEntry?.NameLabel?.Text, flagText = string.Join(",", (participantEntry?.FlagIcon?.Select(flagIcon => flagIcon?.HintText)).EmptyIfNull()), }) )?.ToArray(); foreach(var participantNameAndFlagText in listParticipantNameAndFlagText) { if (Array.IndexOf(standings, participantNameAndFlagText.flagText) > -1) { Host.Log(participantNameAndFlagText); return true; } } return false;}
Not sure what you mean with optimizing, for this answer I assume you mean reduing the number of symbols needed and don’t mind if I also reduce the probability of Exceptions thrown.
Given this assumption, you could try this:
string[] standings = { "Pilot has bad standing", "Pilot has terrible standing", "Pilot is a suspect" }; bool hostilesInLocal() => Sanderling.MemoryMeasurement?.Value?.WindowChatChannel ?.SelectMany(windowChatChannel => windowChatChannel?.ParticipantView?.Entry ?.Select(participantEntry => new { name = participantEntry?.NameLabel?.Text, flagText = string.Join(",", (participantEntry?.FlagIcon?.Select(flagIcon => flagIcon?.HintText)).EmptyIfNull()), })) ?.Any(participantNameAndFlagText => standings.Any(standing => { var match = standing.Equals(participantNameAndFlagText.flagText); if(match) Host.Log(participantNameAndFlagText); return match; })) ?? true;
Instead of throwing the NullReferenceException for example in the case when there is no chat window it will return true.
If i also want to use this, do i just copy paste it in to my script?
So far, I don’t see any problems with this approach.
However, for the actual algorithm, I will try a different approach to decide whether there are hostiles in local the bot should dock when I add this feature to the mining script.
This uses a whitelist of standings (flag text) to ignore. As I observed the players own character being visible in local too, the algorithm returns ‘true’ if the number of chat participant entries classified as neutral or hostile is not equal to one:
using Parse = Sanderling.Parse;
bool IsNeutralOrEnemy(IChatParticipantEntry participantEntry) =>
!(participantEntry?.FlagIcon?.Any(flagIcon =>
new[] { "good standing", "excellent standing" }
.Any(goodStandingText =>
flagIcon?.HintText?.RegexMatchSuccessIgnoreCase(goodStandingText) ?? false)) ?? false);
WindowChatChannel chatLocal =>
Sanderling.MemoryMeasurementParsed?.Value?.WindowChatChannel
?.FirstOrDefault(windowChat => windowChat?.Caption?.RegexMatchSuccessIgnoreCase("local") ?? false);
// assuming that own character is always visible in local
bool hostileOrNeutralsInLocal => 1 != chatLocal?.ParticipantView?.Entry?.Count(IsNeutralOrEnemy);
EDIT: Apparently I confused the concepts of “Hostile” and “Neutral or Hostile” when writing my post. The approach I showed will treat neutrals the same as hostiles.
I was forced to take the opposite approach. I spend a lot of time mining in systems where neutrals, and players without a specific standing (no flag icon text) are present. The original IsNeutralOrEnemy kept me docked all the time. For this reason I now only run and cower on the following three conditions (yes this does me a periotically get ganked by a neutral but I then add them to my contacts as hostile):
"Pilot has bad standing", "Pilot has terrible standing", "Pilot is a suspect"
I was forced to take the opposite approach. I spend a lot of time mining in systems where neutrals, and players without a specific standing (no flag icon text) are present. The original IsNeutralOrEnemy kept me docked all the time. For this reason I now only run and cower on the following three conditions (yes this does me a periotically get ganked by a neutral but I then add them to my contacts as hostile):
"Pilot has bad standing", "Pilot has terrible standing", "Pilot is a suspect"
Thank you for explaining this. I made a mistake reading this and confused it with another question. Good to know why you made that decision in the first place.