Exemple #1
0
        /// <summary>
        ///   Interact with the agent so we know what ammo to bring
        /// </summary>
        /// <returns>True if interact is done</returns>
        private bool Interact()
        {
            // Are we done?
            if (_agentInteraction.State == AgentInteractionState.Done)
            {
                return(true);
            }

            if (_agentInteraction.Agent == null)
            {
                throw new Exception("Invalid agent");
            }

            // Start the conversation
            if (_agentInteraction.State == AgentInteractionState.Idle)
            {
                _agentInteraction.State = AgentInteractionState.StartConversation;
            }

            // Interact with the agent to find out what ammo we need
            _agentInteraction.ProcessState();

            if (_agentInteraction.State == AgentInteractionState.DeclineMission)
            {
                if (_agentInteraction.Agent.Window != null)
                {
                    _agentInteraction.Agent.Window.Close();
                }

                throw new Exception("Low security systems");
            }

            if (_agentInteraction.State == AgentInteractionState.Done)
            {
                _arm.AmmoToLoad.Clear();
                _arm.AmmoToLoad.AddRange(_agentInteraction.AmmoToLoad);
                return(true);
            }

            return(false);
        }
        /// <summary>
        ///   Interact with the agent so we know what ammo to bring
        /// </summary>
        /// <returns>True if interact is done</returns>
        private bool Interact()
        {
            // Are we done?
            if (_agentInteraction.State == AgentInteractionState.Done)
            {
                return(true);
            }

            if (_agentInteraction.Agent == null)
            {
                throw new Exception("Invalid agent");
            }

            // Start the conversation
            if (_agentInteraction.State == AgentInteractionState.Idle)
            {
                _agentInteraction.State = AgentInteractionState.StartConversation;
            }

            // Interact with the agent to find out what ammo we need
            _agentInteraction.ProcessState();

            if (_agentInteraction.State == AgentInteractionState.DeclineMission)
            {
                if (_agentInteraction.Agent.Window != null)
                {
                    _agentInteraction.Agent.Window.Close();
                }
                Logging.Log("GenericCombatStoryline: Mission offer is in a Low Security System"); //do storyline missions in lowsec get blacklisted by: "public StorylineState Arm(Storyline storyline)"?
                throw new Exception("Low security systems");
            }

            if (_agentInteraction.State == AgentInteractionState.Done)
            {
                _arm.AmmoToLoad.Clear();
                _arm.AmmoToLoad.AddRange(_agentInteraction.AmmoToLoad);
                return(true);
            }

            return(false);
        }
