• R/O
  • HTTP
  • SSH
  • HTTPS

Commit

Tags
No Tags

Frequently used words (click to add to your profile)

javac++androidlinuxc#objective-cqt誰得windowscocoapythonphprubygameguibathyscaphec翻訳omegat計画中(planning stage)frameworktwittertestdomvb.netdirectxbtronarduinopreviewerゲームエンジン

Automap (client) [VS plugin mod]


Commit MetaInfo

Revision932d2165779ad60d317ce0713a944d05e42864bf (tree)
Time2019-12-12 07:15:50
Authormelchior <melchior@user...>
Commitermelchior

Log Message

Metadata collection capability, added tooltips on map

Change Summary

Incremental Difference

--- a/Automap/Automap.csproj
+++ b/Automap/Automap.csproj
@@ -71,6 +71,7 @@
7171 <Compile Include="Data\Designator.cs" />
7272 <Compile Include="Automap_Internals.cs" />
7373 <Compile Include="Designators\DefaultDesignators.cs" />
74+ <Compile Include="Data\ColumnMeta.cs" />
7475 </ItemGroup>
7576 <ItemGroup>
7677 <Folder Include="VS_libs\" />
--- a/Automap/Automap_Internals.cs
+++ b/Automap/Automap_Internals.cs
@@ -25,16 +25,13 @@ namespace Automap
2525 private const string _chunkPath = @"Chunks";
2626 private const string _domain = @"automap";
2727
28- private ConcurrentDictionary<Vec2i, uint> columnCounter = new ConcurrentDictionary<Vec2i, uint>(3, 103 );//ChunkMeta struct?
29- private HashSet<Vec2i> knownChunkTops = new HashSet<Vec2i>( );
28+ private ConcurrentDictionary<Vec2i, uint> columnCounter = new ConcurrentDictionary<Vec2i, uint>(3, 150 );
29+ private ColumnsMetadata chunkTopMetadata;
3030
3131 private PointsOfInterest POIs;
3232 private Dictionary<int, Designator> BlockID_Designators;
3333
34- private int North_mostChunk;
35- private int East_mostChunk;
36- private int West_mostChunk;
37- private int South_mostChunk;
34+
3835 private Vec2i startChunkColumn;
3936 private uint lastUpdate;
4037
@@ -45,18 +42,14 @@ namespace Automap
4542 private void StartAutomap( )
4643 {
4744 path = ClientAPI.GetOrCreateDataPath(_mapPath);
48- path = ClientAPI.GetOrCreateDataPath(Path.Combine(path, "World_" + ClientAPI.World.Seed));//Add name of World too!
45+ path = ClientAPI.GetOrCreateDataPath(Path.Combine(path, "World_" + ClientAPI.World.Seed));//Add name of World too...'ServerApi.WorldManager.CurrentWorldName'
4946
5047 stylesFile = ClientAPI.World.AssetManager.Get(new AssetLocation(_domain, "config/automap_format.css"));
5148 Logger.VerboseDebug("CSS loaded: {0} size: {1}",stylesFile.IsLoaded() ,stylesFile.ToText( ).Length);
5249
53-
5450 Prefill_POI_Designators( );
5551 startChunkColumn = new Vec2i((ClientAPI.World.Player.Entity.LocalPos.AsBlockPos.X / ClientAPI.World.BlockAccessor.ChunkSize), (ClientAPI.World.Player.Entity.LocalPos.AsBlockPos.Z / ClientAPI.World.BlockAccessor.ChunkSize));
56- North_mostChunk = startChunkColumn.Y;
57- South_mostChunk = startChunkColumn.Y;
58- East_mostChunk = startChunkColumn.X;
59- West_mostChunk = startChunkColumn.X;
52+ chunkTopMetadata = new ColumnsMetadata(startChunkColumn);
6053
6154 Logger.Notification("AUTOMAP Start {0}", startChunkColumn);
6255
@@ -74,7 +67,7 @@ namespace Automap
7467 {
7568 Vec2i topPosition = new Vec2i(chunkCoord.X, chunkCoord.Z);
7669
77- columnCounter.AddOrUpdate(topPosition, 1, (key, colAct) => colAct + 1);
70+ columnCounter.AddOrUpdate(topPosition, 1, (key, colAct) => colAct + 1);
7871 }
7972
8073 private void AwakenCartographer(float delayed)
@@ -92,7 +85,7 @@ namespace Automap
9285 //Time to (re)write chunk shards
9386 cartographer_thread.Interrupt( );
9487 }
95- ClientAPI.TriggerChatMessage($"Automap {lastUpdate} changes - MAX (N:{North_mostChunk},S:{South_mostChunk},E:{East_mostChunk}, W:{West_mostChunk} - TOTAL: {knownChunkTops.Count})");
88+ ClientAPI.TriggerChatMessage($"Automap {lastUpdate} changes - MAX (N:{chunkTopMetadata.North_mostChunk},S:{chunkTopMetadata.South_mostChunk},E:{chunkTopMetadata.East_mostChunk}, W:{chunkTopMetadata.West_mostChunk} - TOTAL: {chunkTopMetadata.Count})");
9689 }
9790
9891 }
@@ -106,6 +99,7 @@ namespace Automap
10699 try {
107100 uint ejectedItem = 0;
108101 uint updatedChunks = 0;
102+
109103
110104 //-- Should dodge enumerator changing underfoot....at a cost.
111105 if (!columnCounter.IsEmpty) {
@@ -117,13 +111,15 @@ namespace Automap
117111 if (mapChunk == null) {
118112 Logger.Warning("SKIP CHUNK: ({0}) - Map Chunk NULL!", mostActiveCol.Key);
119113
120- columnCounter.TryRemove(mostActiveCol.Key, out ejectedItem);
114+ columnCounter.TryRemove(mostActiveCol.Key, out ejectedItem );
121115 continue;
122116 }
123117
124118 string filename = $"{mostActiveCol.Key.X}_{mostActiveCol.Key.Y}.png";
125119 filename = Path.Combine(path, filename);
126120
121+ var chunkMeta = UpdateColumnMetadata(mostActiveCol,mapChunk);
122+
127123 uint pixels = 0;
128124 var chkImg = GenerateChunkImage(mostActiveCol.Key, mapChunk, out pixels);
129125
@@ -133,7 +129,7 @@ namespace Automap
133129 Logger.VerboseDebug("Wrote chunk shard: ({0}) - Edits#:{1}, Pixels#:{2}", mostActiveCol.Key, mostActiveCol.Value, pixels);
134130 #endif
135131 updatedChunks++;
136- knownChunkTops.Add(mostActiveCol.Key);
132+ chunkTopMetadata.Update(chunkMeta);
137133 columnCounter.TryRemove(mostActiveCol.Key, out ejectedItem);
138134 }
139135 else {
@@ -168,7 +164,8 @@ namespace Automap
168164 Logger.VerboseDebug("Thread '{0}' executing finally block.", Thread.CurrentThread.Name);
169165 }
170166 }
171- #endregion
167+
168+ #endregion
172169
173170
174171 private void Prefill_POI_Designators( )
@@ -204,7 +201,7 @@ namespace Automap
204201
205202
206203 #region COPYPASTA
207- //TODO: rewrite - with alternate algo.
204+ //TODO: rewrite - with vertical ray caster, down to bottom-most chunk (for object detection...)
208205 //A slightly re-written; ChunkMapLayer :: public int[] GenerateChunkImage(Vec2i chunkPos, IMapChunk mc)
209206 internal Bitmap GenerateChunkImage(Vec2i chunkPos, IMapChunk mc, out uint pixelCount)
210207 {
@@ -326,11 +323,10 @@ namespace Automap
326323 {
327324 string mapFilename = Path.Combine(path, "Automap.html");
328325
329- North_mostChunk = knownChunkTops.Min(tc => tc.Y);
330- South_mostChunk = knownChunkTops.Max(tc => tc.Y);
331- East_mostChunk = knownChunkTops.Max(tc => tc.X);
332- West_mostChunk = knownChunkTops.Min(tc => tc.X);
333-
326+ int TopNorth = chunkTopMetadata.North_mostChunk;
327+ int TopSouth = chunkTopMetadata.South_mostChunk;
328+ int TopEast = chunkTopMetadata.East_mostChunk;
329+ int TopWest = chunkTopMetadata.West_mostChunk;
334330
335331 using (StreamWriter outputText = new StreamWriter(File.Open(mapFilename, FileMode.Create, FileAccess.Write, FileShare.ReadWrite))) {
336332 using (HtmlTextWriter tableWriter = new HtmlTextWriter(outputText)) {
@@ -353,7 +349,7 @@ namespace Automap
353349 tableWriter.WriteEncodedText($"Created {DateTimeOffset.UtcNow.ToString("u")}");
354350 tableWriter.RenderEndTag( );
355351 tableWriter.RenderBeginTag(HtmlTextWriterTag.P);
356- tableWriter.WriteEncodedText($"W:{West_mostChunk}, E: {East_mostChunk}, N:{North_mostChunk}, S:{South_mostChunk} ");
352+ tableWriter.WriteEncodedText($"W:{TopWest}, E: {TopEast}, N:{TopNorth}, S:{TopSouth} ");
357353 tableWriter.RenderEndTag( );
358354 tableWriter.WriteLine( );
359355 tableWriter.RenderBeginTag(HtmlTextWriterTag.Table);
@@ -369,7 +365,7 @@ namespace Automap
369365 tableWriter.Write("N, W");
370366 tableWriter.RenderEndTag( );
371367
372- for (int xAxisT = West_mostChunk; xAxisT <= East_mostChunk; xAxisT++) {
368+ for (int xAxisT = TopWest; xAxisT <= TopEast; xAxisT++) {
373369 tableWriter.RenderBeginTag(HtmlTextWriterTag.Th);
374370 tableWriter.Write(xAxisT);
375371 tableWriter.RenderEndTag( );
@@ -385,25 +381,44 @@ namespace Automap
385381
386382 //###### <tbody> - Chunk rows & Y-axis cols
387383 tableWriter.RenderBeginTag(HtmlTextWriterTag.Tbody);
384+
388385 //######## <tr> for every vertical row
389- for (int yAxis = North_mostChunk; yAxis <= South_mostChunk; yAxis++) {
386+ for (int yAxis = TopNorth; yAxis <= TopSouth; yAxis++) {
390387 tableWriter.RenderBeginTag(HtmlTextWriterTag.Tr);
391388 tableWriter.RenderBeginTag(HtmlTextWriterTag.Td);
392389 tableWriter.Write(yAxis);//legend: Y-axis
393390 tableWriter.RenderEndTag( );
394391
395- for (int xAxis = West_mostChunk; xAxis <= East_mostChunk; xAxis++) {
392+ for (int xAxis = TopWest; xAxis <= TopEast; xAxis++) {
396393 //###### <td> #### for chunk shard
397394 tableWriter.RenderBeginTag(HtmlTextWriterTag.Td);
398- if (knownChunkTops.Contains( new Vec2i(xAxis, yAxis))){
399- tableWriter.AddAttribute(HtmlTextWriterAttribute.Src, $"{xAxis}_{yAxis}.png");
400- tableWriter.AddAttribute(HtmlTextWriterAttribute.Alt, $"X{xAxis}, Y{yAxis}");
395+ var colLoc = new Vec2i(xAxis, yAxis);
396+ if (chunkTopMetadata.Contains( colLoc)){
397+ ColumnMeta meta = chunkTopMetadata[colLoc];
398+ //Tooltip first
399+ tableWriter.AddAttribute(HtmlTextWriterAttribute.Class, "tooltip");
400+ tableWriter.RenderBeginTag(HtmlTextWriterTag.Div);
401+
402+ tableWriter.AddAttribute(HtmlTextWriterAttribute.Src, $"{xAxis}_{yAxis}.png");
401403 tableWriter.RenderBeginTag(HtmlTextWriterTag.Img);
402404 tableWriter.RenderEndTag( );
405+ // <span class="tooltiptext">Tooltip text
406+ tableWriter.AddAttribute(HtmlTextWriterAttribute.Class, "tooltiptext");
407+ tableWriter.RenderBeginTag(HtmlTextWriterTag.Span);
408+ tableWriter.WriteEncodedText($"{meta.Location.PrettyCoords(ClientAPI)} "+
409+ $" Max-Height: {meta.YMax}, Temp: {meta.Temperature.ToString("F1")}"
410+ );
411+ tableWriter.RenderEndTag( );//</span>
412+
413+
414+
415+
416+ tableWriter.RenderEndTag( );//</div> --tooltip enclosure
403417 }
404418 else {
405419 tableWriter.Write("?");
406- }
420+ }
421+
407422 tableWriter.RenderEndTag( );
408423 }//############ </td> ###########
409424
@@ -412,8 +427,7 @@ namespace Automap
412427 tableWriter.RenderEndTag( );
413428
414429 tableWriter.RenderEndTag( );
415- tableWriter.EndRender( );
416- tableWriter.Flush( );
430+
417431 }
418432 tableWriter.RenderEndTag( );
419433
@@ -425,7 +439,7 @@ namespace Automap
425439 tableWriter.Write("S, W");
426440 tableWriter.RenderEndTag( );
427441
428- for (int xAxisB = West_mostChunk; xAxisB <= East_mostChunk; xAxisB++) {
442+ for (int xAxisB = TopWest; xAxisB <= TopEast; xAxisB++) {
429443 tableWriter.RenderBeginTag(HtmlTextWriterTag.Td);
430444 tableWriter.Write(xAxisB);
431445 tableWriter.RenderEndTag( );
@@ -454,7 +468,7 @@ namespace Automap
454468
455469 tableWriter.RenderEndTag( );
456470 tableWriter.RenderEndTag( );
457- tableWriter.RenderEndTag( );
471+
458472
459473 tableWriter.EndRender( );
460474 tableWriter.Flush( );
@@ -467,6 +481,21 @@ namespace Automap
467481
468482
469483
484+ private ColumnMeta UpdateColumnMetadata(KeyValuePair<Vec2i, uint> mostActiveCol, IMapChunk mapChunk)
485+ {
486+ ColumnMeta data = new ColumnMeta(mostActiveCol.Key.Copy());
487+ BlockPos equivBP = new BlockPos(mostActiveCol.Key.X * ClientAPI.World.BlockAccessor.ChunkSize,
488+ mapChunk.YMax,
489+ mostActiveCol.Key.Y * ClientAPI.World.BlockAccessor.ChunkSize);
490+
491+ var climate = ClientAPI.World.BlockAccessor.GetClimateAt(equivBP);
492+ data.Temperature = climate.Temperature;
493+ data.YMax = mapChunk.YMax;
494+
495+
496+
497+ return data;
498+ }
470499 }
471500
472501 }
\ No newline at end of file
--- /dev/null
+++ b/Automap/Data/ColumnMeta.cs
@@ -0,0 +1,98 @@
1+using System;
2+using System.Collections.Generic;
3+using System.Collections.ObjectModel;
4+using System.Linq;
5+
6+using Vintagestory.API.MathTools;
7+
8+namespace Automap
9+{
10+
11+ public struct ColumnMeta
12+ {
13+ public Vec2i Location;
14+ public float Temperature;// Temperature
15+ public int YMax;// Y feature height
16+ public Dictionary<int,uint> RockRatio;//(surface) Geographic region (rock) Ratio. [BlockID * count]
17+
18+ public ColumnMeta(Vec2i loc)
19+ {
20+ Location = loc;
21+ Temperature = 0f;
22+ YMax = 0;
23+ RockRatio = new Dictionary<int, uint>( 10 );
24+ }
25+ }
26+
27+ public class ColumnsMetadata : KeyedCollection<Vec2i, ColumnMeta>
28+ {
29+ private ColumnsMetadata( )
30+ {
31+ throw new NotSupportedException();
32+ }
33+
34+ public ColumnsMetadata(Vec2i startChunkColumn)
35+ {
36+ North_mostChunk = startChunkColumn.Y;
37+ South_mostChunk = startChunkColumn.Y;
38+ East_mostChunk = startChunkColumn.X;
39+ West_mostChunk = startChunkColumn.X;
40+ }
41+
42+ public int North_mostChunk {
43+ get; private set;
44+ }
45+
46+ public int South_mostChunk {
47+ get; private set;
48+ }
49+
50+ public int East_mostChunk {
51+ get; private set;
52+ }
53+
54+ public int West_mostChunk {
55+ get; private set;
56+ }
57+
58+ protected override Vec2i GetKeyForItem(ColumnMeta item)
59+ {
60+ return item.Location;
61+ }
62+
63+ internal void Update(ColumnMeta metaData)
64+ {
65+ if (this.Contains(metaData.Location)) {
66+ this.Remove(metaData.Location);
67+ this.Add(metaData);
68+ }
69+ else {
70+ this.Add(metaData);
71+ }
72+
73+ }
74+
75+ public new void Add(ColumnMeta newItem)
76+ {
77+ if (North_mostChunk > newItem.Location.Y) {
78+ North_mostChunk = newItem.Location.Y;
79+ }
80+
81+ if (South_mostChunk < newItem.Location.Y) {
82+ South_mostChunk = newItem.Location.Y;
83+ }
84+
85+ if (East_mostChunk < newItem.Location.X) {
86+ East_mostChunk = newItem.Location.X;
87+ }
88+
89+ if (West_mostChunk > newItem.Location.X) {
90+ West_mostChunk = newItem.Location.X;
91+ }
92+
93+ base.Add(newItem);
94+ }
95+
96+ }
97+}
98+
--- a/Automap/Designators/DefaultDesignators.cs
+++ b/Automap/Designators/DefaultDesignators.cs
@@ -42,6 +42,14 @@ namespace Automap
4242 DecodePostSign
4343 );
4444
45+ public static Designator Translocators =
46+ new Designator(
47+ new AssetLocation("game", "statictranslocator-normal"),
48+ Color.Violet,
49+ EnumBlockMaterial.Metal
50+ //DecodeTranslocator
51+ );
52+
4553 internal static void DecodeSign(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
4654 {
4755 clientAPI.Logger.VerboseDebug("Sign Designator Invoked!");
--- a/Automap/Helpers.cs
+++ b/Automap/Helpers.cs
@@ -51,6 +51,19 @@ namespace Automap
5151 return string.Format("X{0}, Y{1}, Z{2}", location.X - start.X, location.Y, location.Z - start.Z );
5252 }
5353
54+ /// <summary>
55+ /// Chunk location to User display coordinate system
56+ /// </summary>
57+ /// <returns>Friendly string</returns>
58+ /// <param name="location">Chunk Coords.</param>
59+ public static string PrettyCoords(this Vec2i location, ICoreClientAPI ClientApi)
60+ {
61+ var start = ClientApi.World.DefaultSpawnPosition.AsBlockPos;
62+ var chunkSize = ClientApi.World.BlockAccessor.ChunkSize;
63+
64+ return string.Format("X{0}, Z{1}", (location.X*chunkSize) - start.X, (location.Y*chunkSize) - start.Z);
65+ }
66+
5467 public static BlockPos AverageHighestPos(List<BlockPos> positions)
5568 {
5669 int x = 0, y = 0, z = 0, length = positions.Count;
--- a/Automap/assets/automap/config/automap_format.css
+++ b/Automap/assets/automap/config/automap_format.css
@@ -1,7 +1,6 @@
11 table {
22 border: 1px solid black;
33 border-collapse: collapse;
4-overflow:hidden;
54 }
65
76 thead tr th {
@@ -38,7 +37,39 @@ padding: 0px;
3837 border: 0px none black;
3938 max-width: 32px;
4039 background-color: white;
41-overflow:hidden;
4240 width:32px;
4341 font-size: 6pt;
44-}
\ No newline at end of file
42+}
43+
44+/* Tooltip container */
45+.tooltip {
46+position: relative;
47+display: inline-block;
48+}
49+
50+/* Tooltip text */
51+.tooltip .tooltiptext {
52+visibility: hidden;
53+background-color: black;
54+color: #fff;
55+text-align: center;
56+padding: 5px 0;
57+position: absolute;
58+z-index: 1;
59+}
60+
61+/* Show the tooltip text when you mouse over the tooltip container */
62+.tooltip:hover .tooltiptext {
63+left: 33px;
64+top: 33px;
65+opacity: 0.75;
66+position: absolute;
67+visibility: visible;
68+min-width: 120px;
69+box-shadow: 5px 5px 8px 12px black;
70+}
71+
72+.tooltip img:hover {
73+outline: 1px dashed orange;
74+opacity: 0.9;
75+}