Accuracy Editor Requests and Comments

Started by Bletchley_Geek, August 15, 2018, 05:20:40 PM

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Bletchley_Geek

Thank you very much for the opportunity of taking an early look at the Army Editor.

I am opening a thread with some comments on the Accuracy Editor:


  • The ability to edit every single data point in the accuracy table is good, it allows for very fine control
  • But there are too many slots to be edited by hand, hence I'd suggest to allow to "draw it" allowing the user to click a column and while dragging, draw the slope of the function.
  • In addition, I'd suggest that you can load that data from a CSV file (so you can work on it in a spreadsheet application, for instance)
  • Instead of the percentage of range, which is quite opaque, I'd suggest that the actual range (i.e. percentage times max range) is shown on the display
  • Linked to the data loading comment above, I think that allowing the data to be saved under a name (i.e. "Mauser", "Martini Henry") would be a nother great addition. Editing a custom accuracy curve for every unit on an army looks to me to be a bit much.

Can't wait to play the battles.

Edit: just found the option to do so

Dr D Ezra Sidran

I think those are very good comments and I agree. Andy came up with the idea for the accuracy curve and being able to input from a CSV file is major plus.

Again, thanks to Andy, we have added digital pen support for the Map Editor (this will be the next module released for beta-test). Perhaps it can be added for drawing the Accuracy curve. However, a lot of people don't have digital pens (in fact I had to borrow one from an artist friend just for testing).

Andy ONeill

Plan A was to allow users to draw a curve.
I built a small utility to explore the practicality.
I found it surprisingly difficult to draw a decent curve with a mouse.
In the end I used that to get me started with curves and edited in the app.
We can consider polishing up my utility a bit and offering that separately.

The various files are txt so you could build them in excel or whatever and paste into a txt file.
I don't envisage people using custom curves per unit.

I can fairly easily calculate the range each percentage translates into and add that in the mouseover stuff.

Bletchley_Geek

Thanks for the answers guys.

Am I correct understanding that if I drop new data files in the directory where the premade curves are available, the editor will just load them?

Regarding tracing the curve: with a Surface stylus or a good gaming mouse that allows to adjust sensitivity it is quite easy :)

Mickey3D

Editor is crashing with the following error in the Windows event log:

QuoteApplication : GSBPArmyEditor.exe
Version du Framework : v4.0.30319
Description : le processus a été arrêté en raison d'une exception non gérée.
Informations sur l'exception : System.IndexOutOfRangeException
   à UILib.ArrayToPointCollectionConverter.Convert(System.Object, System.Type, System.Object, System.Globalization.CultureInfo)
   à System.Windows.Data.BindingExpression.TransferValue(System.Object, Boolean)
   à System.Windows.Data.BindingExpression.Activate(System.Object)
   à System.Windows.Data.BindingExpression.AttachToContext(AttachAttempt)
   à System.Windows.Data.BindingExpression.AttachOverride(System.Windows.DependencyObject, System.Windows.DependencyProperty)
   à System.Windows.Data.BindingExpressionBase.OnAttach(System.Windows.DependencyObject, System.Windows.DependencyProperty)
   à System.Windows.StyleHelper.GetInstanceValue(System.Windows.UncommonField`1<System.Collections.Specialized.HybridDictionary[]>, System.Windows.DependencyObject, System.Windows.FrameworkElement, System.Windows.FrameworkContentElement, Int32, System.Windows.DependencyProperty, Int32, System.Windows.EffectiveValueEntry ByRef)
   à System.Windows.FrameworkTemplate.ReceivePropertySet(System.Object, System.Xaml.XamlMember, System.Object, System.Windows.DependencyObject)
   à System.Windows.FrameworkTemplate+<>c__DisplayClass45_0.<LoadOptimizedTemplateContent>b__3(System.Object, System.Windows.Markup.XamlSetValueEventArgs)
   à System.Xaml.XamlObjectWriter.OnSetValue(System.Object, System.Xaml.XamlMember, System.Object)
   à System.Xaml.XamlObjectWriter.Logic_ApplyPropertyValue(MS.Internal.Xaml.Context.ObjectWriterContext, System.Xaml.XamlMember, System.Object, Boolean)
   à System.Xaml.XamlObjectWriter.Logic_DoAssignmentToParentProperty(MS.Internal.Xaml.Context.ObjectWriterContext)
   à System.Xaml.XamlObjectWriter.Logic_AssignProvidedValue(MS.Internal.Xaml.Context.ObjectWriterContext)
   à System.Xaml.XamlObjectWriter.WriteEndObject()
   à System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlReader, System.Xaml.XamlObjectWriter)

Informations sur l'exception : System.Windows.Markup.XamlParseException
   à System.Windows.Markup.XamlReader.RewrapException(System.Exception, System.Xaml.IXamlLineInfo, System.Uri)
   à System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlReader, System.Xaml.XamlObjectWriter)
   à System.Windows.FrameworkTemplate.LoadTemplateXaml(System.Xaml.XamlObjectWriter)
   à System.Windows.FrameworkTemplate.LoadOptimizedTemplateContent(System.Windows.DependencyObject, System.Windows.Markup.IComponentConnector, System.Windows.Markup.IStyleConnector, System.Collections.Generic.List`1<System.Windows.DependencyObject>, System.Windows.UncommonField`1<System.Collections.Hashtable>)
   à System.Windows.FrameworkTemplate.LoadContent(System.Windows.DependencyObject, System.Collections.Generic.List`1<System.Windows.DependencyObject>)
   à System.Windows.StyleHelper.ApplyTemplateContent(System.Windows.UncommonField`1<System.Collections.Specialized.HybridDictionary[]>, System.Windows.DependencyObject, System.Windows.FrameworkElementFactory, Int32, System.Collections.Specialized.HybridDictionary, System.Windows.FrameworkTemplate)
   à System.Windows.FrameworkTemplate.ApplyTemplateContent(System.Windows.UncommonField`1<System.Collections.Specialized.HybridDictionary[]>, System.Windows.FrameworkElement)
   à System.Windows.FrameworkElement.ApplyTemplate()
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.Border.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.Control.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.StackPanel.StackMeasureHelper(System.Windows.Controls.IStackMeasure, System.Windows.Controls.IStackMeasureScrollData, System.Windows.Size)
   à System.Windows.Controls.StackPanel.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à MS.Internal.Helper.MeasureElementWithSingleChild(System.Windows.UIElement, System.Windows.Size)
   à System.Windows.Controls.ItemsPresenter.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.Grid.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à MS.Internal.Helper.MeasureElementWithSingleChild(System.Windows.UIElement, System.Windows.Size)
   à System.Windows.Controls.ScrollContentPresenter.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.Grid.MeasureCell(Int32, Boolean)
   à System.Windows.Controls.Grid.MeasureCellsGroup(Int32, System.Windows.Size, Boolean, Boolean, Boolean ByRef)
   à System.Windows.Controls.Grid.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.ScrollViewer.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.Border.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.Decorator.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Documents.AdornerDecorator.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.Decorator.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Controls.Primitives.PopupRoot.MeasureOverride(System.Windows.Size)
   à System.Windows.FrameworkElement.MeasureCore(System.Windows.Size)
   à System.Windows.UIElement.Measure(System.Windows.Size)
   à System.Windows.Interop.HwndSource.SetLayoutSize()
   à System.Windows.Interop.HwndSource.set_RootVisualInternal(System.Windows.Media.Visual)
   à System.Windows.Controls.Primitives.Popup.SetRootVisualToPopupRoot()
   à System.Windows.Controls.Primitives.Popup.CreateWindow(Boolean)
   à System.Windows.Controls.Primitives.Popup.OnIsOpenChanged(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.DependencyObject.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.FrameworkElement.OnPropertyChanged(System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex, System.Windows.DependencyProperty, System.Windows.PropertyMetadata, System.Windows.EffectiveValueEntry, System.Windows.EffectiveValueEntry ByRef, Boolean, Boolean, System.Windows.OperationType)
   à System.Windows.DependencyObject.InvalidateProperty(System.Windows.DependencyProperty, Boolean)
   à System.Windows.Data.BindingExpressionBase.Invalidate(Boolean)
   à System.Windows.Data.BindingExpression.TransferValue(System.Object, Boolean)
   à MS.Internal.Data.ClrBindingWorker.NewValueAvailable(Boolean, Boolean, Boolean)
   à MS.Internal.Data.PropertyPathWorker.UpdateSourceValueState(Int32, System.ComponentModel.ICollectionView, System.Object, Boolean)
   à MS.Internal.Data.PropertyPathWorker.OnDependencyPropertyChanged(System.Windows.DependencyObject, System.Windows.DependencyProperty, Boolean)
   à System.Windows.Data.BindingExpression.HandlePropertyInvalidation(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.Data.BindingExpressionBase.OnPropertyInvalidation(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.Data.BindingExpression.OnPropertyInvalidation(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.DependentList.InvalidateDependents(System.Windows.DependencyObject, System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.DependencyObject.NotifyPropertyChange(System.Windows.DependencyPropertyChangedEventArgs)
   à System.Windows.DependencyObject.UpdateEffectiveValue(System.Windows.EntryIndex, System.Windows.DependencyProperty, System.Windows.PropertyMetadata, System.Windows.EffectiveValueEntry, System.Windows.EffectiveValueEntry ByRef, Boolean, Boolean, System.Windows.OperationType)
   à System.Windows.DependencyObject.SetValueCommon(System.Windows.DependencyProperty, System.Object, System.Windows.PropertyMetadata, Boolean, Boolean, System.Windows.OperationType, Boolean)
   à MS.Internal.Data.PropertyPathWorker.SetValue(System.Object, System.Object)
   à System.Windows.Data.BindingExpression.UpdateSource(System.Object)

Informations sur l'exception : System.NullReferenceException
   à System.Windows.Controls.Primitives.Popup.OnWindowResize(System.Object, System.Windows.AutoResizedEventArgs)
   à System.Windows.Interop.HwndSource.Resize(System.Windows.Size)
   à System.Windows.Interop.HwndSource.OnLayoutUpdated(System.Object, System.EventArgs)
   à System.Windows.ContextLayoutManager.fireLayoutUpdateEvent()
   à System.Windows.ContextLayoutManager.UpdateLayout()
   à System.Windows.ContextLayoutManager.UpdateLayoutCallback(System.Object)
   à System.Windows.Media.MediaContext.FireInvokeOnRenderCallbacks()
   à System.Windows.Media.MediaContext.RenderMessageHandlerCore(System.Object)
   à System.Windows.Media.MediaContext.RenderMessageHandler(System.Object)
   à System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   à System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   à System.Windows.Threading.DispatcherOperation.InvokeImpl()
   à MS.Internal.CulturePreservingExecutionContext.CallbackWrapper(System.Object)
   à System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   à System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
   à System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
   à MS.Internal.CulturePreservingExecutionContext.Run(MS.Internal.CulturePreservingExecutionContext, System.Threading.ContextCallback, System.Object)
   à System.Windows.Threading.DispatcherOperation.Invoke()
   à System.Windows.Threading.Dispatcher.ProcessQueue()
   à System.Windows.Threading.Dispatcher.WndProcHook(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   à MS.Win32.HwndWrapper.WndProc(IntPtr, Int32, IntPtr, IntPtr, Boolean ByRef)
   à MS.Win32.HwndSubclass.DispatcherCallbackOperation(System.Object)
   à System.Windows.Threading.ExceptionWrapper.InternalRealCall(System.Delegate, System.Object, Int32)
   à System.Windows.Threading.ExceptionWrapper.TryCatchWhen(System.Object, System.Delegate, System.Object, Int32, System.Delegate)
   à System.Windows.Threading.Dispatcher.LegacyInvokeImpl(System.Windows.Threading.DispatcherPriority, System.TimeSpan, System.Delegate, System.Object, Int32)
   à MS.Win32.HwndSubclass.SubclassWndProc(IntPtr, Int32, IntPtr, IntPtr)
   à MS.Win32.UnsafeNativeMethods.DispatchMessage(System.Windows.Interop.MSG ByRef)
   à System.Windows.Threading.Dispatcher.PushFrameImpl(System.Windows.Threading.DispatcherFrame)
   à System.Windows.Application.RunDispatcher(System.Object)
   à System.Windows.Application.RunInternal(System.Windows.Window)
   à ArmyEditor.App.Main()

It happens when I do the following:

- Open army file BigArmy.xml (attached)
- I click on the Accurcy list box of the "1234" unit

Note that I have a test.txt custom accuracy file (attached). It is a copy of Pistol.txt that I have modified using the accuracy editor.



Andy ONeill

Any txt files in that accuracies folder will indeed be picked up and used by the army editor.

Looking at Test.txt. it has 99 lines in it.
Files should have 100 lines.

As it tries to work with the hundredth line, there is none and it crashes.

I've made a change so it should be less prone to crashing in this instance.
You will also see a message when you run the app which tells you about any problem file.

I copied pistol.txt and edited the file in the app.
When I hit save I still have 100 lines as expected.
Not sure how you ended up with 99 lines in test.txt.

Mickey3D

QuoteLooking at Test.txt. it has 99 lines in it.

I have edited it manually, I'm afraid I removed a line inadvertently.  :-[