Exemple #3
0
        private void OnFrame(object sender, EventArgs e)
        {
            var watch = new Stopwatch();

            // Only pulse state changes every 1.5s
            if (DateTime.Now.Subtract(_lastPulse).TotalMilliseconds < 1500)
            {
                return;
            }
            _lastPulse = DateTime.Now;

            // Session is not ready yet, do not continue
            if (!Cache.Instance.DirectEve.Session.IsReady)
            {
                return;
            }

            // If Questor window not visible, show it
            if (!m_Parent.Visible)
            {
                m_Parent.Visible = true;
            }

            // We are not in space or station, don't do shit yet!
            if (!Cache.Instance.InSpace && !Cache.Instance.InStation)
            {
                return;
            }

            // New frame, invalidate old cache
            Cache.Instance.InvalidateCache();

            // Update settings (settings only load if character name changed)
            Settings.Instance.LoadSettings();
            CharacterName = Cache.Instance.DirectEve.Me.Name;

            // Check 3D rendering
            if (Cache.Instance.DirectEve.Session.IsInSpace && Cache.Instance.DirectEve.Rendering3D != !Disable3D)
            {
                Cache.Instance.DirectEve.Rendering3D = !Disable3D;
            }

            // Invalid settings, quit while we're ahead
            if (!ValidSettings)
            {
                if (DateTime.Now.Subtract(_lastAction).TotalSeconds < 15)
                {
                    ValidateSettings();
                    _lastAction = DateTime.Now;
                }
                return;
            }

            foreach (var window in Cache.Instance.Windows)
            {
                // Telecom messages are generally mission info messages
                if (window.Name == "telecom")
                {
                    Logging.Log("Questor: Closing telecom message...");
                    Logging.Log("Questor: Content of telecom window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]");
                    window.Close();
                }

                // Modal windows must be closed
                // But lets only close known modal windows
                if (window.Name == "modal")
                {
                    bool close = false;
                    if (!string.IsNullOrEmpty(window.Html))
                    {
                        // Server going down
                        close |= window.Html.Contains("Please make sure your characters are out of harms way");
                        // In space "shit"
                        close |= window.Html.Contains("Item cannot be moved back to a loot container.");
                        close |= window.Html.Contains("you do not have the cargo space");
                        close |= window.Html.Contains("cargo units would be required to complete this operation.");
                        close |= window.Html.Contains("You are too far away from the acceleration gate to activate it!");
                        close |= window.Html.Contains("maximum distance is 2500 meters");
                        // Stupid warning, lets see if we can find it
                        close |= window.Html.Contains("Do you wish to proceed with this dangerous action?");
                        // Yes we know the mission isnt complete, Questor will just redo the mission
                        close |= window.Html.Contains("Please check your mission journal for further information.");
                        // Lag :/
                        close |= window.Html.Contains("This gate is locked!");
                        close |= window.Html.Contains("The Zbikoki's Hacker Card");
                        close |= window.Html.Contains(" units free.");
                    }

                    if (close)
                    {
                        Logging.Log("Questor: Closing modal window...");
                        Logging.Log("Questor: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]");
                        window.Close();
                    }
                }
            }

            // We always check our defense state if we're in space, regardless of questor state
            // We also always check panic
            if (Cache.Instance.InSpace)
            {
                watch.Reset();
                watch.Start();
                if (ExitSta == false)
                {
                    _defense.ProcessState();
                }
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("Defense.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }
            }

            // Defense is more important then pause, rest (even panic) isnt!
            if (Paused)
            {
                return;
            }

            // Panic always runs, not just in space
            watch.Reset();
            watch.Start();
            _panic.InMission = State == QuestorState.ExecuteMission;
            if (State == QuestorState.Storyline && _storyline.State == StorylineState.ExecuteMission)
            {
                _panic.InMission |= _storyline.StorylineHandler is GenericCombatStoryline && (_storyline.StorylineHandler as GenericCombatStoryline).State == GenericCombatStorylineState.ExecuteMission;
            }
            _panic.ProcessState();
            watch.Stop();

            if (Settings.Instance.DebugPerformance)
            {
                Logging.Log("Panic.ProcessState took " + watch.ElapsedMilliseconds + "ms");
            }

            if (_panic.State == PanicState.Panic || _panic.State == PanicState.Panicking)
            {
                // If Panic is in panic state, questor is in panic state :)
                State = State == QuestorState.Storyline ? QuestorState.StorylinePanic : QuestorState.Panic;

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("State = " + State);
                }
            }
            else if (_panic.State == PanicState.Resume)
            {
                // Reset panic state
                _panic.State = PanicState.Normal;

                // Ugly storyline resume hack
                if (State == QuestorState.StorylinePanic)
                {
                    State = QuestorState.Storyline;

                    if (_storyline.StorylineHandler is GenericCombatStoryline)
                    {
                        (_storyline.StorylineHandler as GenericCombatStoryline).State = GenericCombatStorylineState.GotoMission;
                    }
                }
                else
                {
                    // Head back to the mission
                    _traveler.State = TravelerState.Idle;
                    State           = QuestorState.GotoMission;
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("State = " + State);
                }
            }

            if (Settings.Instance.DebugStates)
            {
                Logging.Log("Panic.State = " + _panic.State);
            }

            // When in warp there's nothing we can do, so ignore everything
            if (Cache.Instance.InWarp)
            {
                return;
            }

            DirectAgentMission mission;

            switch (State)
            {
            case QuestorState.Idle:
                if (Cache.Instance.StopTimeSpecified)
                {
                    if (DateTime.Now >= Cache.Instance.StopTime)
                    {
                        Logging.Log("Time to stop.  Quitting game.");
                        Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdQuitGame);
                        return;
                    }
                }

                if (Cache.Instance.InSpace)
                {
                    // Questor doesnt handle inspace-starts very well, head back to base to try again
                    Logging.Log("Questor: Started questor while in space, heading back to base in 15 seconds");

                    _lastAction = DateTime.Now;
                    State       = QuestorState.DelayedGotoBase;
                    break;
                }

                if (DateTime.Now.Subtract(Program.startTime).Minutes > Program.maxRuntime)
                {
                    // quit questor
                    Logging.Log("Questor: Maximum runtime exceeded.  Quiting...");
                    Application.Exit();
                }

                mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId);
                if (!string.IsNullOrEmpty(Mission) && (mission == null || mission.Name != Mission || mission.State != (int)MissionState.Accepted))
                {
                    // Do not save statistics if loyalty points == -1
                    // Seeing as we completed a mission, we will have loyalty points for this agent
                    if (Cache.Instance.Agent.LoyaltyPoints == -1)
                    {
                        return;
                    }

                    // Get the path
                    var path     = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                    var filename = Path.Combine(path, Cache.Instance.FilterPath(CharacterName) + ".statistics.log");

                    // Write the header
                    if (!File.Exists(filename))
                    {
                        File.AppendAllText(filename, "Date;Mission;Time;Isk;Loot;LP;\r\n");
                    }

                    // Build the line
                    var line = string.Format("{0:dd/MM/yyyy HH:mm:ss}", DateTime.Now) + ";";
                    line += Mission + ";";
                    line += ((int)DateTime.Now.Subtract(Started).TotalMinutes) + ";";
                    line += ((int)(Cache.Instance.DirectEve.Me.Wealth - Wealth)) + ";";
                    line += ((int)LootValue) + ";";
                    line += (Cache.Instance.Agent.LoyaltyPoints - LoyaltyPoints) + ";";
                    line += ((int)LostDrones) + ";";
                    line += ((int)AmmoConsumption) + ";";
                    line += ((int)AmmoValue) + ";\r\n";

                    // The mission is finished
                    File.AppendAllText(filename, line);

                    // Disable next log line
                    Mission = null;
                }

                if (AutoStart)
                {
                    // Dont start missions hour before downtime
                    if (DateTime.UtcNow.Hour == 10)
                    {
                        break;
                    }

                    // Dont start missions in downtime
                    if (DateTime.UtcNow.Hour == 11 && DateTime.UtcNow.Minute < 15)
                    {
                        break;
                    }

                    if (Settings.Instance.RandomDelay > 0 || Settings.Instance.MinimumDelay > 0)
                    {
                        _randomDelay = (Settings.Instance.RandomDelay > 0 ? _random.Next(Settings.Instance.RandomDelay) : 0) + Settings.Instance.MinimumDelay;
                        _lastAction  = DateTime.Now;

                        State = QuestorState.DelayedStart;

                        Logging.Log("Questor: Random mission start delay of [" + _randomDelay + "] seconds");
                    }
                    else
                    {
                        State = QuestorState.Start;
                    }
                }
                else if (ExitWhenIdle)
                {
                    LavishScript.ExecuteCommand("exit");
                }
                break;

            case QuestorState.DelayedStart:
                if (DateTime.Now.Subtract(_lastAction).TotalSeconds < _randomDelay)
                {
                    break;
                }

                State = QuestorState.Start;
                break;


            case QuestorState.DelayedGotoBase:
                if (DateTime.Now.Subtract(_lastAction).TotalSeconds < 15)
                {
                    break;
                }

                Logging.Log("Questor: Heading back to base");
                State = QuestorState.GotoBase;
                break;

            case QuestorState.Start:
                if (_agentInteraction.State == AgentInteractionState.Idle)
                {
                    if (Settings.Instance.EnableStorylines && _storyline.HasStoryline())
                    {
                        Logging.Log("Questor: Storyline detected, doing storyline.");

                        _storyline.Reset();
                        State = QuestorState.Storyline;
                        break;
                    }

                    Logging.Log("AgentInteraction: Start conversation [Start Mission]");

                    _agentInteraction.State   = AgentInteractionState.StartConversation;
                    _agentInteraction.Purpose = AgentInteractionPurpose.StartMission;

                    // Update statistic values
                    Wealth          = Cache.Instance.DirectEve.Me.Wealth;
                    LootValue       = 0;
                    LoyaltyPoints   = Cache.Instance.Agent.LoyaltyPoints;
                    Started         = DateTime.Now;
                    Mission         = string.Empty;
                    LostDrones      = 0;
                    AmmoConsumption = 0;
                    AmmoValue       = 0;
                }

                _agentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State = " + _agentInteraction.State);
                }

                if (_agentInteraction.State == AgentInteractionState.Done)
                {
                    mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId);
                    if (mission != null)
                    {
                        // Update loyalty points again (the first time might return -1)
                        LoyaltyPoints = Cache.Instance.Agent.LoyaltyPoints;
                        Mission       = mission.Name;
                    }

                    _agentInteraction.State = AgentInteractionState.Idle;
                    State = QuestorState.Arm;
                }
                break;

            case QuestorState.Arm:
                if (_arm.State == ArmState.Idle)
                {
                    Logging.Log("Arm: Begin");
                    _arm.State = ArmState.Begin;

                    // Load right ammo based on mission
                    _arm.AmmoToLoad.Clear();
                    _arm.AmmoToLoad.AddRange(_agentInteraction.AmmoToLoad);
                }

                _arm.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Arm.State = " + _arm.State);
                }

                if (_arm.State == ArmState.Done)
                {
                    _arm.State = ArmState.Idle;
                    State      = QuestorState.WarpOutStation;
                }
                break;

            case QuestorState.WarpOutStation:

                var _bookmark = Cache.Instance.BookmarksByLabel(Settings.Instance.bookmarkWarpOut ?? "").OrderBy(b => b.CreatedOn).FirstOrDefault();
                var _solarid  = Cache.Instance.DirectEve.Session.SolarSystemId ?? -1;
                if (_bookmark == null)
                {
                    Logging.Log("WarpOut: No Bookmark");
                    State = QuestorState.GotoMission;
                }
                else if (_bookmark.LocationId == _solarid)
                {
                    if (_traveler.Destination == null)
                    {
                        Logging.Log("WarpOut: Warp at " + _bookmark.Title);
                        _traveler.Destination = new BookmarkDestination(_bookmark);
                        ExitSta = true;
                    }

                    _traveler.ProcessState();
                    if (_traveler.State == TravelerState.AtDestination)
                    {
                        Logging.Log("WarpOut: Safe!");
                        ExitSta = false;
                        State   = QuestorState.GotoMission;
                        _traveler.Destination = null;
                    }
                }
                else
                {
                    Logging.Log("WarpOut: No Bookmark in System");
                    State = QuestorState.GotoMission;
                }
                break;

            case QuestorState.GotoMission:
                var missionDestination = _traveler.Destination as MissionBookmarkDestination;
                if (missionDestination == null || missionDestination.AgentId != Cache.Instance.AgentId)     // We assume that this will always work "correctly" (tm)
                {
                    _traveler.Destination = new MissionBookmarkDestination(Cache.Instance.GetMissionBookmark(Cache.Instance.AgentId, "Encounter"));
                }

                if (Cache.Instance.PriorityTargets.Any(pt => pt != null && pt.IsValid))
                {
                    Logging.Log("GotoMission: Priority targets found, engaging!");
                    _combat.ProcessState();
                }

                _traveler.ProcessState();
                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Traveler.State = " + _traveler.State);
                }

                if (_traveler.State == TravelerState.AtDestination)
                {
                    State = QuestorState.ExecuteMission;

                    // Seeing as we just warped to the mission, start the mission controller
                    _missionController.State = MissionControllerState.Start;
                    _combat.State            = CombatState.CheckTargets;

                    _traveler.Destination = null;
                }
                break;

            case QuestorState.CombatHelper:
                _combat.ProcessState();
                _drones.ProcessState();
                _salvage.ProcessState();
                break;

            case QuestorState.ExecuteMission:
                watch.Reset();
                watch.Start();
                _combat.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("Combat.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Combat.State = " + _combat.State);
                }

                watch.Reset();
                watch.Start();
                _drones.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("Drones.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Drones.State = " + _drones.State);
                }

                watch.Reset();
                watch.Start();
                _salvage.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("Salvage.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Salvage.State = " + _salvage.State);
                }

                watch.Reset();
                watch.Start();
                _missionController.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("MissionController.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("MissionController.State = " + _missionController.State);
                }

                // If we are out of ammo, return to base, the mission will fail to complete and the bot will reload the ship
                // and try the mission again
                if (_combat.State == CombatState.OutOfAmmo)
                {
                    Logging.Log("Combat: Out of Ammo!");
                    State = QuestorState.GotoBase;

                    // Clear looted containers
                    Cache.Instance.LootedContainers.Clear();
                }

                if (_missionController.State == MissionControllerState.Done)
                {
                    State = QuestorState.GotoBase;

                    // Clear looted containers
                    Cache.Instance.LootedContainers.Clear();
                }

                // If in error state, just go home and stop the bot
                if (_missionController.State == MissionControllerState.Error)
                {
                    Logging.Log("MissionController: Error");
                    State = QuestorState.GotoBase;

                    // Clear looted containers
                    Cache.Instance.LootedContainers.Clear();
                }
                break;

            case QuestorState.GotoBase:
                var baseDestination = _traveler.Destination as StationDestination;
                if (baseDestination == null || baseDestination.StationId != Cache.Instance.Agent.StationId)
                {
                    _traveler.Destination = new StationDestination(Cache.Instance.Agent.SolarSystemId, Cache.Instance.Agent.StationId, Cache.Instance.DirectEve.GetLocationName(Cache.Instance.Agent.StationId));
                }

                if (Cache.Instance.PriorityTargets.Any(pt => pt != null && pt.IsValid))
                {
                    Logging.Log("GotoBase: Priority targets found, engaging!");
                    _combat.ProcessState();
                }

                _traveler.ProcessState();
                if (_traveler.State == TravelerState.AtDestination)
                {
                    mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId);
                    if (_missionController.State == MissionControllerState.Error)
                    {
                        State = QuestorState.Error;
                    }
                    else if (_combat.State != CombatState.OutOfAmmo && mission != null && mission.State == (int)MissionState.Accepted)
                    {
                        State = QuestorState.CompleteMission;
                    }
                    else
                    {
                        State = QuestorState.UnloadLoot;
                    }

                    _traveler.Destination = null;
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Traveler.State = " + _traveler.State);
                }
                break;

            case QuestorState.CompleteMission:
                if (_agentInteraction.State == AgentInteractionState.Idle)
                {
                    // Lost drone statistics
                    // (inelegantly located here so as to avoid the necessity to switch to a combat ship after salvaging)
                    if (Settings.Instance.UseDrones)
                    {
                        var droneBay = Cache.Instance.DirectEve.GetShipsDroneBay();
                        if (droneBay.Window == null)
                        {
                            Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.OpenDroneBayOfActiveShip);
                            break;
                        }
                        if (!droneBay.IsReady)
                        {
                            break;
                        }
                        if (Cache.Instance.InvTypesById.ContainsKey(Settings.Instance.DroneTypeId))
                        {
                            var drone = Cache.Instance.InvTypesById[Settings.Instance.DroneTypeId];
                            LostDrones = (int)Math.Floor((droneBay.Capacity - droneBay.UsedCapacity) / drone.Volume);
                            Logging.Log("DroneStats: Logging the number of lost drones: " + LostDrones.ToString());
                        }
                        else
                        {
                            Logging.Log("DroneStats: Couldn't find the drone TypeID specified in the settings.xml; this shouldn't happen!");
                        }
                    }
                    // Lost drone statistics stuff ends here


                    // Ammo Consumption statistics
                    // Is cargo open?
                    var cargoship = Cache.Instance.DirectEve.GetShipsCargo();
                    if (cargoship.Window == null)
                    {
                        // No, command it to open
                        Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.OpenCargoHoldOfActiveShip);
                        break;
                    }

                    if (!cargoship.IsReady)
                    {
                        break;
                    }

                    var correctAmmo1 = Settings.Instance.Ammo.Where(a => a.DamageType == Cache.Instance.DamageType);
                    var AmmoCargo    = cargoship.Items.Where(i => correctAmmo1.Any(a => a.TypeId == i.TypeId));
                    foreach (var item in AmmoCargo)
                    {
                        var Ammo1    = Settings.Instance.Ammo.Where(a => a.TypeId == item.TypeId).FirstOrDefault();
                        var AmmoType = Cache.Instance.InvTypesById[item.TypeId];
                        AmmoConsumption = (Ammo1.Quantity - item.Quantity);
                        AmmoValue       = (AmmoType.MedianBuy ?? 0) * AmmoConsumption;
                    }

                    Logging.Log("AgentInteraction: Start Conversation [Complete Mission]");

                    _agentInteraction.State   = AgentInteractionState.StartConversation;
                    _agentInteraction.Purpose = AgentInteractionPurpose.CompleteMission;
                }

                _agentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State = " + _agentInteraction.State);
                }

                if (_agentInteraction.State == AgentInteractionState.Done)
                {
                    _agentInteraction.State = AgentInteractionState.Idle;
                    State = QuestorState.UnloadLoot;
                }
                break;

            case QuestorState.UnloadLoot:
                if (_unloadLoot.State == UnloadLootState.Idle)
                {
                    Logging.Log("UnloadLoot: Begin");
                    _unloadLoot.State = UnloadLootState.Begin;
                }

                _unloadLoot.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("UnloadLoot.State = " + _unloadLoot.State);
                }

                if (_unloadLoot.State == UnloadLootState.Done)
                {
                    Logging.Log("UnloadLoot: Done");

                    _unloadLoot.State = UnloadLootState.Idle;

                    // Update total loot value
                    LootValue += _unloadLoot.LootValue;

                    mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId);
                    if (_combat.State != CombatState.OutOfAmmo && Settings.Instance.AfterMissionSalvaging && Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ").Count > 0 && (mission == null || mission.State == (int)MissionState.Offered))
                    {
                        State = QuestorState.BeginAfterMissionSalvaging;
                    }
                    else if (_combat.State == CombatState.OutOfAmmo)
                    {
                        State = QuestorState.Start;
                    }
                    else
                    {
                        State = QuestorState.Idle;
                    }
                }
                break;

            case QuestorState.BeginAfterMissionSalvaging:
                _GatesPresent = false;
                if (_arm.State == ArmState.Idle)
                {
                    _arm.State = ArmState.SwitchToSalvageShip;
                }

                _arm.ProcessState();
                if (_arm.State == ArmState.Done)
                {
                    _arm.State = ArmState.Idle;

                    var bookmark = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ").OrderBy(b => b.CreatedOn).FirstOrDefault();
                    if (bookmark == null)
                    {
                        State = QuestorState.Idle;
                        break;
                    }

                    State = QuestorState.GotoSalvageBookmark;
                    _traveler.Destination = new BookmarkDestination(bookmark);
                }
                break;

            case QuestorState.GotoSalvageBookmark:
                _traveler.ProcessState();
                string target  = "Acceleration Gate";
                var    targets = Cache.Instance.EntitiesByName(target);
                if (_traveler.State == TravelerState.AtDestination || GateInSalvage())
                {
                    State = QuestorState.Salvage;
                    _traveler.Destination = null;
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Traveler.State = " + _traveler.State);
                }
                break;

            case QuestorState.Salvage:
                var cargo = Cache.Instance.DirectEve.GetShipsCargo();

                // Is our cargo window open?
                if (cargo.Window == null)
                {
                    // No, command it to open
                    Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.OpenCargoHoldOfActiveShip);
                    break;
                }

                if (Settings.Instance.UnloadLootAtStation && cargo.IsReady && (cargo.Capacity - cargo.UsedCapacity) < 100)
                {
                    Logging.Log("Salvage: We are full, goto base to unload");
                    State = QuestorState.GotoBase;
                    break;
                }

                if (Cache.Instance.UnlootedContainers.Count() == 0)
                {
                    Logging.Log("Salvage: Finished salvaging the room");

                    bool GatesInRoom = GateInSalvage();
                    var  bookmarks   = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ");
                    do
                    {
                        var bookmark = bookmarks.FirstOrDefault(b => Cache.Instance.DistanceFromMe(b.X ?? 0, b.Y ?? 0, b.Z ?? 0) < 250000);
                        if (!GatesInRoom && _GatesPresent)     // if there were gates, but we've gone through them all, delete all bookmarks
                        {
                            bookmark = bookmarks.FirstOrDefault();
                        }
                        else if (GatesInRoom)
                        {
                            break;
                        }
                        if (bookmark == null)
                        {
                            break;
                        }

                        bookmark.Delete();
                        bookmarks.Remove(bookmark);
                    } while (true);

                    if (bookmarks.Count == 0 && !GatesInRoom)
                    {
                        Logging.Log("Salvage: We have salvaged all bookmarks, goto base");
                        State = QuestorState.GotoBase;
                    }
                    else
                    {
                        if (!GatesInRoom)
                        {
                            Logging.Log("Salvage: Goto the next salvage bookmark");

                            State = QuestorState.GotoSalvageBookmark;
                            _traveler.Destination = new BookmarkDestination(bookmarks.OrderBy(b => b.CreatedOn).First());
                        }
                        else if (Settings.Instance.UseGatesInSalvage)
                        {
                            Logging.Log("Salvage: Acceleration gate found - moving to next pocket");
                            State = QuestorState.SalvageUseGate;
                        }
                        else
                        {
                            Logging.Log("Salvage: Acceleration gate found, useGatesInSalvage set to false - Returning to base");
                            State = QuestorState.GotoBase;
                            _traveler.Destination = null;
                        }
                    }
                    break;
                }

                var closestWreck = Cache.Instance.UnlootedContainers.First();
                if (closestWreck.Distance > 2500 && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closestWreck.Id))
                {
                    if (closestWreck.Distance > 150000)
                    {
                        closestWreck.WarpTo();
                    }
                    else
                    {
                        closestWreck.Approach();
                    }
                }
                else if (closestWreck.Distance <= 2500 && Cache.Instance.Approaching != null)
                {
                    Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdStopShip);
                }

                try
                {
                    // Overwrite settings, as the 'normal' settings do not apply
                    _salvage.MaximumWreckTargets  = Math.Min(Cache.Instance.DirectEve.ActiveShip.MaxLockedTargets, Cache.Instance.DirectEve.Me.MaxLockedTargets);
                    _salvage.ReserveCargoCapacity = 80;
                    _salvage.LootEverything       = true;
                    _salvage.ProcessState();
                }
                finally
                {
                    ApplySettings();
                }
                break;


            case QuestorState.SalvageUseGate:

                target = "Acceleration Gate";

                targets = Cache.Instance.EntitiesByName(target);
                if (targets == null || targets.Count() == 0)
                {
                    State = QuestorState.GotoSalvageBookmark;
                    return;
                }

                _lastX = Cache.Instance.DirectEve.ActiveShip.Entity.X;
                _lastY = Cache.Instance.DirectEve.ActiveShip.Entity.Y;
                _lastZ = Cache.Instance.DirectEve.ActiveShip.Entity.Z;

                var closest = targets.OrderBy(t => t.Distance).First();
                if (closest.Distance < 2500)
                {
                    Logging.Log("Salvage: Acceleration gate found - GroupID=" + closest.GroupId);

                    // Activate it and move to the next Pocket
                    closest.Activate();

                    // Do not change actions, if NextPocket gets a timeout (>2 mins) then it reverts to the last action
                    Logging.Log("Salvage: Activate [" + closest.Name + "] and change state to 'NextPocket'");

                    State      = QuestorState.SalvageNextPocket;
                    _lastPulse = DateTime.Now;
                }
                else if (closest.Distance < 150000)
                {
                    // Move to the target
                    if (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closest.Id)
                    {
                        Logging.Log("Salvage: Approaching target [" + closest.Name + "][" + closest.Id + "]");
                        closest.Approach();
                    }
                }
                else
                {
                    // Probably never happens
                    closest.WarpTo();
                }
                _lastPulse = DateTime.Now.AddSeconds(10);
                break;

            case QuestorState.SalvageNextPocket:
                var distance = Cache.Instance.DistanceFromMe(_lastX, _lastY, _lastZ);
                if (distance > 100000)
                {
                    Logging.Log("Salvage: We've moved to the next Pocket [" + distance + "]");

                    State = QuestorState.Salvage;
                }
                else if (DateTime.Now.Subtract(_lastPulse).TotalMinutes > 2)
                {
                    Logging.Log("Salvage: We've timed out, retry last action");

                    // We have reached a timeout, revert to ExecutePocketActions (e.g. most likely Activate)
                    State = QuestorState.SalvageUseGate;
                }
                break;

            case QuestorState.Storyline:
                _storyline.ProcessState();

                if (_storyline.State == StorylineState.Done)
                {
                    Logging.Log("Questor: We have completed the storyline, returning to base");

                    State = QuestorState.GotoBase;
                    break;
                }
                break;

            case QuestorState.Traveler:
                var destination = Cache.Instance.DirectEve.Navigation.GetDestinationPath();
                if (destination == null || destination.Count == 0)
                {
                    // should never happen, but still...
                    Logging.Log("Traveler: No destination?");
                    State = QuestorState.Error;
                }
                else
                if (destination.Count == 1 && destination.First() == 0)
                {
                    destination[0] = Cache.Instance.DirectEve.Session.SolarSystemId ?? -1;
                }
                if (_traveler.Destination == null || _traveler.Destination.SolarSystemId != destination.Last())
                {
                    var bookmarks = Cache.Instance.DirectEve.Bookmarks.Where(b => b.LocationId == destination.Last());
                    if (bookmarks != null && bookmarks.Count() > 0)
                    {
                        _traveler.Destination = new BookmarkDestination(bookmarks.OrderBy(b => b.CreatedOn).First());
                    }
                    else
                    {
                        Logging.Log("Traveler: Destination: [" + Cache.Instance.DirectEve.Navigation.GetLocation(destination.Last()).Name + "]");
                        _traveler.Destination = new SolarSystemDestination(destination.Last());
                    }
                }
                else
                {
                    _traveler.ProcessState();
                    if (_traveler.State == TravelerState.AtDestination)
                    {
                        if (_missionController.State == MissionControllerState.Error)
                        {
                            Logging.Log("Questor stopped: an error has occured");
                            State = QuestorState.Error;
                        }
                        else if (Cache.Instance.InSpace)
                        {
                            Logging.Log("Traveler: Arrived at destination (in space, Questor stopped)");
                            State = QuestorState.Error;
                        }
                        else
                        {
                            Logging.Log("Traveler: Arrived at destination");
                            State = QuestorState.Idle;
                        }
                    }
                }
                break;
            }
        }
