• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#windowsobjective-ccocoa誰得qtpythonphprubygameguibathyscaphec計画中(planning stage)翻訳omegatframeworktwitterdomtestvb.netdirectxゲームエンジンbtronarduinopreviewer

Automap (client) [VS plugin mod]


Commit MetaInfo

Revision002c133b4b615eb424094513cb7fb64c593e7c26 (tree)
Time2020-03-11 22:35:18
AuthorThe Grand Dog <alex.h@me.c...>
CommiterThe Grand Dog

Log Message

Merge branch 'Split_renderers' into vgd

Change Summary

Incremental Difference

--- a/Automap/Automap.csproj
+++ b/Automap/Automap.csproj
@@ -93,7 +93,8 @@
9393 <Compile Include="Renderers\AlternateRenderer.cs" />
9494 <Compile Include="Data\StatusData.cs" />
9595 <Compile Include="Data\CommandData.cs" />
96- <Compile Include="Data\RunState.cs" />
96+ <Compile Include="Data\CommandType.cs" />
97+ <Compile Include="Data\PersistedConfiguration.cs" />
9798 </ItemGroup>
9899 <ItemGroup>
99100 <Folder Include="VS_libs\" />
--- a/Automap/AutomapMod.cs
+++ b/Automap/AutomapMod.cs
@@ -7,6 +7,8 @@ namespace Automap
77 {
88 public class AutomapMod : ModSystem
99 {
10+ public const string _configFilename = @"automap.json";
11+
1012 private ICoreAPI API { get; set; }
1113 private ICoreClientAPI ClientAPI { get; set; }
1214 private ILogger Logger { get; set; }
@@ -28,13 +30,15 @@ namespace Automap
2830 this.ClientAPI = api as ICoreClientAPI;
2931 this.Logger = Mod.Logger;
3032
31-
3233 ClientAPI.Logger.VerboseDebug("Automap Present!");
33- _localAutomap = new AutomapSystem(this.ClientAPI, this.Logger);
34- _automapDialog = new AutomapGUIDialog(ClientAPI, _localAutomap);
34+ PrepareClientsideConfig( );
35+ _localAutomap = new AutomapSystem(this.ClientAPI, this.Logger, this.CachedConfiguration);
36+ _automapDialog = new AutomapGUIDialog(ClientAPI, _localAutomap, this.CachedConfiguration);
3537
3638 ClientAPI.Input.RegisterHotKey(AutomapGUIDialog._automapControlPanelKey, "Automap control panel", GlKeys.M, HotkeyType.GUIOrOtherControls, shiftPressed: true);
3739 ClientAPI.Input.SetHotKeyHandler(AutomapGUIDialog._automapControlPanelKey, ToggleAM_Dialog);
40+
41+ ClientAPI.Event.LeaveWorld += PersistParameterChange;
3842 }
3943
4044 base.StartClientSide(api);
@@ -52,6 +56,41 @@ namespace Automap
5256
5357 return true;
5458 }
59+
60+ internal PersistedConfiguration CachedConfiguration {
61+ get
62+ {
63+ return ( PersistedConfiguration )ClientAPI.ObjectCache[_configFilename];
64+ }
65+ set
66+ {
67+ ClientAPI.ObjectCache.Add(_configFilename, value);
68+ }
69+ }
70+
71+ private void PrepareClientsideConfig( )
72+ {
73+ PersistedConfiguration config = ClientAPI.LoadModConfig<PersistedConfiguration>(_configFilename);
74+
75+ if (config == null) {
76+ //Regen default
77+ Mod.Logger.Warning("Regenerating default config as it was missing / unparsable...");
78+ ClientAPI.StoreModConfig<PersistedConfiguration>(new PersistedConfiguration(defaults: true ), _configFilename);
79+ config = ClientAPI.LoadModConfig<PersistedConfiguration>(_configFilename);
80+ }
81+
82+ this.CachedConfiguration = config;
83+ }
84+
85+ internal void PersistParameterChange( )
86+ {
87+ //Store altered parameters
88+
89+ ClientAPI.StoreModConfig<PersistedConfiguration>(this.CachedConfiguration, _configFilename);
90+ }
91+
92+
93+
5594 }
5695 }
5796
--- a/Automap/Data/BlockDesignator.cs
+++ b/Automap/Data/BlockDesignator.cs
@@ -2,6 +2,9 @@
22 using System.Collections.Generic;
33 using System.Collections.ObjectModel;
44 using System.Drawing;
5+using System.Runtime.Serialization;
6+
7+using Newtonsoft.Json;
58
69 using Vintagestory.API.Client;
710 using Vintagestory.API.Common;
@@ -14,17 +17,30 @@ namespace Automap
1417 /// <summary>
1518 /// Point of Interest Rule Designator
1619 /// </summary>
20+ [JsonObject(MemberSerialization.OptIn)]
1721 public class BlockDesignator
1822 {
23+ [JsonProperty]
1924 public Color OverwriteColor;
20- public BlockDesignatorAction SpecialAction;
25+
26+ [JsonIgnore]
27+ public BlockDesignatonAction SpecialAction;
28+
29+ [JsonProperty]
30+ public string SpecialActionName;
31+
32+ [JsonProperty]
2133 public AssetLocation Pattern;
34+
35+ [JsonProperty]
2236 public EnumBlockMaterial? Material;
37+
38+ [JsonProperty]
2339 public bool Enabled { get; set; }
2440
2541 private BlockDesignator()
2642 {
27- throw new NotSupportedException();
43+ //throw new NotSupportedException();
2844 }
2945
3046 public BlockDesignator(AssetLocation pattern, Color overwriteColor, EnumBlockMaterial? material)
@@ -41,6 +57,7 @@ namespace Automap
4157 this.OverwriteColor = overwriteColor;
4258 this.Material = material;
4359 this.SpecialAction = specialAct;
60+ this.SpecialActionName = specialAct.Method.Name;
4461 this.Enabled = true;
4562 }
4663
@@ -48,6 +65,30 @@ namespace Automap
4865 {
4966 return Pattern.ToShortString() + "|" + OverwriteColor.Name + "|" + Material ?? "";
5067 }
68+
69+ [OnDeserialized]
70+ public void RelinkDesignator(StreamingContext sCtx )
71+ {
72+ //TODO: properly Via reflection - and support for external designators?
73+ if (SpecialAction == null && !String.IsNullOrEmpty(SpecialActionName)) {
74+ switch (SpecialActionName) {
75+
76+ case "DecodeSign":
77+ SpecialAction = DefaultDesignators.DecodeSign;
78+ break;
79+
80+ case "DecodePostSign":
81+ SpecialAction = DefaultDesignators.DecodePostSign;
82+ break;
83+
84+ case "DecodeTranslocator":
85+ SpecialAction = DefaultDesignators.DecodeTranslocator;
86+ break;
87+
88+ }
89+ }
90+
91+ }
5192 }
5293 }
5394
--- a/Automap/Data/ColumnMeta.cs
+++ b/Automap/Data/ColumnMeta.cs
@@ -89,6 +89,8 @@ namespace Automap
8989 this.YMax = mapChunk.YMax;
9090 }
9191
92+
93+
9294 [ProtoBeforeSerialization]
9395 private void PrepareData( )
9496 {
@@ -118,8 +120,8 @@ namespace Automap
118120 int col, row;
119121
120122 BitVector32 bitMasker = new BitVector32(0);
121- var rowSection = BitVector32.CreateSection(ChunkSize);
122- var colSection = BitVector32.CreateSection(ChunkSize, rowSection);
123+ var rowSection = BitVector32.CreateSection(( short )(ChunkSize - 1));
124+ var colSection = BitVector32.CreateSection(( short )(ChunkSize - 1), rowSection);
123125
124126 for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++) {
125127 bitMasker = new BitVector32(data: ( int )rowcol);
--- a/Automap/Data/CommandData.cs
+++ b/Automap/Data/CommandData.cs
@@ -16,10 +16,9 @@ namespace Automap
1616 public class CommandData : IAttribute
1717 {
1818 [ProtoMember(1)]
19- public RunState State { get; set; }//Run , Stop, SingleSnapshot -> Stop
19+ public CommandType State { get; set; }//Run , Stop, SingleSnapshot -> Stop
20+
2021
21- [ProtoMember(2)]
22- private List<DelegateState> DelegatesFlags;
2322
2423 [ProtoMember(3)]
2524 public string Notation { get; set; }
@@ -29,28 +28,12 @@ namespace Automap
2928 //Choose : Renderer(s)
3029
3130
32- public CommandData(RunState assumeState, bool[] theseDelegates)
31+ public CommandData(CommandType assumeState)
3332 {
3433 State = assumeState;
3534
36- DelegatesFlags = new List<DelegateState>(theseDelegates.Length);
37- foreach (var df in theseDelegates)
38- {
39- DelegatesFlags.Add(new DelegateState()
40- {
41- Enabled = df,
42- AlternateColor = null,
43- });
44-
45- }
46-
47- }
4835
49- public CommandData(RunState assumeState)
50- {
51- State = assumeState;//Never RUN.
5236
53- DelegatesFlags = new List<DelegateState>();
5437 }
5538
5639
@@ -58,7 +41,7 @@ namespace Automap
5841 {
5942 var temp = ProtoBuf.Serializer.Deserialize<CommandData>(stream.BaseStream);
6043 this.State = temp.State;
61- this.DelegatesFlags = temp.DelegatesFlags;
44+
6245
6346 }
6447
@@ -84,7 +67,7 @@ namespace Automap
8467
8568 public string ToJsonToken()
8669 {
87- return $"New-State:{State}, Delegates# {DelegatesFlags.Count} ";
70+ return $"Command-Type:{State} ";
8871 }
8972
9073 public bool Equals(IWorldAccessor worldForResolve, IAttribute attr)
@@ -99,18 +82,5 @@ namespace Automap
9982 return false;
10083 }
10184 }
102-
103- [ProtoContract]
104- internal struct DelegateState
105- {
106- [ProtoMember(1)]
107- public bool Enabled;
108-
109- [ProtoMember(2)]
110- public Color? AlternateColor;
111-
112-
113-
114- }
11585 }
11686
--- a/Automap/Data/RunState.cs
+++ b/Automap/Data/CommandType.cs
@@ -4,7 +4,7 @@ namespace Automap
44 /// <summary>
55 /// Command Type
66 /// </summary>
7- public enum RunState : byte
7+ public enum CommandType : byte
88 {
99 Stop = 0x00,
1010 Run = 0x01,
--- a/Automap/Data/EntityDesignator.cs
+++ b/Automap/Data/EntityDesignator.cs
@@ -2,6 +2,9 @@
22 using System.Collections.Generic;
33 using System.Collections.ObjectModel;
44 using System.Drawing;
5+using System.Runtime.Serialization;
6+
7+using Newtonsoft.Json;
58
69 using Vintagestory.API.Client;
710 using Vintagestory.API.Common;
@@ -15,17 +18,30 @@ namespace Automap
1518 /// <summary>
1619 /// Point of Interest Rule Designator
1720 /// </summary>
21+ [JsonObject(MemberSerialization.OptIn)]
1822 public class EntityDesignator
1923 {
24+ [JsonProperty]
2025 public Color Color;
21- public EntityDesignatorAction SpecialAction;
26+
27+ [JsonIgnore]
28+ public EntityDesignatonAction SpecialAction;
29+
30+ [JsonProperty]
31+ public string SpecialActionName;
32+
33+ [JsonProperty]
2234 public AssetLocation Pattern;
35+
36+ [JsonProperty]
2337 public EnumEntityState? StateCheck;//Needed?
38+
39+ [JsonProperty]
2440 public bool Enabled { get; set; }
2541
2642 private EntityDesignator()
2743 {
28- throw new NotSupportedException();
44+ //throw new NotSupportedException();
2945 }
3046
3147 public EntityDesignator(AssetLocation pattern, Color color, EnumEntityState? state)
@@ -42,11 +58,29 @@ namespace Automap
4258 Color = color;
4359 StateCheck = state;
4460 SpecialAction = specialAct;
61+ SpecialActionName = specialAct.Method.Name;
4562 Enabled = true;
4663 }
4764
4865 public override string ToString()
4966 => Pattern.ToShortString() + "|" + Color.Name + "|" + StateCheck ?? "";
67+
68+ [OnDeserialized]
69+ public void RelinkDesignator(StreamingContext sCtx)
70+ {
71+ //TODO: properly Via reflection - and support for external designators?
72+ if (SpecialAction == null && !String.IsNullOrEmpty(SpecialActionName)) {
73+ switch (SpecialActionName) {
74+
75+ case "KeepTrackOfMerchant":
76+ SpecialAction = DefaultDesignators.KeepTrackOfMerchant;
77+ break;
78+
79+
80+ }
81+ }
82+
83+ }
5084 }
5185 }
5286
--- /dev/null
+++ b/Automap/Data/PersistedConfiguration.cs
@@ -0,0 +1,37 @@
1+using System;
2+using System.Collections.Generic;
3+
4+using Newtonsoft.Json;
5+
6+namespace Automap
7+{
8+
9+ public class PersistedConfiguration
10+ {
11+ /// <summary>
12+ /// Run AM After a small delay when client has loaded fully
13+ /// </summary>
14+ /// <value>To autostart.</value>
15+ public bool Autostart { get; set; } = false;
16+
17+ //public string ChosenRendererName { get; set; }
18+
19+ //All - Designators, setup
20+ public List<BlockDesignator> BlockDesignators { get; set; }
21+ public List<EntityDesignator> EntityDesignators { get; set; }
22+
23+
24+ public PersistedConfiguration(bool defaults = false )
25+ {
26+
27+ if (defaults) {
28+ BlockDesignators = DefaultDesignators.DefaultBlockDesignators( );
29+ EntityDesignators= DefaultDesignators.DefaultEntityDesignators( );
30+ }
31+
32+ }
33+
34+
35+ }
36+}
37+
--- a/Automap/Data/StatusData.cs
+++ b/Automap/Data/StatusData.cs
@@ -9,9 +9,9 @@ namespace Automap {
99 public uint VoidChunks { get; set; }
1010 public uint Delta { get; set; }
1111 public uint Max_N, Max_E, Max_S, Max_W;
12- public RunState CurrentState { get; set; }
12+ public CommandType CurrentState { get; set; }
1313
14- public StatusData(uint totalUpdates, uint voidChunks, uint delta, RunState currently) {
14+ public StatusData(uint totalUpdates, uint voidChunks, uint delta, CommandType currently) {
1515 TotalUpdates = totalUpdates;
1616 VoidChunks = voidChunks;
1717 Delta = delta;
@@ -22,7 +22,7 @@ namespace Automap {
2222 TotalUpdates = stream.ReadUInt32();
2323 VoidChunks = stream.ReadUInt32();
2424 Delta = stream.ReadUInt32();
25- CurrentState = (RunState) stream.ReadByte();
25+ CurrentState = (CommandType) stream.ReadByte();
2626 }
2727
2828 public int GetAttributeId() {
--- a/Automap/Designators/DefaultDesignators.cs
+++ b/Automap/Designators/DefaultDesignators.cs
@@ -81,6 +81,8 @@ namespace Automap
8181 };
8282 }
8383
84+ #region Designators
85+
8486 internal static void DecodeSign(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
8587 {
8688 #if DEBUG
@@ -176,6 +178,8 @@ namespace Automap
176178
177179 }
178180 }
181+
182+ #endregion
179183 }
180184 }
181185
--- a/Automap/Subsystems/AutomapGUIDialog.cs
+++ b/Automap/Subsystems/AutomapGUIDialog.cs
@@ -12,9 +12,11 @@ namespace Automap
1212 public const string _automapControlPanelKey = "automapControlPanelKey";
1313 private const string _statusTextKey = @"txtStatus";
1414 private const string _noteTextKey = @"edtNote";
15+ private const string _swAutostart = @"swAutostart";
16+ private const string _btnRunKey = @"btnRun";
1517
1618 private ILogger Logger;
17-
19+ private PersistedConfiguration configuration;
1820 private long dashTickHandle;
1921
2022 public override string ToggleKeyCombinationCode
@@ -25,16 +27,20 @@ namespace Automap
2527 }
2628
2729 private uint totalShards, voidShards, changesThisTick;
28- private RunState lastState;
30+ private CommandType lastState;
2931
3032
31- public AutomapGUIDialog(ICoreClientAPI capi, AutomapSystem ams) : base(capi)
33+ public AutomapGUIDialog(ICoreClientAPI capi, AutomapSystem ams, PersistedConfiguration cfg) : base(capi)
3234 {
3335
3436 Logger = capi.Logger;
3537 SetupDialog();
3638 capi.Event.RegisterEventBusListener(AutomapStatusMsg, 1.0D, AutomapSystem.AutomapStatusEventKey);
39+ configuration = cfg;
40+ }
3741
42+ public AutomapGUIDialog(ICoreClientAPI capi) : base(capi)
43+ {
3844 }
3945
4046 //Event for GUI status display
@@ -53,6 +59,10 @@ namespace Automap
5359 toggleBounds.fixedHeight = 24;
5460 toggleBounds.fixedWidth = 64;
5561
62+ ElementBounds autostartBounds = toggleBounds.RightCopy(66, 0, 1, 1);
63+ autostartBounds.fixedHeight = 24;
64+ autostartBounds.fixedWidth = 80;
65+
5666 ElementBounds txtStatusBounds = textBounds.CopyOffsetedSibling(0, 26, 2, 4);
5767 txtStatusBounds.fixedHeight = 16;
5868 txtStatusBounds.percentWidth = 1;
@@ -70,19 +80,21 @@ namespace Automap
7080 .AddShadedDialogBG(bgBounds)
7181 .AddDialogTitleBar("Automap Controls", OnTitleBarCloseClicked)
7282 .AddStaticText("Configure Automap settings:", CairoFont.WhiteDetailText(), textBounds)
73- .AddToggleButton("Run", CairoFont.ButtonText(), RunToggle, toggleBounds, "btnRun")
83+ .AddToggleButton("Run", CairoFont.ButtonText(), RunToggle, toggleBounds, _btnRunKey)
84+ .AddSwitch(AutostartChange,autostartBounds,_swAutostart)
85+ .AddStaticText("Autostart",CairoFont.WhiteDetailText(),autostartBounds.RightCopy(16))
7486 .AddDynamicText("Idle.", CairoFont.WhiteSmallText().WithFontSize(12), EnumTextOrientation.Left, txtStatusBounds, _statusTextKey)
7587 .AddTextInput(txtNoteArea, null, CairoFont.WhiteMediumText().WithFontSize(16), _noteTextKey)
7688 .AddButton("Note:", CreateNote, btnNoteArea, CairoFont.ButtonText())
7789 .Compose();
7890
79- //Controls for ALL Block & Entity Designators (Enable/Disable)
91+ //Controls for ALL Block & Entity Designators (Enable/Disable) <-- block edits while in 'Run' state
8092 //_automapSystem.BlockID_Designators
8193 //_automapSystem.Entity_Designators
8294 //Renderer selection
8395 //Message verbosity? Speed?
8496
85- //A Button to add POI - notes manually (when AM running)
97+
8698
8799 }
88100
@@ -91,6 +103,20 @@ namespace Automap
91103 TryClose();
92104 }
93105
106+ public override void OnGuiOpened( )
107+ {
108+ base.OnGuiOpened( );
109+ UpdateDashDisplay(0f);
110+ if (dashTickHandle == 0L) dashTickHandle = capi.Event.RegisterGameTickListener(UpdateDashDisplay, 1000);
111+ }
112+
113+ public override void OnGuiClosed( )
114+ {
115+ base.OnGuiClosed( );
116+
117+ if (dashTickHandle != 0L) capi.Event.UnregisterGameTickListener(dashTickHandle);
118+ }
119+
94120 /// <summary>
95121 /// Toggle Automap from/to RUN state
96122 /// </summary>
@@ -100,27 +126,16 @@ namespace Automap
100126 {
101127 Logger.VerboseDebug("Dialog Changed; [ Automap Enabled: {0} ]", toggle);
102128 var statusText = this.SingleComposer.GetDynamicText(_statusTextKey);
103- statusText.SetNewText($"State: {(toggle ? "Run" : "Halt")}, Total: {totalShards}, Nulls: {voidShards} ");
104-
105- CommandData cmd;
106-
107- if (toggle)
108- {
109- dashTickHandle = capi.Event.RegisterGameTickListener(UpdateDashDisplay, 6001);
110- cmd = new CommandData(toggle ? RunState.Run : RunState.Stop, new bool[] { true, true, true, true, true });
111- }
112- else
113- {
114- capi.Event.UnregisterGameTickListener(dashTickHandle);
115- cmd = new CommandData(toggle ? RunState.Run : RunState.Stop);
116- }
129+ UpdateDashDisplay(0f);
130+
131+ CommandData cmd = new CommandData(toggle ? CommandType.Run : CommandType.Stop);
117132
118133 capi.Event.PushEvent(AutomapSystem.AutomapCommandEventKey, cmd);
119134 }
120135
121136 private bool CreateNote()
122137 {
123- var noteCmd = new CommandData(RunState.Notation);
138+ var noteCmd = new CommandData(CommandType.Notation);
124139 var txtNote = this.SingleComposer.GetTextInput(_noteTextKey);
125140 if (!String.IsNullOrWhiteSpace(txtNote.GetText()))
126141 {
@@ -129,7 +144,12 @@ namespace Automap
129144
130145 capi.Event.PushEvent(AutomapSystem.AutomapCommandEventKey, noteCmd);
131146 }
132- return false;//???
147+ return true;//FINDOUT: What does this DO?
148+ }
149+
150+ private void AutostartChange(bool startValue)
151+ {
152+ configuration.Autostart = startValue;
133153 }
134154
135155 private void AutomapStatusMsg(string eventName, ref EnumHandling handling, IAttribute data)
@@ -145,9 +165,17 @@ namespace Automap
145165 private void UpdateDashDisplay(float delay)
146166 {
147167 var statusText = this.SingleComposer.GetDynamicText(_statusTextKey);
148- statusText.SetNewText($"State: {lastState}, Total: {totalShards}, Delta: {changesThisTick} Nulls: {voidShards} ");
149168
169+ var btnRun = this.SingleComposer.GetToggleButton(_btnRunKey);
150170
171+ if (lastState == CommandType.Run) {
172+ statusText.SetNewText($"State: {lastState}, Total: {totalShards}, Delta: +{changesThisTick} Nulls: {voidShards} ");
173+ btnRun.SetValue(true);
174+ }
175+ else if (lastState == CommandType.Stop) {
176+ statusText.SetNewText($"State: {lastState}, Total: {totalShards}, Nulls: {voidShards} ");
177+ btnRun.SetValue(false);
178+ }
151179 }
152180
153181
--- a/Automap/Subsystems/AutomapSystem.cs
+++ b/Automap/Subsystems/AutomapSystem.cs
@@ -9,7 +9,9 @@ using System.Threading;
99
1010 using Hjg.Pngcs;
1111 using Hjg.Pngcs.Chunks;
12+
1213 using Newtonsoft.Json;
14+
1315 using Vintagestory.API.Client;
1416 using Vintagestory.API.Common;
1517 using Vintagestory.API.Config;
@@ -41,7 +43,7 @@ namespace Automap
4143 internal Dictionary<AssetLocation, EntityDesignator> Entity_Designators { get; private set; }
4244 internal Dictionary<int, string> RockIdCodes { get; private set; }
4345
44- internal RunState CurrentState { get; set; }
46+ internal CommandType CurrentState { get; set; }
4547 //Run status, Chunks processed, stats, center of map....
4648 private uint nullChunkCount, updatedChunksTotal;
4749 private Vec2i startChunkColumn;
@@ -49,17 +51,22 @@ namespace Automap
4951 private readonly int chunkSize;
5052 private string path;
5153 private IAsset staticMap;
54+ private PersistedConfiguration configuration;
55+
5256
5357 public static string AutomapStatusEventKey = @"AutomapStatus";
5458 public static string AutomapCommandEventKey = @"AutomapCommand";
59+ PersistedConfiguration cachedConfiguration;
5560
56-
57- public AutomapSystem(ICoreClientAPI clientAPI, ILogger logger)
61+ public AutomapSystem(ICoreClientAPI clientAPI, ILogger logger, PersistedConfiguration config)
5862 {
5963 this.ClientAPI = clientAPI;
6064 this.Logger = logger;
6165 chunkSize = ClientAPI.World.BlockAccessor.ChunkSize;
6266 ClientAPI.Event.LevelFinalize += EngageAutomap;
67+ configuration = config;
68+
69+
6370
6471 //TODO:Choose which one from GUI
6572 this.ChunkRenderer = new StandardRenderer(clientAPI, logger);
@@ -67,6 +74,12 @@ namespace Automap
6774 //Listen on bus for commands
6875 ClientAPI.Event.RegisterEventBusListener(CommandListener, 1.0, AutomapSystem.AutomapCommandEventKey);
6976
77+ if (configuration.Autostart)
78+ {
79+ CurrentState = CommandType.Run;
80+ Logger.Debug("Autostart is Enabled.");
81+ }
82+
7083 }
7184
7285
@@ -113,7 +126,7 @@ namespace Automap
113126 private void AwakenCartographer(float delayed)
114127 {
115128
116- if (CurrentState == RunState.Run && (ClientAPI.IsGamePaused != false || ClientAPI.IsShuttingDown != true))
129+ if (CurrentState == CommandType.Run && (ClientAPI.IsGamePaused != false || ClientAPI.IsShuttingDown != true))
117130 {
118131 #if DEBUG
119132 Logger.VerboseDebug("Cartographer re-trigger from [{0}]", cartographer_thread.ThreadState);
@@ -132,7 +145,7 @@ namespace Automap
132145 //ClientAPI.TriggerChatMessage($"Automap {updatedChunksTotal} Updates - MAX (N:{chunkTopMetadata.North_mostChunk},S:{chunkTopMetadata.South_mostChunk},E:{chunkTopMetadata.East_mostChunk}, W:{chunkTopMetadata.West_mostChunk} - TOTAL: {chunkTopMetadata.Count})");
133146 //#endif
134147 }
135- else if (CurrentState == RunState.Snapshot)
148+ else if (CurrentState == CommandType.Snapshot)
136149 {
137150 //TODO: Snapshot generator second thread...
138151 }
@@ -155,9 +168,10 @@ namespace Automap
155168 if (!columnCounter.IsEmpty)
156169 {
157170 var tempSet = columnCounter.ToArray().OrderByDescending(kvp => kvp.Value);
171+ UpdateEntityMetadata( );
172+
158173 foreach (var mostActiveCol in tempSet)
159174 {
160-
161175 var mapChunk = ClientAPI.World.BlockAccessor.GetMapChunk(mostActiveCol.Key);
162176
163177 if (mapChunk == null)
@@ -178,8 +192,7 @@ namespace Automap
178192 chunkMeta = CreateColumnMetadata(mostActiveCol, mapChunk);
179193 }
180194
181- UpdateEntityMetadata();
182- ProcessChunkBlocks(mostActiveCol.Key, mapChunk, chunkMeta);
195+ ProcessChunkBlocks(mostActiveCol.Key, mapChunk, ref chunkMeta);
183196
184197 PngWriter pngWriter = SetupPngImage(mostActiveCol.Key, chunkMeta);
185198 ChunkRenderer.GenerateChunkPngShard(mostActiveCol.Key, mapChunk, chunkMeta, pngWriter, out updatedPixels);
@@ -187,9 +200,9 @@ namespace Automap
187200 if (updatedPixels > 0)
188201 {
189202
190-#if DEBUG
203+ #if DEBUG
191204 Logger.VerboseDebug("Wrote chunk shard: ({0}) - Edits#:{1}, Pixels#:{2}", mostActiveCol.Key, mostActiveCol.Value, updatedPixels);
192-#endif
205+ #endif
193206 updatedChunks++;
194207 chunkTopMetadata.Update(chunkMeta);
195208 columnCounter.TryRemove(mostActiveCol.Key, out ejectedItem);
@@ -240,7 +253,7 @@ namespace Automap
240253
241254 private void UpdateStatus(uint totalUpdates, uint voidChunks, uint delta)
242255 {
243- StatusData updateData = new StatusData(totalUpdates, voidChunks, delta, RunState.Run);
256+ StatusData updateData = new StatusData(totalUpdates, voidChunks, delta, CommandType.Run);
244257
245258 this.ClientAPI.Event.PushEvent(AutomapStatusEventKey, updateData);
246259 }
@@ -250,17 +263,17 @@ namespace Automap
250263
251264 this.BlockID_Designators = new Dictionary<int, BlockDesignator>();
252265 this.Entity_Designators = new Dictionary<AssetLocation, EntityDesignator>();
253- this.RockIdCodes = Helpers.ArbitrarytBlockIdHunter(ClientAPI, new AssetLocation(GlobalConstants.DefaultDomain, "rock"), EnumBlockMaterial.Stone);
266+ this.RockIdCodes = Helpers.ArbitrarytBlockIdHunter(ClientAPI, new AssetLocation(GlobalConstants.DefaultDomain, "rock-"), EnumBlockMaterial.Stone);
254267
255268 //Add special marker types for BlockID's of "Interest", overwrite colour, and method
256269
257- Install_POI_Designators(DefaultDesignators.DefaultBlockDesignators(), DefaultDesignators.DefaultEntityDesignators());
270+ Reload_POI_Designators();
258271 }
259272
260- private void Install_POI_Designators(ICollection<BlockDesignator> blockDesig, List<EntityDesignator> entDesig)
261- {
262- Logger.VerboseDebug("Connecting {0} standard Block-Designators", blockDesig.Count);
263- foreach (var designator in blockDesig)
273+ private void Reload_POI_Designators()
274+ {
275+ Logger.VerboseDebug("Connecting {0} Configured Block-Designators", configuration.BlockDesignators.Count);
276+ foreach (var designator in configuration.BlockDesignators)
264277 {
265278 var blockIDs = Helpers.ArbitrarytBlockIdHunter(ClientAPI, designator.Pattern, designator.Material);
266279 if (blockIDs.Count > 0) { Logger.VerboseDebug("Designator {0} has {1} associated blockIDs", designator.ToString(), blockIDs.Count); }
@@ -272,8 +285,8 @@ namespace Automap
272285 this.ChunkRenderer.BlockID_Designators = BlockID_Designators;
273286
274287
275- Logger.VerboseDebug("Connecting {0} standard Entity-Designators", entDesig.Count);
276- foreach (var designator in entDesig)
288+ Logger.VerboseDebug("Connecting {0} Configured Entity-Designators", configuration.EntityDesignators.Count);
289+ foreach (var designator in configuration.EntityDesignators)
277290 {
278291 //Get Variants first, from EntityTypes...better be populated!
279292 var matched = ClientAPI.World.EntityTypes.FindAll(entp => entp.Code.BeginsWith(designator.Pattern.Domain, designator.Pattern.Path));
@@ -292,6 +305,7 @@ namespace Automap
292305
293306 }
294307
308+ //TODO: Rewrite as Newtonsoft JsonTextWriter !!!
295309 /// <summary>
296310 /// Generates the JSON Metadata. (in Map object format )
297311 /// </summary>
@@ -299,77 +313,210 @@ namespace Automap
299313 {
300314 string jsonFilename = Path.Combine(path, "Metadata.js");
301315
302- StreamWriter jsonWriter = new StreamWriter(jsonFilename, false, Encoding.UTF8);
316+ StreamWriter stream = new StreamWriter(jsonFilename, false, Encoding.UTF8);
317+
318+ using (stream) {
319+ JsonTextWriter jsonWriter = new JsonTextWriter(stream);
320+
321+ jsonWriter.Formatting = Formatting.None;
322+ jsonWriter.StringEscapeHandling = StringEscapeHandling.EscapeHtml;
323+ jsonWriter.Indentation = 0;
324+ //jsonWriter.AutoCompleteOnClose = true;
325+ jsonWriter.QuoteChar = '\'';
326+ jsonWriter.DateFormatHandling = DateFormatHandling.IsoDateFormat;
327+ jsonWriter.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
328+
303329 using (jsonWriter)
304330 {
305- jsonWriter.Write("ViewFrame.chunks={};");
306- jsonWriter.Write("ViewFrame.chunks.worldSeedNum={0};", ClientAPI.World.Seed);
307- jsonWriter.Write("ViewFrame.chunks.genTime=new Date('{0}');", DateTimeOffset.UtcNow.ToString("O"));
308- jsonWriter.Write("ViewFrame.chunks.startCoords=[{0},{1}];", startChunkColumn.X, startChunkColumn.Y);
309- jsonWriter.Write("ViewFrame.chunks.chunkSize={0};", chunkSize);
310- jsonWriter.Write("ViewFrame.chunks.northMostChunk={0};", chunkTopMetadata.North_mostChunk);
311- jsonWriter.Write("ViewFrame.chunks.southMostChunk={0};", chunkTopMetadata.South_mostChunk);
312- jsonWriter.Write("ViewFrame.chunks.eastMostChunk={0};", chunkTopMetadata.East_mostChunk);
313- jsonWriter.Write("ViewFrame.chunks.westMostChunk={0};", chunkTopMetadata.West_mostChunk);
314- // this is so that the tool tip doesnt need to be hard coded in the map
315- jsonWriter.Write("ViewFrame.chunks.chunkMetaNames=[");
316- // there are 10 (TEN) (ten) things
317- jsonWriter.Write("'Loc.','Age','Temp.','Y Max','Fert.','Forest','Rain','Shrub','Air','Non-Air'");
318- jsonWriter.Write("];");
331+ jsonWriter.WriteRaw("ViewFrame.chunks={};\n");
332+ jsonWriter.WriteRaw("ViewFrame.chunks.worldSeedNum=" );
333+ jsonWriter.WriteValue(ClientAPI.World.Seed);
334+ jsonWriter.WriteRaw(";\n");
335+
336+ jsonWriter.WriteRaw("ViewFrame.chunks.genTime=");
337+ jsonWriter.WriteValue(DateTimeOffset.UtcNow);
338+ jsonWriter.WriteRaw(";\n");
339+
340+ jsonWriter.WriteRaw("ViewFrame.chunks.startCoords=");
341+ jsonWriter.WriteStartArray( );
342+ jsonWriter.WriteValue(startChunkColumn.X);
343+ jsonWriter.WriteValue(startChunkColumn.Y);
344+ jsonWriter.WriteEndArray( );
345+ jsonWriter.WriteRaw(";\n");
346+
347+ jsonWriter.WriteRaw("ViewFrame.chunks.chunkSize=");
348+ jsonWriter.WriteValue(chunkSize);
349+ jsonWriter.WriteRaw(";\n");
350+
351+ jsonWriter.WriteRaw("ViewFrame.chunks.northMostChunk=");
352+ jsonWriter.WriteValue(chunkTopMetadata.North_mostChunk);
353+ jsonWriter.WriteRaw(";\n");
354+
355+ jsonWriter.WriteRaw("ViewFrame.chunks.southMostChunk=");
356+ jsonWriter.WriteValue(chunkTopMetadata.South_mostChunk);
357+ jsonWriter.WriteRaw(";\n");
358+
359+ jsonWriter.WriteRaw("ViewFrame.chunks.westMostChunk=");
360+ jsonWriter.WriteValue(chunkTopMetadata.West_mostChunk);
361+ jsonWriter.WriteRaw(";\n");
362+
363+ jsonWriter.WriteRaw("ViewFrame.chunks.eastMostChunk=");
364+ jsonWriter.WriteValue(chunkTopMetadata.East_mostChunk);
365+ jsonWriter.WriteRaw(";\n");
366+
367+
319368 //MAP object format - [key, value]: key is "x_y"
320- jsonWriter.Write("ViewFrame.chunks.chunkMetadata=new Map([");
369+ jsonWriter.WriteRaw("ViewFrame.chunks.chunkMetadata=");
370+ jsonWriter.WriteStartConstructor("Map");
371+ jsonWriter.WriteStartArray( );//An array of... 2-component arrays
372+
373+
321374 foreach (var shard in chunkTopMetadata)
322375 {
323- jsonWriter.Write("['{0}_{1}',", shard.Location.X, shard.Location.Y);
324- jsonWriter.Write("[");
325- // 10 things but 0 indexed so NINE (9)
326- jsonWriter.Write("'{0}','{1}','{2}','{3}','{4}','{5}','{6}','{7}','{8}','{9}'",
327- shard.Location.PrettyCoords(ClientAPI),
328- shard.ChunkAge.ToString("g"),//World age - relative? or last edit ??
329- shard.Temperature.ToString("F1"),
330- shard.YMax,
331- shard.Fertility.ToString("F1"),
332- shard.ForestDensity.ToString("F1"),
333- shard.Rainfall.ToString("F1"),
334- shard.ShrubDensity.ToString("F1"),
335- shard.AirBlocks,
336- shard.NonAirBlocks
337- );
338- //TODO: Rock-ratio, also requires a BlockID => Name lookup table....elsewhere
339- jsonWriter.Write("]],");
376+ jsonWriter.WriteStartArray( );//Start tuple
377+ jsonWriter.WriteValue($"{shard.Location.X}_{shard.Location.Y}");//Key of Tuple
378+
379+ jsonWriter.WriteStartObject( );
380+ jsonWriter.WritePropertyName("prettyCoord");
381+ jsonWriter.WriteValue( shard.Location.PrettyCoords(ClientAPI));
382+
383+ jsonWriter.WritePropertyName("chunkAge");
384+ jsonWriter.WriteValue(shard.ChunkAge);
385+
386+ jsonWriter.WritePropertyName("temp");
387+ jsonWriter.WriteValue(shard.Temperature);
388+
389+ jsonWriter.WritePropertyName("YMax");
390+ jsonWriter.WriteValue(shard.YMax);
391+
392+ jsonWriter.WritePropertyName("fert");
393+ jsonWriter.WriteValue(shard.Fertility);
394+
395+ jsonWriter.WritePropertyName("forestDens");
396+ jsonWriter.WriteValue( shard.ForestDensity);
397+
398+ jsonWriter.WritePropertyName("rain");
399+ jsonWriter.WriteValue( shard.Rainfall);
400+
401+ jsonWriter.WritePropertyName("shrubDens");
402+ jsonWriter.WriteValue( shard.ShrubDensity);
403+
404+ jsonWriter.WritePropertyName("airBlocks");
405+ jsonWriter.WriteValue( shard.AirBlocks);
406+
407+ jsonWriter.WritePropertyName("nonAirBlocks");
408+ jsonWriter.WriteValue( shard.NonAirBlocks);
409+
410+ //TODO: Heightmap ?
411+ //Start rockMap ; FOR a Ratio....on tooltip GUI
412+ jsonWriter.WritePropertyName("rockRatio");
413+ jsonWriter.WriteStartConstructor("Map");
414+ jsonWriter.WriteStartArray( );
415+ foreach (var rockEntry in shard.RockRatio) {
416+ var rockBlock = ClientAPI.World.GetBlock(rockEntry.Key);
417+ jsonWriter.WriteStartArray( );
418+ jsonWriter.WriteValue(rockBlock.Code.Path);
419+ jsonWriter.WriteValue(rockEntry.Value);//Total per chunk-column
420+ jsonWriter.WriteEndArray( );
421+ }
422+ jsonWriter.WriteEndArray( );
423+ jsonWriter.WriteEndConstructor( );//end rock-map
424+
425+ jsonWriter.WriteEndObject( );//end Map value: {Object}
426+ jsonWriter.WriteEndArray( );//end Tuple
340427 }
341- jsonWriter.Write("]);");
342428
429+ jsonWriter.WriteEndArray( );//Enclose tuples of chunkMetadata
430+ jsonWriter.WriteEndConstructor( );//Close constructor of Map (chunkMetadata)
431+ jsonWriter.WriteRaw(";\n");
432+
433+ jsonWriter.WriteRaw("ViewFrame.chunks.pointsOfInterest=");
434+ jsonWriter.WriteStartConstructor("Map");
435+ jsonWriter.WriteStartArray( );//An array of... 2-component arrays
343436
344- jsonWriter.Write("ViewFrame.chunks.pointsOfInterest=new Map([");
345437 foreach (var poi in POIs)
346438 {
347- jsonWriter.Write("['{0}_{1}',", (float) poi.Location.X / chunkSize, (float) poi.Location.Z / chunkSize);
348- jsonWriter.Write("{");
349- jsonWriter.Write("prettyCoord:'{0}',", poi.Location.PrettyCoords(ClientAPI));
350- jsonWriter.Write("notes:{0},", JsonConvert.ToString(poi.Notes, '\'', StringEscapeHandling.EscapeHtml));
351- jsonWriter.Write("time:new Date('{0}'),", poi.Timestamp.ToString("O"));
352- jsonWriter.Write("chunkPos:'{0}_{1}',", (poi.Location.X / chunkSize), (poi.Location.Z / chunkSize));
353- jsonWriter.Write("}],");
439+ jsonWriter.WriteStartArray( );
440+ jsonWriter.WriteValue($"{poi.Location.X}_{poi.Location.Z}");
441+
442+ jsonWriter.WriteStartObject();
443+ jsonWriter.WritePropertyName("prettyCoord");
444+ jsonWriter.WriteValue(poi.Location.PrettyCoords(ClientAPI) );
445+
446+ jsonWriter.WritePropertyName("notes");
447+ jsonWriter.WriteValue(poi.Notes);//Encoded to HTML Entities
448+
449+ jsonWriter.WritePropertyName("time");
450+ jsonWriter.WriteValue(poi.Timestamp);
451+
452+ jsonWriter.WritePropertyName("chunkPos");
453+ jsonWriter.WriteValue($"{(poi.Location.X / chunkSize)}_{(poi.Location.Z / chunkSize)}");
454+
455+ jsonWriter.WriteEndObject( );
456+ jsonWriter.WriteEndArray( );
354457 }
355458 jsonWriter.Write("]);");
356459
357460 jsonWriter.Write("ViewFrame.chunks.entitiesOfInterest=new Map([");
358461 foreach (var eoi in EOIs)
359462 {
360- jsonWriter.Write("['{0}_{1}',", (float) eoi.Location.X / chunkSize, (float) eoi.Location.Z / chunkSize);
361- jsonWriter.Write("{");
362- jsonWriter.Write("prettyCoord:'{0}',", eoi.Location.PrettyCoords(ClientAPI));
363- jsonWriter.Write("notes:{0},", JsonConvert.ToString(eoi.Notes, '\'', StringEscapeHandling.EscapeHtml));
364- jsonWriter.Write("time:new Date('{0}'),", eoi.Timestamp.ToString("O"));
365- jsonWriter.Write("chunkPos:'{0}_{1}',", (eoi.Location.X / chunkSize), (eoi.Location.Z / chunkSize));
366- jsonWriter.Write("entityId:'{0}'", eoi.EntityId);
367- jsonWriter.Write("}],");
463+ jsonWriter.WriteStartArray( );
464+ jsonWriter.WriteValue($"{poi.Location.X}_{poi.Location.Z}");
465+
466+ jsonWriter.WriteStartObject( );
467+ jsonWriter.WritePropertyName("prettyCoord");
468+ jsonWriter.WriteValue(poi.Location.PrettyCoords(ClientAPI));
469+
470+ jsonWriter.WritePropertyName("notes");
471+ jsonWriter.WriteValue(poi.Notes);//Encoded to HTML Entities
472+
473+ jsonWriter.WritePropertyName("time");
474+ jsonWriter.WriteValue(poi.Timestamp);
475+
476+ jsonWriter.WritePropertyName("chunkPos");
477+ jsonWriter.WriteValue($"{(poi.Location.X / chunkSize)}_{(poi.Location.Z / chunkSize)}");
478+
479+ jsonWriter.WriteEndObject( );
480+ jsonWriter.WriteEndArray( );
368481 }
369- jsonWriter.Write("]);");
482+
483+ jsonWriter.WriteEndArray( );
484+ jsonWriter.WriteEndConstructor( );
485+ jsonWriter.WriteRaw(";\n");
486+
487+ jsonWriter.WriteWhitespace("\n");
488+ jsonWriter.WriteComment("============= BlockID's for Rockmap / Rock-ratios ===============");
489+ jsonWriter.WriteWhitespace("\n");
490+
491+ jsonWriter.WriteRaw("ViewFrame.chunks.rock_Lookup =");
492+ jsonWriter.WriteStartConstructor("Map");
493+ jsonWriter.WriteStartArray( );//An array of... 2-component arrays
494+
495+ foreach (var entry in RockIdCodes) {
496+ var block = ClientAPI.World.GetBlock(entry.Key);
497+
498+ jsonWriter.WriteStartArray( );
499+ jsonWriter.WriteValue(block.Code.Path);
500+
501+ jsonWriter.WriteStartObject( );
502+ jsonWriter.WritePropertyName("assetCode");
503+ jsonWriter.WriteValue(entry.Value);
504+
505+ jsonWriter.WritePropertyName("name");
506+ jsonWriter.WriteValue(Lang.GetUnformatted(block.Code.Path));
507+ //Color?
508+
509+ jsonWriter.WriteEndObject( );
510+ jsonWriter.WriteEndArray( );
511+ }
512+ jsonWriter.WriteEndArray( );
513+ jsonWriter.WriteEndConstructor();
514+
515+ jsonWriter.WriteRaw(";\n");
370516
371517 jsonWriter.Flush();
372518 }
519+ }
373520
374521 }
375522
@@ -484,7 +631,7 @@ namespace Automap
484631 /// <param name="key">Chunk Coordinate</param>
485632 /// <param name="mapChunk">Map chunk.</param>
486633 /// <param name="chunkMeta">Chunk metadata</param>
487- private void ProcessChunkBlocks(Vec2i key, IMapChunk mapChunk, ColumnMeta chunkMeta)
634+ private void ProcessChunkBlocks(Vec2i key, IMapChunk mapChunk, ref ColumnMeta chunkMeta)
488635 {
489636
490637 int targetChunkY = mapChunk.YMax / chunkSize;//Surface ...
@@ -571,12 +718,12 @@ namespace Automap
571718 {
572719 Logger.Debug("Presently {0} Entities", ClientAPI.World.LoadedEntities.Count);
573720 //Mabey scan only for 'new' entities by tracking ID in set?
574- foreach (var loadedEntity in ClientAPI.World.LoadedEntities.ToList())
721+ foreach (var loadedEntity in ClientAPI.World.LoadedEntities.ToArray())
575722 {
576723
577-#if DEBUG
724+ #if DEBUG
578725 //Logger.VerboseDebug($"ENTITY: ({loadedEntity.Value.Code}) = #{loadedEntity.Value.EntityId} {loadedEntity.Value.State} {loadedEntity.Value.LocalPos} <<<<<<<<<<<<");
579-#endif
726+ #endif
580727
581728 var dMatch = Entity_Designators.SingleOrDefault(se => se.Key.Equals(loadedEntity.Value.Code));
582729 if (dMatch.Value != null)
@@ -611,26 +758,26 @@ namespace Automap
611758 CommandData cmdData = data as CommandData;
612759
613760
614- if (CurrentState != RunState.Snapshot)
761+ if (CurrentState != CommandType.Snapshot)
615762 {
616763 switch (cmdData.State)
617764 {
618- case RunState.Run:
765+ case CommandType.Run:
619766 CurrentState = cmdData.State;
620767 AwakenCartographer(0.0f);
621768 break;
622769
623- case RunState.Stop:
770+ case CommandType.Stop:
624771 CurrentState = cmdData.State;
625772 break;
626773
627- case RunState.Snapshot:
628- CurrentState = RunState.Stop;
774+ case CommandType.Snapshot:
775+ CurrentState = CommandType.Stop;
629776 //Snapshot starts a second thread/process...
630777
631778 break;
632779
633- case RunState.Notation:
780+ case CommandType.Notation:
634781 //Add to POI list where player location
635782 AddNote(cmdData.Notation);
636783 break;