예제 #1
0
        /// <summary>
        /// Constructor for a manually edited result from a base result.
        /// </summary>
        /// <param name="result">Associated remapping point, may be null.</param>
        /// <param name="bestScratchpad">The best scratchpad.</param>
        /// <exception cref="System.ArgumentNullException">result</exception>
        public RemappingResult(RemappingResult result, CharacterScratchpad bestScratchpad)
            : this(result?.Point, result?.BaseScratchpad)
        {
            result.ThrowIfNull(nameof(result));

            Skills.AddRange(result.Skills);
            BestScratchpad = bestScratchpad;
        }
예제 #2
0
        /// <summary>
        /// Constructor for a manually edited result from a base result.
        /// </summary>
        /// <param name="result">Associated remapping point, may be null.</param>
        /// <param name="bestScratchpad">The best scratchpad.</param>
        /// <exception cref="System.ArgumentNullException">result</exception>
        public RemappingResult(RemappingResult result, CharacterScratchpad bestScratchpad)
            : this(result?.Point, result?.BaseScratchpad)
        {
            result.ThrowIfNull(nameof(result));

            Skills.AddRange(result.Skills);
            BestScratchpad = bestScratchpad;
        }
        /// <summary>
        /// Initializes a new instance of <see cref="AttributesOptimizerControl"/>.
        /// </summary>
        /// <param name="character">Character information</param>
        /// <param name="plan">Skill plan</param>
        /// <param name="remapping">Optimized remapping</param>
        /// <param name="description"></param>
        public AttributesOptimizerControl(Character character, BasePlan plan,
            RemappingResult remapping, string description)
        {
            InitializeComponent();
            lbMEM.Font = FontFactory.GetFont("Tahoma");
            lbWIL.Font = FontFactory.GetFont("Tahoma");
            lbCHA.Font = FontFactory.GetFont("Tahoma");
            lbPER.Font = FontFactory.GetFont("Tahoma");
            lbINT.Font = FontFactory.GetFont("Tahoma");

            m_character = character;
            m_plan = plan;
            m_remapping = remapping;
            m_description = description;

            UpdateControls(m_character, m_plan, m_remapping, m_description);
        }