Exemple #4
0
        public void ProcessState()
        {
            switch (State)
            {
            case StorylineState.Idle:
                IdleState();
                break;

            case StorylineState.Arm:
                State = _storyline.Arm(this);
                break;

            case StorylineState.GotoAgent:
                GotoAgent(StorylineState.PreAcceptMission);
                break;

            case StorylineState.PreAcceptMission:
                State = _storyline.PreAcceptMission(this);
                break;

            case StorylineState.AcceptMission:
                if (_agentInteraction.State == AgentInteractionState.Idle)
                {
                    Logging.Log("AgentInteraction: Start conversation [Start Mission]");

                    _agentInteraction.State       = AgentInteractionState.StartConversation;
                    _agentInteraction.Purpose     = AgentInteractionPurpose.StartMission;
                    _agentInteraction.AgentId     = AgentId;
                    _agentInteraction.ForceAccept = true;
                }

                _agentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State = " + _agentInteraction.State);
                }

                if (_agentInteraction.State == AgentInteractionState.Done)
                {
                    _agentInteraction.State = AgentInteractionState.Idle;
                    State = StorylineState.ExecuteMission;
                }
                break;

            case StorylineState.ExecuteMission:
                State = _storyline.ExecuteMission(this);
                break;

            case StorylineState.ReturnToAgent:
                GotoAgent(StorylineState.CompleteMission);
                break;

            case StorylineState.CompleteMission:
                if (_agentInteraction.State == AgentInteractionState.Idle)
                {
                    Logging.Log("AgentInteraction: Start Conversation [Complete Mission]");

                    _agentInteraction.State   = AgentInteractionState.StartConversation;
                    _agentInteraction.Purpose = AgentInteractionPurpose.CompleteMission;
                }

                _agentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State = " + _agentInteraction.State);
                }

                if (_agentInteraction.State == AgentInteractionState.Done)
                {
                    _agentInteraction.State = AgentInteractionState.Idle;
                    State = StorylineState.BringSpoilsOfWar;
                }
                break;

            case StorylineState.BringSpoilsOfWar:
                BringSpoilsOfWar();
                break;

            case StorylineState.BlacklistAgent:
                _agentBlacklist.Add(AgentId);
                State = StorylineState.Done;
                break;

            case StorylineState.Done:
                break;
            }
        }
Exemple #5
0
        private void OnFrame(object sender, EventArgs e)
        {
            var watch = new Stopwatch();

            // Only pulse state changes every 1.5s
            if (DateTime.Now.Subtract(_lastPulse).TotalMilliseconds < 1500)
            {
                return;
            }
            _lastPulse = DateTime.Now;

            // Session is not ready yet, do not continue
            if (!Cache.Instance.DirectEve.Session.IsReady)
            {
                return;
            }

            // We are not in space or station, don't do shit yet!
            if (!Cache.Instance.InSpace && !Cache.Instance.InStation)
            {
                return;
            }

            // New frame, invalidate old cache
            Cache.Instance.InvalidateCache();

            // Update settings (settings only load if character name changed)
            Settings.Instance.LoadSettings();
            CharacterName = Cache.Instance.DirectEve.Me.Name;

            // Check 3D rendering
            if (Cache.Instance.DirectEve.Session.IsInSpace && Cache.Instance.DirectEve.Rendering3D != !Disable3D)
            {
                Cache.Instance.DirectEve.Rendering3D = !Disable3D;
            }

            // Invalid settings, quit while we're ahead
            if (!ValidSettings)
            {
                if (DateTime.Now.Subtract(_lastAction).TotalSeconds < 15)
                {
                    ValidateSettings();
                    _lastAction = DateTime.Now;
                }
                return;
            }

            foreach (var window in Cache.Instance.Windows)
            {
                // Telecom messages are generally mission info messages
                if (window.Name == "telecom")
                {
                    Logging.Log("Questor: Closing telecom message...");
                    Logging.Log("Questor: Content of telecom window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]");
                    window.Close();
                }

                // Modal windows must be closed
                // But lets only close known modal windows
                if (window.Name == "modal")
                {
                    bool close = false;
                    if (!string.IsNullOrEmpty(window.Html))
                    {
                        // Server going down
                        close |= window.Html.Contains("Please make sure your characters are out of harms way");
                        // In space "shit"
                        close |= window.Html.Contains("Item cannot be moved back to a loot container.");
                        close |= window.Html.Contains("you do not have the cargo space");
                        close |= window.Html.Contains("cargo units would be required to complete this operation.");
                        close |= window.Html.Contains("You are too far away from the acceleration gate to activate it!");
                        close |= window.Html.Contains("maximum distance is 2500 meters");
                        // Stupid warning, lets see if we can find it
                        close |= window.Html.Contains("Do you wish to proceed with this dangerous action?");
                        // Yes we know the mission isnt complete, Questor will just redo the mission
                        close |= window.Html.Contains("Please check your mission journal for further information.");
                        // Lag :/
                        close |= window.Html.Contains("The Zbikoki's Hacker Card");
                        close |= window.Html.Contains(" units free.");
                    }

                    if (close)
                    {
                        Logging.Log("Questor: Closing modal window...");
                        Logging.Log("Questor: Content of modal window (HTML): [" + (window.Html ?? string.Empty).Replace("\n", "").Replace("\r", "") + "]");
                        window.Close();
                    }
                }
            }

            // We always check our defense state if we're in space, regardless of questor state
            // We also always check panic
            if (Cache.Instance.InSpace)
            {
                watch.Reset();
                watch.Start();
                _defense.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("Defense.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }
            }

            // Defense is more important then pause, rest (even panic) isnt!
            if (Paused)
            {
                return;
            }

            // Panic always runs, not just in space
            watch.Reset();
            watch.Start();
            _panic.InMission = State == QuestorState.ExecuteMission;
            if (State == QuestorState.Storyline && _storyline.State == StorylineState.ExecuteMission)
            {
                _panic.InMission |= _storyline.StorylineHandler is GenericCombatStoryline && (_storyline.StorylineHandler as GenericCombatStoryline).State == GenericCombatStorylineState.ExecuteMission;
            }
            _panic.ProcessState();
            watch.Stop();

            if (Settings.Instance.DebugPerformance)
            {
                Logging.Log("Panic.ProcessState took " + watch.ElapsedMilliseconds + "ms");
            }

            if (_panic.State == PanicState.Panic || _panic.State == PanicState.Panicking)
            {
                // If Panic is in panic state, questor is in panic state :)
                State = State == QuestorState.Storyline ? QuestorState.StorylinePanic : QuestorState.Panic;

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("State = " + State);
                }
            }
            else if (_panic.State == PanicState.Resume)
            {
                // Reset panic state
                _panic.State = PanicState.Normal;

                // Ugly storyline resume hack
                if (State == QuestorState.StorylinePanic)
                {
                    State = QuestorState.Storyline;

                    if (_storyline.StorylineHandler is GenericCombatStoryline)
                    {
                        (_storyline.StorylineHandler as GenericCombatStoryline).State = GenericCombatStorylineState.GotoMission;
                    }
                }
                else
                {
                    // Head back to the mission
                    _traveler.State = TravelerState.Idle;
                    State           = QuestorState.GotoMission;
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("State = " + State);
                }
            }

            if (Settings.Instance.DebugStates)
            {
                Logging.Log("Panic.State = " + _panic.State);
            }

            // When in warp there's nothing we can do, so ignore everything
            if (Cache.Instance.InWarp)
            {
                return;
            }

            DirectAgentMission mission;

            switch (State)
            {
            case QuestorState.Idle:
                if (Cache.Instance.InSpace)
                {
                    // Questor doesnt handle inspace-starts very well, head back to base to try again
                    Logging.Log("Questor: Started questor while in space, heading back to base in 15 seconds");

                    _lastAction = DateTime.Now;
                    State       = QuestorState.DelayedGotoBase;
                    break;
                }

                mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId);
                if (!string.IsNullOrEmpty(Mission) && (mission == null || mission.Name != Mission || mission.State != (int)MissionState.Accepted))
                {
                    // Do not save statistics if loyalty points == -1
                    // Seeing as we completed a mission, we will have loyalty points for this agent
                    if (Cache.Instance.Agent.LoyaltyPoints == -1)
                    {
                        return;
                    }

                    // Get the path
                    var path     = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
                    var filename = Path.Combine(path, Cache.Instance.FilterPath(CharacterName) + ".statistics.log");

                    // Write the header
                    if (!File.Exists(filename))
                    {
                        File.AppendAllText(filename, "Mission;Time;Isk;Loot;LP;\r\n");
                    }

                    // Build the line
                    var line = Mission + ";";
                    line += ((int)DateTime.Now.Subtract(Started).TotalMinutes) + ";";
                    line += ((int)(Cache.Instance.DirectEve.Me.Wealth - Wealth)) + ";";
                    line += ((int)LootValue) + ";";
                    line += (Cache.Instance.Agent.LoyaltyPoints - LoyaltyPoints) + ";\r\n";

                    // The mission is finished
                    File.AppendAllText(filename, line);

                    // Disable next log line
                    Mission = null;
                }

                if (AutoStart)
                {
                    // Dont start missions hour before downtime
                    if (DateTime.UtcNow.Hour == 10)
                    {
                        break;
                    }

                    // Dont start missions in downtime
                    if (DateTime.UtcNow.Hour == 11 && DateTime.UtcNow.Minute < 15)
                    {
                        break;
                    }

                    if (Settings.Instance.RandomDelay > 0 || Settings.Instance.MinimumDelay > 0)
                    {
                        _randomDelay = (Settings.Instance.RandomDelay > 0 ? _random.Next(Settings.Instance.RandomDelay) : 0) + Settings.Instance.MinimumDelay;
                        _lastAction  = DateTime.Now;

                        State = QuestorState.DelayedStart;

                        Logging.Log("Questor: Random mission start delay of [" + _randomDelay + "] seconds");
                    }
                    else
                    {
                        State = QuestorState.Start;
                    }
                }
                else if (ExitWhenIdle)
                {
                    LavishScript.ExecuteCommand("exit");
                }
                break;

            case QuestorState.DelayedStart:
                if (DateTime.Now.Subtract(_lastAction).TotalSeconds < _randomDelay)
                {
                    break;
                }

                State = QuestorState.Start;
                break;


            case QuestorState.DelayedGotoBase:
                if (DateTime.Now.Subtract(_lastAction).TotalSeconds < 15)
                {
                    break;
                }

                Logging.Log("Questor: Heading back to base");
                State = QuestorState.GotoBase;
                break;

            case QuestorState.Start:
                if (_agentInteraction.State == AgentInteractionState.Idle)
                {
                    if (Settings.Instance.EnableStorylines && _storyline.HasStoryline())
                    {
                        Logging.Log("Questor: Storyline detected, doing storyline.");

                        _storyline.Reset();
                        State = QuestorState.Storyline;
                        break;
                    }

                    Logging.Log("AgentInteraction: Start conversation [Start Mission]");

                    _agentInteraction.State   = AgentInteractionState.StartConversation;
                    _agentInteraction.Purpose = AgentInteractionPurpose.StartMission;

                    // Update statistic values
                    Wealth        = Cache.Instance.DirectEve.Me.Wealth;
                    LootValue     = 0;
                    LoyaltyPoints = Cache.Instance.Agent.LoyaltyPoints;
                    Started       = DateTime.Now;
                    Mission       = string.Empty;
                }

                _agentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State = " + _agentInteraction.State);
                }

                if (_agentInteraction.State == AgentInteractionState.Done)
                {
                    mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId);
                    if (mission != null)
                    {
                        // Update loyalty points again (the first time might return -1)
                        LoyaltyPoints = Cache.Instance.Agent.LoyaltyPoints;
                        Mission       = mission.Name;
                    }

                    _agentInteraction.State = AgentInteractionState.Idle;
                    State = QuestorState.Arm;
                }
                break;

            case QuestorState.Arm:
                if (_arm.State == ArmState.Idle)
                {
                    Logging.Log("Arm: Begin");
                    _arm.State = ArmState.Begin;

                    // Load right ammo based on mission
                    _arm.AmmoToLoad.Clear();
                    _arm.AmmoToLoad.AddRange(_agentInteraction.AmmoToLoad);
                }

                _arm.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Arm.State = " + _arm.State);
                }

                if (_arm.State == ArmState.Done)
                {
                    _arm.State = ArmState.Idle;
                    State      = QuestorState.GotoMission;
                }
                break;

            case QuestorState.GotoMission:
                var missionDestination = _traveler.Destination as MissionBookmarkDestination;
                if (missionDestination == null || missionDestination.AgentId != Cache.Instance.AgentId)     // We assume that this will always work "correctly" (tm)
                {
                    _traveler.Destination = new MissionBookmarkDestination(Cache.Instance.GetMissionBookmark(Cache.Instance.AgentId, "Encounter"));
                }

                if (Cache.Instance.PriorityTargets.Any(pt => pt != null && pt.IsValid))
                {
                    Logging.Log("GotoMission: Priority targets found, engaging!");
                    _combat.ProcessState();
                }

                _traveler.ProcessState();
                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Traveler.State = " + _traveler.State);
                }

                if (_traveler.State == TravelerState.AtDestination)
                {
                    State = QuestorState.ExecuteMission;

                    // Seeing as we just warped to the mission, start the mission controller
                    _missionController.State = MissionControllerState.Start;
                    _combat.State            = CombatState.CheckTargets;

                    _traveler.Destination = null;
                }
                break;

            case QuestorState.CombatHelper:
                _combat.ProcessState();
                _drones.ProcessState();
                _salvage.ProcessState();
                break;

            case QuestorState.ExecuteMission:
                watch.Reset();
                watch.Start();
                _combat.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("Combat.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Combat.State = " + _combat.State);
                }

                watch.Reset();
                watch.Start();
                _drones.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("Drones.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Drones.State = " + _drones.State);
                }

                watch.Reset();
                watch.Start();
                _salvage.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("Salvage.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Salvage.State = " + _salvage.State);
                }

                watch.Reset();
                watch.Start();
                _missionController.ProcessState();
                watch.Stop();

                if (Settings.Instance.DebugPerformance)
                {
                    Logging.Log("MissionController.ProcessState took " + watch.ElapsedMilliseconds + "ms");
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("MissionController.State = " + _missionController.State);
                }

                // If we are out of ammo, return to base, the mission will fail to complete and the bot will reload the ship
                // and try the mission again
                if (_combat.State == CombatState.OutOfAmmo)
                {
                    Logging.Log("Combat: Out of Ammo!");
                    State = QuestorState.GotoBase;

                    // Clear looted containers
                    Cache.Instance.LootedContainers.Clear();
                }

                if (_missionController.State == MissionControllerState.Done)
                {
                    State = QuestorState.GotoBase;

                    // Clear looted containers
                    Cache.Instance.LootedContainers.Clear();
                }

                // If in error state, just go home and stop the bot
                if (_missionController.State == MissionControllerState.Error)
                {
                    Logging.Log("MissionController: Error");
                    State = QuestorState.GotoBase;

                    // Clear looted containers
                    Cache.Instance.LootedContainers.Clear();
                }
                break;

            case QuestorState.GotoBase:
                var baseDestination = _traveler.Destination as StationDestination;
                if (baseDestination == null || baseDestination.StationId != Cache.Instance.Agent.StationId)
                {
                    _traveler.Destination = new StationDestination(Cache.Instance.Agent.SolarSystemId, Cache.Instance.Agent.StationId, Cache.Instance.DirectEve.GetLocationName(Cache.Instance.Agent.StationId));
                }

                if (Cache.Instance.PriorityTargets.Any(pt => pt != null && pt.IsValid))
                {
                    Logging.Log("GotoBase: Priority targets found, engaging!");
                    _combat.ProcessState();
                }

                _traveler.ProcessState();
                if (_traveler.State == TravelerState.AtDestination)
                {
                    mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId);
                    if (_missionController.State == MissionControllerState.Error)
                    {
                        State = QuestorState.Error;
                    }
                    else if (_combat.State != CombatState.OutOfAmmo && mission != null && mission.State == (int)MissionState.Accepted)
                    {
                        State = QuestorState.CompleteMission;
                    }
                    else
                    {
                        State = QuestorState.UnloadLoot;
                    }

                    _traveler.Destination = null;
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Traveler.State = " + _traveler.State);
                }
                break;

            case QuestorState.CompleteMission:
                if (_agentInteraction.State == AgentInteractionState.Idle)
                {
                    Logging.Log("AgentInteraction: Start Conversation [Complete Mission]");

                    _agentInteraction.State   = AgentInteractionState.StartConversation;
                    _agentInteraction.Purpose = AgentInteractionPurpose.CompleteMission;
                }

                _agentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State = " + _agentInteraction.State);
                }

                if (_agentInteraction.State == AgentInteractionState.Done)
                {
                    _agentInteraction.State = AgentInteractionState.Idle;
                    State = QuestorState.UnloadLoot;
                }
                break;

            case QuestorState.UnloadLoot:
                if (_unloadLoot.State == UnloadLootState.Idle)
                {
                    Logging.Log("UnloadLoot: Begin");
                    _unloadLoot.State = UnloadLootState.Begin;
                }

                _unloadLoot.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("UnloadLoot.State = " + _unloadLoot.State);
                }

                if (_unloadLoot.State == UnloadLootState.Done)
                {
                    Logging.Log("UnloadLoot: Done");

                    _unloadLoot.State = UnloadLootState.Idle;

                    // Update total loot value
                    LootValue += _unloadLoot.LootValue;

                    mission = Cache.Instance.GetAgentMission(Cache.Instance.AgentId);
                    if (_combat.State != CombatState.OutOfAmmo && Settings.Instance.AfterMissionSalvaging && Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ").Count > 0 && (mission == null || mission.State == (int)MissionState.Offered))
                    {
                        State = QuestorState.BeginAfterMissionSalvaging;
                    }
                    else if (_combat.State == CombatState.OutOfAmmo)
                    {
                        State = QuestorState.Start;
                    }
                    else
                    {
                        State = QuestorState.Idle;
                    }
                }
                break;

            case QuestorState.BeginAfterMissionSalvaging:
                if (_arm.State == ArmState.Idle)
                {
                    _arm.State = ArmState.SwitchToSalvageShip;
                }

                _arm.ProcessState();
                if (_arm.State == ArmState.Done)
                {
                    _arm.State = ArmState.Idle;

                    var bookmark = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ").OrderBy(b => b.CreatedOn).FirstOrDefault();
                    if (bookmark == null)
                    {
                        State = QuestorState.Idle;
                        break;
                    }

                    State = QuestorState.GotoSalvageBookmark;
                    _traveler.Destination = new BookmarkDestination(bookmark);
                }
                break;

            case QuestorState.GotoSalvageBookmark:
                _traveler.ProcessState();
                if (_traveler.State == TravelerState.AtDestination)
                {
                    State = QuestorState.Salvage;

                    _traveler.Destination = null;
                }

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("Traveler.State = " + _traveler.State);
                }
                break;

            case QuestorState.Salvage:
                var cargo = Cache.Instance.DirectEve.GetShipsCargo();

                // Is our cargo window open?
                if (cargo.Window == null)
                {
                    // No, command it to open
                    Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.OpenCargoHoldOfActiveShip);
                    break;
                }

                if (Settings.Instance.UnloadLootAtStation && cargo.IsReady && (cargo.Capacity - cargo.UsedCapacity) < 100)
                {
                    Logging.Log("Salvage: We are full, goto base to unload");
                    State = QuestorState.GotoBase;
                    break;
                }

                if (Cache.Instance.UnlootedContainers.Count() == 0)
                {
                    Logging.Log("Salvage: Finished salvaging the room");

                    var bookmarks = Cache.Instance.BookmarksByLabel(Settings.Instance.BookmarkPrefix + " ");
                    do
                    {
                        // Remove all bookmarks from address book
                        var bookmark = bookmarks.FirstOrDefault(b => Cache.Instance.DistanceFromMe(b.X ?? 0, b.Y ?? 0, b.Z ?? 0) < 250000);
                        if (bookmark == null)
                        {
                            break;
                        }

                        bookmark.Delete();
                        bookmarks.Remove(bookmark);
                    } while (true);

                    if (bookmarks.Count == 0)
                    {
                        Logging.Log("Salvage: We have salvaged all bookmarks, goto base");
                        State = QuestorState.GotoBase;
                    }
                    else
                    {
                        Logging.Log("Salvage: Goto the next salvage bookmark");
                        _traveler.Destination = new BookmarkDestination(bookmarks.OrderBy(b => b.CreatedOn).First());
                        State = QuestorState.GotoSalvageBookmark;
                    }
                    break;
                }

                var closestWreck = Cache.Instance.UnlootedContainers.First();
                if (closestWreck.Distance > 2500 && (Cache.Instance.Approaching == null || Cache.Instance.Approaching.Id != closestWreck.Id))
                {
                    if (closestWreck.Distance > 150000)
                    {
                        closestWreck.WarpTo();
                    }
                    else
                    {
                        closestWreck.Approach();
                    }
                }
                else if (closestWreck.Distance <= 2500 && Cache.Instance.Approaching != null)
                {
                    Cache.Instance.DirectEve.ExecuteCommand(DirectCmd.CmdStopShip);
                }

                try
                {
                    // Overwrite settings, as the 'normal' settings do not apply
                    _salvage.MaximumWreckTargets  = Math.Min(Cache.Instance.DirectEve.ActiveShip.MaxLockedTargets, Cache.Instance.DirectEve.Me.MaxLockedTargets);
                    _salvage.ReserveCargoCapacity = 80;
                    _salvage.LootEverything       = true;
                    _salvage.ProcessState();
                }
                finally
                {
                    ApplySettings();
                }
                break;

            case QuestorState.Storyline:
                _storyline.ProcessState();

                if (_storyline.State == StorylineState.Done)
                {
                    Logging.Log("Questor: We have completed the storyline, returning to base");

                    State = QuestorState.GotoBase;
                    break;
                }
                break;
            }
        }