예제 #4
0
 /// <summary>
 /// Constructor.
 /// </summary>
 /// <param name="remapping">The remapping.</param>
 public AttributeChangedEventArgs(RemappingResult remapping)
 {
     Remapping = remapping;
 }
        /// <summary>
        /// Recalculating plan and summary page after change of a <see cref="AttributesOptimizerControl"/>.
        /// </summary>
        /// <param name="sender">The source of the event.</param>
        /// <param name="e">The <see cref="AttributeChangedEventArgs"/> instance containing the event data.</param>
        private void AttributesOptimizationControl_AttributeChanged(object sender, AttributeChangedEventArgs e)
        {
            AttributesOptimizerControl control = (AttributesOptimizerControl)sender;

            if (m_strategy == AttributeOptimizationStrategy.RemappingPoints)
            {
                m_remappingDictionary[control] = e.Remapping;
                UpdateSummaryInformation(m_remappingDictionary.Values);
            }

            m_statisticsScratchpad = e.Remapping.BestScratchpad.Clone();
            m_remapping = e.Remapping;

            // Update the plan order's column
            m_planEditor.ShowWithPluggable(this);
        }
        /// <summary>
        /// Creates a <see cref="AttributesOptimizerControl"/> for a given remapping.
        /// </summary>
        /// <param name="remapping">The remapping object to represents.</param>
        /// <returns>The created control.</returns>
        private AttributesOptimizerControl CreateAttributesOptimizationControl(RemappingResult remapping)
        {
            AttributesOptimizerControl control;
            AttributesOptimizerControl ctl = null;
            try
            {
                ctl = new AttributesOptimizerControl(m_character, m_plan, remapping, m_description);
                ctl.AttributeChanged += AttributesOptimizationControl_AttributeChanged;

                // For a manually edited point, we initialize the control with the attributes from the current remapping point
                if (m_strategy == AttributeOptimizationStrategy.ManualRemappingPointEdition &&
                    m_manuallyEditedRemappingPoint.Status == RemappingPointStatus.UpToDate)
                    ctl.UpdateValuesFrom(m_manuallyEditedRemappingPoint);

                control = ctl;
                ctl = null;
            }
            finally
            {
                ctl?.Dispose();
            }

            return control;
        }
        /// <summary>
        /// Adds the tab page for the given remapping
        /// </summary>
        /// <param name="remapping">The remapping.</param>
        /// <param name="tabName">Name of the tab.</param>
        private void AddTabPage(RemappingResult remapping, string tabName)
        {
            AttributesOptimizerControl ctl = CreateAttributesOptimizationControl(remapping);

            if (ctl == null)
                return;

            m_remappingDictionary[ctl] = remapping;

            TabPage tempPage = null;
            try
            {
                tempPage = new TabPage(tabName);
                tempPage.Controls.Add(ctl);

                TabPage page = tempPage;
                tempPage = null;

                tabControl.TabPages.Add(page);
            }
            finally
            {
                tempPage?.Dispose();
            }
        }
 /// <summary>
 /// Adds the list item for the given attribute.
 /// </summary>
 /// <param name="remap"></param>
 /// <param name="group"></param>
 /// <param name="attrib"></param>
 private void AddItemForAttribute(RemappingResult remap, ListViewGroup group,
                                  EveAttribute attrib)
 {
     // Add the list view item for this attribute
     string itemText = RemappingPoint.GetStringForAttribute(attrib, remap.BaseScratchpad, remap.BestScratchpad);
     lvPoints.Items.Add(new ListViewItem(itemText, group));
 }
        /// <summary>
        /// Adds summary information for given remapping.
        /// </summary>
        /// <param name="remap">Remapping object</param>
        /// <param name="lastRemap">Time of previous remapping</param>
        private void AddSummaryForRemapping(RemappingResult remap, ref TimeSpan lastRemap)
        {
            // Create the group
            string text = $"{remap} at {remap.StartTime.ToDescriptiveText(DescriptiveTextOptions.IncludeCommas)}";
            ListViewGroup group = new ListViewGroup(text);
            lvPoints.Groups.Add(group);

            // Check there are at least one year between each remap
            TimeSpan timeSinceLastRemap = remap.StartTime.Subtract(lastRemap);
            if (timeSinceLastRemap < TimeSpan.FromDays(365) && remap.StartTime != TimeSpan.Zero)
            {
                ListViewItem item = lvPoints.Items.Add(
                    new ListViewItem(
                        $"The previous remap point was only {timeSinceLastRemap.ToDescriptiveText(DescriptiveTextOptions.IncludeCommas)} ago.",
                        group));
                item.ForeColor = Color.DarkRed;
            }

            lastRemap = remap.StartTime;

            // Add five items, one for each attribute
            AddItemForAttribute(remap, group, EveAttribute.Intelligence);
            AddItemForAttribute(remap, group, EveAttribute.Perception);
            AddItemForAttribute(remap, group, EveAttribute.Charisma);
            AddItemForAttribute(remap, group, EveAttribute.Willpower);
            AddItemForAttribute(remap, group, EveAttribute.Memory);
        }
        /// <summary>
        /// Reset to remapping with current attributes.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void buttonCurrent_Click(object sender, EventArgs e)
        {
            // Make unoptimized remap
            RemappingResult zeroRemapping = new RemappingResult(m_remapping, m_remapping.BaseScratchpad.Clone());
            zeroRemapping.Update();

            // Update the controls
            UpdateControls(m_character, m_plan, zeroRemapping, m_description);

            // Fires the event
            AttributeChanged?.ThreadSafeInvoke(this, new AttributeChangedEventArgs(zeroRemapping));
        }
        /// <summary>
        /// Updates controls on the form.
        /// </summary>
        /// <param name="remapping">An <see cref="RemappingResult"/> object</param>
        /// <param name="remappingList">List of remappings</param>
        private void UpdateForm(RemappingResult remapping, ICollection<RemappingResult> remappingList)
        {
            // Update the attributes
            if (remapping != null)
            {
                m_statisticsScratchpad = remapping.BestScratchpad.Clone();
                UpdateForRemapping(remapping);
            }
            else
                UpdateForRemappingList(remappingList);

            // Update the plan order's column
            if ((remapping != null) || (remappingList.Count != 0))
                m_planEditor.ShowWithPluggable(this);

            // Hide the throbber and the waiting message
            panelWait.Hide();
        }
        /// <summary>
        /// Starts optimization.
        /// </summary>
        /// <param name="update">if set to <c>true</c> [update].</param>
        /// <exception cref="System.NotImplementedException"></exception>
        private void Run(bool update = false)
        {
            // Compute best scratchpad
            RemappingResult remapping = null;
            ICollection<RemappingResult> remappingList = null;

            switch (m_strategy)
            {
                case AttributeOptimizationStrategy.ManualRemappingPointEdition:
                    m_areRemappingPointsActive = true;
                    if (update)
                    {
                        remapping = m_remapping;
                        m_manuallyEditedRemappingPoint = remapping.Point.Clone();
                    }
                    else
                    {
                        remapping = AttributesOptimizer.GetResultsFromRemappingPoints(m_plan).Single(
                            x => x.Point == m_manuallyEditedRemappingPoint);
                        m_manuallyEditedRemappingPoint = m_manuallyEditedRemappingPoint.Clone();
                        m_remapping = remapping;
                    }
                    remapping.Optimize(TimeSpan.MaxValue);
                    break;
                case AttributeOptimizationStrategy.Character:
                    m_areRemappingPointsActive = false;
                    remapping = AttributesOptimizer.OptimizeFromCharacter(m_character, m_plan);
                    break;
                case AttributeOptimizationStrategy.OneYearPlan:
                    m_areRemappingPointsActive = false;
                    remapping = AttributesOptimizer.OptimizeFromFirstYearOfPlan(m_plan);
                    break;
                case AttributeOptimizationStrategy.RemappingPoints:
                    m_areRemappingPointsActive = true;
                    remappingList = AttributesOptimizer.OptimizeFromPlanAndRemappingPoints(m_plan);
                    break;
                default:
                    throw new NotImplementedException();
            }

            // Update the controls for every attribute
            Dispatcher.Invoke(() => UpdateForm(remapping, remappingList));
        }
        /// <summary>
        /// Updates the controls with the values from the current remapping point.
        /// </summary>
        /// <param name="point"></param>
        /// <exception cref="System.ArgumentNullException">point</exception>
        public void UpdateValuesFrom(RemappingPoint point)
        {
            point.ThrowIfNull(nameof(point));

            // Creates a scratchpad with the base values from the provided point.
            CharacterScratchpad scratchpad = new CharacterScratchpad(m_character.After(m_plan.ChosenImplantSet));
            for (int i = 0; i < 5; i++)
            {
                scratchpad[(EveAttribute)i].Base = point[(EveAttribute)i];
            }

            RemappingResult remapping = new RemappingResult(m_remapping, scratchpad);
            remapping.Update();

            // Update the controls
            UpdateControls(m_character, m_plan, remapping, m_description);

            // Fires the event
            AttributeChanged?.ThreadSafeInvoke(this, new AttributeChangedEventArgs(remapping));
        }
        /// <summary>
        /// Updates bars and labels with given attributes from remapping.
        /// </summary>
        /// <param name="character">Character information</param>
        /// <param name="plan">Skill plan</param>
        /// <param name="remapping">Remapping with attributes and training time</param>
        /// <param name="description"></param>
        private void UpdateControls(Character character, BasePlan plan, RemappingResult remapping,
            string description)
        {
            UpdateAttributeControls(remapping, EveAttribute.Perception, lbPER, pbPERRemappable, pbPERImplants);
            UpdateAttributeControls(remapping, EveAttribute.Willpower, lbWIL, pbWILRemappable, pbWILImplants);
            UpdateAttributeControls(remapping, EveAttribute.Memory, lbMEM, pbMEMRemappable, pbMEMImplants);
            UpdateAttributeControls(remapping, EveAttribute.Intelligence, lbINT, pbINTRemappable, pbINTImplants);
            UpdateAttributeControls(remapping, EveAttribute.Charisma, lbCHA, pbCHARemappable, pbCHAImplants);

            // Update the description label
            labelDescription.Text = description;

            // Update the current time control
            lbCurrentTime.Text = remapping.BaseDuration.ToDescriptiveText(DescriptiveTextOptions.IncludeCommas);

            // Update the optimized time control
            lbOptimizedTime.Text = remapping.BestDuration.ToDescriptiveText(DescriptiveTextOptions.IncludeCommas);

            // Update the time benefit control
            string bestDurationTimeText = remapping.BaseDuration.Subtract(remapping.BestDuration)
                .ToDescriptiveText(DescriptiveTextOptions.IncludeCommas);
            string worseDurationTimeText = remapping.BestDuration.Subtract(remapping.BaseDuration)
                .ToDescriptiveText(DescriptiveTextOptions.IncludeCommas);

            lbGain.ForeColor = remapping.BestDuration < remapping.BaseDuration
                ? Color.DarkGreen
                : remapping.BaseDuration < remapping.BestDuration
                    ? Color.DarkRed
                    : Color.Black;
            lbGain.Text = remapping.BestDuration < remapping.BaseDuration
                ? $"{bestDurationTimeText} better than current"
                : remapping.BaseDuration < remapping.BestDuration
                    ? $"{worseDurationTimeText} slower than current"
                    : "Same as current";

            // A plan may not have a years worth of skills in it,
            // only fair to warn the user
            lbWarning.Visible = remapping.BestDuration < TimeSpan.FromDays(365);

            // Spare points
            Int64 sparePoints = EveConstants.SpareAttributePointsOnRemap;
            for (int i = 0; i < 5; i++)
            {
                sparePoints -= remapping.BestScratchpad[(EveAttribute)i].Base - EveConstants.CharacterBaseAttributePoints;
            }
            pbUnassigned.Value = sparePoints;

            // If the implant set isn't the active one we notify the user
            lblNotice.Visible = plan.ChosenImplantSet != character.ImplantSets.Current;
        }
        /// <summary>
        /// Calculates new remapping from values of controls.
        /// </summary>
        private void Recalculate()
        {
            CharacterScratchpad scratchpad = m_remapping.BaseScratchpad.Clone();
            scratchpad.Memory.Base = pbMEMRemappable.Value + EveConstants.CharacterBaseAttributePoints;
            scratchpad.Charisma.Base = pbCHARemappable.Value + EveConstants.CharacterBaseAttributePoints;
            scratchpad.Willpower.Base = pbWILRemappable.Value + EveConstants.CharacterBaseAttributePoints;
            scratchpad.Perception.Base = pbPERRemappable.Value + EveConstants.CharacterBaseAttributePoints;
            scratchpad.Intelligence.Base = pbINTRemappable.Value + EveConstants.CharacterBaseAttributePoints;

            // Get remapping for provided attributes
            RemappingResult manualRemapping = new RemappingResult(m_remapping,
                                                                  scratchpad);
            manualRemapping.Update();
            UpdateControls(m_character, m_plan, manualRemapping, m_description);

            // Notify the changes
            AttributeChanged?.ThreadSafeInvoke(this, new AttributeChangedEventArgs(manualRemapping));
        }
        /// <summary>
        /// Updates the UI once the computation has been done (for whole plan or character from birth)
        /// </summary>
        /// <param name="remapping"></param>
        private void UpdateForRemapping(RemappingResult remapping)
        {          
            // Create control
            AttributesOptimizerControl ctrl = CreateAttributesOptimizationControl(remapping);
            Controls.Add(ctrl);

            IList<AttributesOptimizerControl> optControls = Controls.OfType<AttributesOptimizerControl>().ToList();

            if (optControls.Count == 1)
                return;

            Controls.RemoveAt(Controls.IndexOf(optControls.First()));
        }
        /// <summary>
        /// Updates bars and labels for specified attribute.
        /// </summary>
        /// <param name="remapping">Attribute remapping</param>
        /// <param name="attrib">Attribute that will be used to update controls</param>
        /// <param name="label">Label control</param>
        /// <param name="pbRemappable">Attribute bar for remappable value</param>
        /// <param name="pbImplants">Attribute bar for implants</param>
        private static void UpdateAttributeControls(RemappingResult remapping,
            EveAttribute attrib,
            Control label,
            AttributeBarControl pbRemappable,
            AttributeBarControl pbImplants)
        {
            // Compute base and effective attributes
            Int64 effectiveAttribute = remapping.BestScratchpad[attrib].EffectiveValue;
            Int64 oldBaseAttribute = remapping.BaseScratchpad[attrib].Base;
            Int64 remappableAttribute = remapping.BestScratchpad[attrib].Base;
            Int64 implantsBonus = remapping.BestScratchpad[attrib].ImplantBonus;

            // Update the label
            label.Text = $"{effectiveAttribute} (new : {remappableAttribute} ; old : {oldBaseAttribute})";

            // Update the bars
            pbRemappable.Value = remappableAttribute - EveConstants.CharacterBaseAttributePoints;
            pbImplants.Value = implantsBonus;
        }