Exemple #6
0
        /// <summary>
        ///   Goto the pickup location
        ///   Pickup the item
        ///   Goto drop off location
        ///   Drop the item
        ///   Goto Agent
        ///   Complete mission
        /// </summary>
        /// <returns></returns>
        public void ProcessState()
        {
            if (DateTime.UtcNow < _nextCourierMissionCtrlPulse)
            {
                return;
            }

            if (Settings.Instance.DebugCourierMissions)
            {
                Logging.Log("CourierMissionCtrl", "CourierMissionCtrlState: [" + _States.CurrentCourierMissionCtrlState.ToString() + "]", Logging.Debug);
            }

            switch (_States.CurrentCourierMissionCtrlState)
            {
            case CourierMissionCtrlState.Idle:
                break;

            case CourierMissionCtrlState.GotoPickupLocation:
                if (GotoMissionBookmark(Cache.Instance.AgentId, "Objective (Pick Up)"))
                {
                    _States.CurrentCourierMissionCtrlState = CourierMissionCtrlState.PickupItem;
                    return;
                }
                break;

            case CourierMissionCtrlState.PickupItem:
                if (DateTime.UtcNow < Cache.Instance.LastInSpace.AddSeconds(20))
                {
                    return;
                }

                if (moveItemRetryCounter > 20)
                {
                    Cache.Instance.Paused = true;
                    Logging.Log("CourierMissionCtrl", "MoveItem has tried 20x to Pickup the missionitem and failed. Pausing: please debug the cause of this error", Logging.Red);
                    _States.CurrentCourierMissionCtrlState = CourierMissionCtrlState.Error;
                    return;
                }

                if (MoveItem(true))
                {
                    _States.CurrentCourierMissionCtrlState = CourierMissionCtrlState.GotoDropOffLocation;
                    moveItemRetryCounter = 0;
                    return;
                }
                break;

            case CourierMissionCtrlState.GotoDropOffLocation:
                if (GotoMissionBookmark(Cache.Instance.AgentId, "Objective (Drop Off)"))
                {
                    _States.CurrentCourierMissionCtrlState = CourierMissionCtrlState.DropOffItem;
                    return;
                }
                break;

            case CourierMissionCtrlState.DropOffItem:
                if (moveItemRetryCounter > 20)
                {
                    Cache.Instance.Paused = true;
                    Logging.Log("CourierMissionCtrl", "MoveItem has tried 20x to Dropoff the missionitem and failed. Pausing: please debug the cause of this error", Logging.Red);
                    _States.CurrentCourierMissionCtrlState = CourierMissionCtrlState.Error;
                }

                if (MoveItem(false))
                {
                    _States.CurrentCourierMissionCtrlState = CourierMissionCtrlState.CompleteMission;
                    moveItemRetryCounter = 0;
                    return;
                }
                break;

            case CourierMissionCtrlState.CompleteMission:
                //
                // this state should never be reached in space. if we are in space and in this state we should switch to gotomission
                //
                if (Cache.Instance.InSpace)
                {
                    Logging.Log(_States.CurrentCourierMissionCtrlState.ToString(), "We are in space, how did we get set to this state while in space? Changing state to: GotoBase", Logging.White);
                    _States.CurrentCourierMissionCtrlState = CourierMissionCtrlState.GotoDropOffLocation;
                    return;
                }

                if (_States.CurrentAgentInteractionState == AgentInteractionState.Idle)
                {
                    if (DateTime.UtcNow > Cache.Instance.LastInStation.AddSeconds(5) && Cache.Instance.InStation)     //do not proceed until we have been docked for at least a few seconds
                    {
                        return;
                    }

                    Logging.Log("AgentInteraction", "Start Conversation [Complete Mission]", Logging.White);

                    _States.CurrentAgentInteractionState = AgentInteractionState.StartConversation;
                    AgentInteraction.Purpose             = AgentInteractionPurpose.CompleteMission;
                    return;
                }

                AgentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State is ", _States.CurrentAgentInteractionState.ToString(), Logging.White);
                }

                if (_States.CurrentAgentInteractionState == AgentInteractionState.Done)
                {
                    _States.CurrentAgentInteractionState   = AgentInteractionState.Idle;
                    _States.CurrentCourierMissionCtrlState = CourierMissionCtrlState.Done;
                    return;
                }
                break;

            case CourierMissionCtrlState.Done:
                Logging.Log("CourierMissionCtrl", "Done", Logging.White);
                break;
            }
        }
Exemple #7
0
        public void ProcessState()
        {
            switch (_States.CurrentStorylineState)
            {
            case StorylineState.Idle:
                IdleState();
                break;

            case StorylineState.Arm:

                //Logging.Log("Storyline: Arm");
                _States.CurrentStorylineState = _storyline.Arm(this);
                break;

            case StorylineState.GotoAgent:

                //Logging.Log("Storyline: GotoAgent");
                GotoAgent(StorylineState.PreAcceptMission);
                break;

            case StorylineState.PreAcceptMission:

                //Logging.Log("Storyline: PreAcceptMission-!!");
                _States.CurrentAgentInteractionState = AgentInteractionState.Idle;
                _States.CurrentStorylineState        = _storyline.PreAcceptMission(this);
                break;

            case StorylineState.DeclineMission:
                if (_States.CurrentAgentInteractionState == AgentInteractionState.Idle)
                {
                    Logging.Log("Storyline.AgentInteraction", "Start conversation [Decline Mission]", Logging.Yellow);

                    _States.CurrentAgentInteractionState = AgentInteractionState.StartConversation;
                    AgentInteraction.Purpose             = AgentInteractionPurpose.DeclineMission;
                    AgentInteraction.AgentId             = Cache.Instance.CurrentStorylineAgentId;
                }

                AgentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State is ", _States.CurrentAgentInteractionState.ToString(), Logging.White);
                }

                if (_States.CurrentAgentInteractionState == AgentInteractionState.Done)
                {
                    _States.CurrentAgentInteractionState = AgentInteractionState.Idle;

                    // If there is no mission anymore then we're done (we declined it)
                }
                break;

            case StorylineState.AcceptMission:

                //Logging.Log("Storyline: AcceptMission!!-");
                if (_States.CurrentAgentInteractionState == AgentInteractionState.Idle)
                {
                    Logging.Log("Storyline.AgentInteraction", "Start conversation [Start Mission]", Logging.Yellow);

                    _States.CurrentAgentInteractionState = AgentInteractionState.StartConversation;
                    AgentInteraction.Purpose             = AgentInteractionPurpose.StartMission;
                    AgentInteraction.AgentId             = Cache.Instance.CurrentStorylineAgentId;
                    AgentInteraction.ForceAccept         = true;
                }

                AgentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State is ", _States.CurrentAgentInteractionState.ToString(), Logging.White);
                }

                if (_States.CurrentAgentInteractionState == AgentInteractionState.Done)
                {
                    _States.CurrentAgentInteractionState = AgentInteractionState.Idle;

                    // If there is no mission anymore then we're done (we declined it)
                    _States.CurrentStorylineState = StorylineMission == null ? StorylineState.Done : StorylineState.ExecuteMission;
                }
                break;

            case StorylineState.ExecuteMission:
                _States.CurrentStorylineState = _storyline.ExecuteMission(this);
                break;

            case StorylineState.ReturnToAgent:
                GotoAgent(StorylineState.CompleteMission);
                break;

            case StorylineState.CompleteMission:
                if (_States.CurrentAgentInteractionState == AgentInteractionState.Idle)
                {
                    Logging.Log("AgentInteraction", "Start Conversation [Complete Mission]", Logging.Yellow);

                    _States.CurrentAgentInteractionState = AgentInteractionState.StartConversation;
                    AgentInteraction.Purpose             = AgentInteractionPurpose.CompleteMission;
                }

                AgentInteraction.ProcessState();

                if (Settings.Instance.DebugStates)
                {
                    Logging.Log("AgentInteraction.State is", _States.CurrentAgentInteractionState.ToString(), Logging.White);
                }

                if (_States.CurrentAgentInteractionState == AgentInteractionState.Done)
                {
                    _States.CurrentAgentInteractionState = AgentInteractionState.Idle;
                    _States.CurrentStorylineState        = StorylineState.BringSpoilsOfWar;
                }
                break;

            case StorylineState.BringSpoilsOfWar:
                if (!BringSpoilsOfWar())
                {
                    return;
                }
                break;

            case StorylineState.BlacklistAgent:
                Cache.Instance.AgentBlacklist.Add(Cache.Instance.CurrentStorylineAgentId);
                Logging.Log("Storyline", "BlacklistAgent: The agent that provided us with this storyline mission has been added to the session blacklist", Logging.Orange);
                Reset();
                _States.CurrentCombatMissionBehaviorState = CombatMissionsBehaviorState.GotoBase;
                break;

            case StorylineState.Done:
                if (DateTime.UtcNow > _nextStoryLineAttempt)
                {
                    _States.CurrentStorylineState = StorylineState.Idle;
                }
                break;
            }
        }