Automap (client) [VS plugin mod]
修訂 | cdc29d29d788f9126faee33e48c4f65968b49702 (tree) |
---|---|
時間 | 2020-03-29 03:44:50 |
作者 | The Grand Dog <alex.h@me.c...> |
Commiter | The Grand Dog |
fully implement the most advanced version of the map so far
there are SO many changes
@@ -95,6 +95,7 @@ | ||
95 | 95 | <Compile Include="Data\CommandData.cs" /> |
96 | 96 | <Compile Include="Data\CommandType.cs" /> |
97 | 97 | <Compile Include="Data\PersistedConfiguration.cs" /> |
98 | + <Compile Include="Data\DisplayNameAttribute.cs" /> | |
98 | 99 | </ItemGroup> |
99 | 100 | <ItemGroup> |
100 | 101 | <Folder Include="VS_libs\" /> |
@@ -1,6 +1,5 @@ | ||
1 | 1 | using System; |
2 | 2 | using System.Collections.Generic; |
3 | -using System.Collections.ObjectModel; | |
4 | 3 | using System.Collections.Specialized; |
5 | 4 | |
6 | 5 |
@@ -8,7 +7,10 @@ using Vintagestory.API.MathTools; | ||
8 | 7 | using Vintagestory.API.Common; |
9 | 8 | |
10 | 9 | using ProtoBuf; |
11 | - | |
10 | +using System.IO; | |
11 | +using System.Collections.ObjectModel; | |
12 | +using System.Text; | |
13 | +using Vintagestory.API.Client; | |
12 | 14 | |
13 | 15 | namespace Automap |
14 | 16 | { |
@@ -16,36 +18,47 @@ namespace Automap | ||
16 | 18 | public struct ColumnMeta |
17 | 19 | { |
18 | 20 | [ProtoMember(1)] |
21 | + [DisplayName(0, "Coords.")] | |
19 | 22 | public Vec2i Location; |
20 | 23 | |
21 | 24 | [ProtoMember(2)] |
25 | + [DisplayName(1, "Age")] | |
22 | 26 | public TimeSpan ChunkAge;//OLDEST CHUNK. from chunk last edit |
23 | 27 | |
24 | 28 | [ProtoMember(3)] |
29 | + [DisplayName(2, "Temp.")] | |
25 | 30 | public float Temperature;// Temperature - surface |
26 | 31 | |
27 | 32 | [ProtoMember(4)] |
33 | + [DisplayName(3, "Y Max.")] | |
28 | 34 | public ushort YMax;// Y feature height |
29 | 35 | |
30 | 36 | [ProtoMember(5)] |
37 | + //[DisplayName(10, "Rocks")] | |
31 | 38 | public Dictionary<int, uint> RockRatio;//[Column] Geographic region (rock) Ratio. [BlockID * count] |
32 | 39 | |
33 | 40 | [ProtoMember(6)] |
41 | + [DisplayName(4, "Fert.")] | |
34 | 42 | public float Fertility; |
35 | 43 | |
36 | 44 | [ProtoMember(7)] |
45 | + [DisplayName(5, "Forest")] | |
37 | 46 | public float ForestDensity; |
38 | 47 | |
39 | 48 | [ProtoMember(8)] |
49 | + [DisplayName(6, "Rain")] | |
40 | 50 | public float Rainfall; |
41 | 51 | |
42 | 52 | [ProtoMember(9)] |
53 | + [DisplayName(7, "Shrub")] | |
43 | 54 | public float ShrubDensity; |
44 | 55 | |
45 | 56 | [ProtoMember(10)] |
57 | + [DisplayName(8, "Air blocks")] | |
46 | 58 | public uint AirBlocks; |
47 | 59 | |
48 | 60 | [ProtoMember(11)] |
61 | + [DisplayName(9, "Non-air")] | |
49 | 62 | public uint NonAirBlocks; |
50 | 63 | |
51 | 64 | [ProtoMember(12)] |
@@ -56,7 +69,7 @@ namespace Automap | ||
56 | 69 | public ushort[,] HeightMap;//Needs to be 'flattened' for Protocol-Buffer serialization |
57 | 70 | |
58 | 71 | [ProtoMember(13)] |
59 | - private ushort[ ] _flattened_HeightMap; | |
72 | + private ushort[] _flattened_HeightMap; | |
60 | 73 | |
61 | 74 | |
62 | 75 | public ColumnMeta(Vec2i loc, byte chunkSize = 32) |
@@ -89,48 +102,70 @@ namespace Automap | ||
89 | 102 | this.YMax = mapChunk.YMax; |
90 | 103 | } |
91 | 104 | |
92 | - | |
105 | + public void Write(StreamWriter stream, ICoreClientAPI ClientApi) | |
106 | + { | |
107 | + // this is gross i hate this | |
108 | + stream.Write("['{0}_{1}',[", | |
109 | + Location.X, | |
110 | + Location.Y | |
111 | + ); | |
112 | + stream.Write("'{0}',", Location.PrettyCoords(ClientApi)); | |
113 | + stream.Write("'{0}',", ChunkAge); | |
114 | + stream.Write("'{0}',", Temperature.ToString("F3")); | |
115 | + stream.Write("'{0}',", YMax); | |
116 | + stream.Write("'{0}',", Fertility.ToString("F3")); | |
117 | + stream.Write("'{0}',", ForestDensity.ToString("F3")); | |
118 | + stream.Write("'{0}',", Rainfall.ToString("F3")); | |
119 | + stream.Write("'{0}',", ShrubDensity.ToString("F3")); | |
120 | + stream.Write("'{0}',", AirBlocks); | |
121 | + stream.Write("'{0}',", NonAirBlocks); | |
122 | + stream.Write("]]"); | |
123 | + } | |
93 | 124 | |
94 | 125 | [ProtoBeforeSerialization] |
95 | - private void PrepareData( ) | |
126 | + private void PrepareData() | |
96 | 127 | { |
97 | 128 | |
98 | - if (HeightMap != null) { | |
99 | - _flattened_HeightMap = new ushort[ChunkSize * ChunkSize]; | |
100 | - int flatIndex = 0; | |
129 | + if (HeightMap != null) | |
130 | + { | |
131 | + _flattened_HeightMap = new ushort[ChunkSize * ChunkSize]; | |
132 | + int flatIndex = 0; | |
133 | + | |
134 | + for (byte col = 0; col < ChunkSize; col++) | |
135 | + { | |
136 | + for (byte row = 0; row < ChunkSize; row++) | |
137 | + { | |
138 | + _flattened_HeightMap[flatIndex] = HeightMap[col, row]; | |
139 | + flatIndex++; | |
140 | + } | |
141 | + } | |
101 | 142 | |
102 | - for (byte col = 0; col < ChunkSize; col++) { | |
103 | - for (byte row = 0; row < ChunkSize; row++) { | |
104 | - _flattened_HeightMap[flatIndex] = HeightMap[col, row]; | |
105 | - flatIndex++; | |
106 | 143 | } |
107 | - } | |
108 | - | |
109 | - } | |
110 | 144 | |
111 | 145 | } |
112 | 146 | |
113 | 147 | |
114 | 148 | [ProtoAfterDeserialization] |
115 | - private void PostProcess( ) | |
149 | + private void PostProcess() | |
116 | 150 | { |
117 | - if (this.HeightMap == null) this.HeightMap = new ushort[ChunkSize, ChunkSize]; | |
118 | - | |
119 | - if (_flattened_HeightMap != null) { | |
120 | - int col, row; | |
151 | + if (this.HeightMap == null) this.HeightMap = new ushort[ChunkSize, ChunkSize]; | |
121 | 152 | |
122 | - BitVector32 bitMasker = new BitVector32(0); | |
123 | - var rowSection = BitVector32.CreateSection(( short )(ChunkSize - 1)); | |
124 | - var colSection = BitVector32.CreateSection(( short )(ChunkSize - 1), rowSection); | |
125 | - | |
126 | - for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++) { | |
127 | - bitMasker = new BitVector32(data: ( int )rowcol); | |
128 | - row = bitMasker[rowSection]; | |
129 | - col = bitMasker[colSection]; | |
130 | - HeightMap[col, row] = _flattened_HeightMap[rowcol]; | |
131 | - } | |
153 | + if (_flattened_HeightMap != null) | |
154 | + { | |
155 | + int col, row; | |
156 | + _ = new BitVector32(0); | |
157 | + var rowSection = BitVector32.CreateSection((short) (ChunkSize - 1)); | |
158 | + var colSection = BitVector32.CreateSection((short) (ChunkSize - 1), rowSection); | |
159 | + | |
160 | + for (uint rowcol = 0; rowcol < (ChunkSize * ChunkSize); rowcol++) | |
161 | + { | |
162 | + BitVector32 bitMasker = new BitVector32(data: (int) rowcol); | |
163 | + row = bitMasker[rowSection]; | |
164 | + col = bitMasker[colSection]; | |
165 | + HeightMap[col, row] = _flattened_HeightMap[rowcol]; | |
166 | + } | |
132 | 167 | |
133 | - } | |
168 | + } | |
134 | 169 | |
135 | 170 | } |
136 | 171 |
@@ -217,5 +252,4 @@ namespace Automap | ||
217 | 252 | } |
218 | 253 | |
219 | 254 | } |
220 | -} | |
221 | - | |
255 | +} | |
\ No newline at end of file |
@@ -0,0 +1,17 @@ | ||
1 | +using System; | |
2 | +using System.Reflection; | |
3 | + | |
4 | +namespace Automap | |
5 | +{ | |
6 | + [AttributeUsage(AttributeTargets.Field)] | |
7 | + public class DisplayNameAttribute : Attribute | |
8 | + { | |
9 | + public string name; | |
10 | + public byte order; | |
11 | + public DisplayNameAttribute(byte order, string name) | |
12 | + { | |
13 | + this.order = order; | |
14 | + this.name = name; | |
15 | + } | |
16 | + } | |
17 | +} | |
\ No newline at end of file |
@@ -1,11 +1,11 @@ | ||
1 | 1 | using System; |
2 | 2 | using System.Collections.Generic; |
3 | 3 | using System.Collections.ObjectModel; |
4 | - | |
4 | +using System.IO; | |
5 | 5 | using System.Linq; |
6 | - | |
7 | 6 | using Vintagestory.API.Common.Entities; |
8 | 7 | using Vintagestory.API.MathTools; |
8 | +using Vintagestory.API.Client; | |
9 | 9 | |
10 | 10 | namespace Automap |
11 | 11 | { |
@@ -14,10 +14,27 @@ namespace Automap | ||
14 | 14 | /// </summary> |
15 | 15 | public struct EntityOfInterest |
16 | 16 | { |
17 | + [DisplayName(1, "Notes")] | |
17 | 18 | public string Notes; |
19 | + [DisplayName(0, "Loc.")] | |
18 | 20 | public BlockPos Location; |
21 | + [DisplayName(2, "Time")] | |
19 | 22 | public DateTimeOffset Timestamp; |
23 | + [DisplayName(3, "ID")] | |
20 | 24 | public long EntityId; |
25 | + public void Write(StreamWriter stream, ICoreClientAPI ClientApi) | |
26 | + { | |
27 | + // this is gross i hate this | |
28 | + stream.Write("['{0}_{1}',[", | |
29 | + Location.X, | |
30 | + Location.Y | |
31 | + ); | |
32 | + stream.Write("'{0}',", Location.PrettyCoords(ClientApi)); | |
33 | + stream.Write("'{0}',", System.Web.HttpUtility.HtmlEncode(Notes)); | |
34 | + stream.Write("'{0}',", Timestamp); | |
35 | + stream.Write("'{0}',", EntityId); | |
36 | + stream.Write("]]"); | |
37 | + } | |
21 | 38 | } |
22 | 39 | |
23 | 40 | /// <summary> |
@@ -1,6 +1,7 @@ | ||
1 | 1 | using System; |
2 | 2 | using System.Collections.ObjectModel; |
3 | - | |
3 | +using System.IO; | |
4 | +using Vintagestory.API.Client; | |
4 | 5 | using Vintagestory.API.Common; |
5 | 6 | using Vintagestory.API.MathTools; |
6 | 7 |
@@ -11,9 +12,24 @@ namespace Automap | ||
11 | 12 | /// </summary> |
12 | 13 | public struct PointOfInterest |
13 | 14 | { |
15 | + [DisplayName(1, "Notes")] | |
14 | 16 | public string Notes; |
17 | + [DisplayName(0, "Loc.")] | |
15 | 18 | public BlockPos Location; |
19 | + [DisplayName(2, "Time")] | |
16 | 20 | public DateTimeOffset Timestamp; |
21 | + public void Write(StreamWriter stream, ICoreClientAPI ClientApi) | |
22 | + { | |
23 | + // this is gross i hate this | |
24 | + stream.Write("['{0}_{1}',[", | |
25 | + Location.X, | |
26 | + Location.Y | |
27 | + ); | |
28 | + stream.Write("'{0}',", Location.PrettyCoords(ClientApi)); | |
29 | + stream.Write("'{0}',", System.Web.HttpUtility.HtmlEncode(Notes).Replace("\n", " ").Replace("\\","\\\\")); | |
30 | + stream.Write("'{0}',", Timestamp); | |
31 | + stream.Write("]]"); | |
32 | + } | |
17 | 33 | } |
18 | 34 | |
19 | 35 | public class PointsOfInterest : KeyedCollection<BlockPos, PointOfInterest> |
@@ -0,0 +1,22 @@ | ||
1 | +#!/usr/local/bin/node | |
2 | + | |
3 | +// im sorry | |
4 | +// cd into MapSRC and run node ./build.js and this will concat and stuff | |
5 | +const fs = require('fs'); | |
6 | + | |
7 | +fs.readFile('./src/Automap.html', 'utf8', (err, d) => { | |
8 | + if (err) console.log(err); | |
9 | + let outD = d.replace(/<link rel=\"stylesheet\" href=\"(.*)\">/g, '<style>REP:$1</style>') | |
10 | + .replace(/(<script type=\"text\/javascript\") src=\"(.*)\">/g, '$1>REP:$2') | |
11 | + .replace(/REP:(\w*\.\w*)/g, (match, name, offset, string) => { | |
12 | + return fs.readFileSync('./src/' + name, 'utf8') | |
13 | + .replace(/\/\/.*\n?/g, ''); | |
14 | + }) | |
15 | + .replace(/[\t\n]/g, ''); | |
16 | + fs.writeFile('./dist/automap.html', outD, err => { | |
17 | + if (err) console.log(err); | |
18 | + }); | |
19 | + fs.writeFile('../assets/automap/config/automap.html', outD, err => { | |
20 | + if (err) console.log(err); | |
21 | + }); | |
22 | +}); | |
\ No newline at end of file |
@@ -0,0 +1,38 @@ | ||
1 | +html, body, .map { | |
2 | + width: 100%; | |
3 | + height: 100%; | |
4 | + margin: 0; | |
5 | + overflow: hidden; | |
6 | + outline: 1px dotted black; | |
7 | +} | |
8 | + | |
9 | +.infobox { | |
10 | + width: 15em; | |
11 | + /* height: 15em; */ | |
12 | + background-color: rgba(200, 200, 200, 0.5); | |
13 | + left: 0; | |
14 | + top: 0; | |
15 | + font-family: sans-serif; | |
16 | + position: absolute; | |
17 | + z-index: 1; | |
18 | +} | |
19 | + | |
20 | +h1 { | |
21 | + font-size: 22px; | |
22 | + margin: .6em 1em; | |
23 | + text-align: center; | |
24 | +} | |
25 | + | |
26 | +.infoboxTable { | |
27 | + margin: .3em auto; | |
28 | + width: 90%; | |
29 | + outline: 1px solid #333; | |
30 | +} | |
31 | + | |
32 | +.infoboxTable th { | |
33 | + width: 30%; | |
34 | +} | |
35 | + | |
36 | +.infoboxTable td { | |
37 | + text-align: right; | |
38 | +} | |
\ No newline at end of file |
@@ -0,0 +1,22 @@ | ||
1 | +<!DOCTYPE html> | |
2 | +<html lang="en" dir="ltr"> | |
3 | + | |
4 | +<head> | |
5 | + <meta charset="utf-8"> | |
6 | + <title>Automap</title> | |
7 | + <link rel="stylesheet" href="Automap.css"> | |
8 | +</head> | |
9 | + | |
10 | +<body> | |
11 | + <script type="text/javascript" src="ViewFrame.js"></script> | |
12 | + <script type="text/javascript" src="ViewFrameUtils.js"></script> | |
13 | + <div class="infobox"> | |
14 | + <h1>Chunk Info</h1> | |
15 | + <table class="infoboxTable"> | |
16 | + </table> | |
17 | + </div> | |
18 | + <script type="text/javascript" src="index.js"></script> | |
19 | + | |
20 | +</body> | |
21 | + | |
22 | +</html> | |
\ No newline at end of file |
@@ -0,0 +1,140 @@ | ||
1 | +function ViewFrame() { | |
2 | + // dom stuff | |
3 | + const map = document.createElement('canvas'); // the map we see | |
4 | + map.className = 'map'; | |
5 | + map.height = window.innerHeight; | |
6 | + map.width = window.innerWidth; | |
7 | + document.getElementsByTagName('body')[0].append(map); | |
8 | + // this is the map that we actually draw on | |
9 | + this.map = map.getContext('2d', { | |
10 | + alpha: false | |
11 | + }); | |
12 | + this.map.imageSmoothingEnabled = false; | |
13 | + | |
14 | + // the info box in the corner | |
15 | + this.infobox = document.getElementsByClassName('infoboxTable')[0]; | |
16 | + this.infoboxSlots = new Array(); | |
17 | + | |
18 | + // load the metadata! | |
19 | + this.chunkScript = document.createElement('script'); | |
20 | + this.chunkScript.type = 'text/javascript'; | |
21 | + this.chunkScript.src = 'Metadata.js'; | |
22 | + document.getElementsByTagName('body')[0].append(this.chunkScript); | |
23 | + this.chunkScript.addEventListener('load', () => { | |
24 | + ViewFrame.initInfobox(this.infobox, this.infoboxSlots); | |
25 | + this.x = ViewFrame.chunks.startCoords[0]; | |
26 | + this.y = ViewFrame.chunks.startCoords[1]; | |
27 | + this.availableChunks = ViewFrame.chunks.chunkMetadata; | |
28 | + this.render(); | |
29 | + }, { | |
30 | + once: true | |
31 | + }); | |
32 | + | |
33 | + // Tracks images that have been loaded and are on the map | |
34 | + this.loadedChunksByName = new Map(); | |
35 | + // this is needed because [1, 2] != [1, 2] and thats how we store coords. | |
36 | + this.loadedChunksByCoords = new Map(); | |
37 | + this.availableChunks = null; // the chunks in ./Metadata.js | |
38 | + // so that we dont render twice at the same time | |
39 | + this.rendering = false; | |
40 | + | |
41 | + this.x = -1; | |
42 | + this.y = -1; // can be fractional | |
43 | + this.zoom = 32; // pixels wide the images are to be | |
44 | + this.updateEdges(); | |
45 | +} | |
46 | +// prototypes, some less... notable? methods are | |
47 | +// in ViewFrameUtils.js | |
48 | +ViewFrame.prototype.reloadChunkList = function () { | |
49 | + if (this.chunkScript) { | |
50 | + this.chunkScript.remove(); | |
51 | + delete this.chunkScript; | |
52 | + } | |
53 | + | |
54 | + this.chunkScript = document.createElement('script'); | |
55 | + this.chunkScript.type = 'text/javascript'; | |
56 | + this.chunkScript.src = 'Metadata.js'; | |
57 | + document.getElementsByTagName('body')[0].append(this.chunkScript); | |
58 | + | |
59 | + this.chunkScript.addEventListener('load', () => { | |
60 | + this.availableChunks = ViewFrame.chunks.chunkMetadata; | |
61 | + this.render(); | |
62 | + }); | |
63 | +}; | |
64 | + | |
65 | +ViewFrame.prototype.render = function () { | |
66 | + if (!this.availableChunks) return; | |
67 | + if (this.rendering) clearInterval(ViewFrame.intervalRef); | |
68 | + this.rendering = true; | |
69 | + this.updateEdges(); | |
70 | + this.map.clearRect(0, 0, window.innerWidth, window.innerHeight); | |
71 | + // culling | |
72 | + this.loadedChunksByCoords | |
73 | + .forEach((chunk, coord) => { // check the bounds | |
74 | + if (coord[0] < this.eastChunk && | |
75 | + coord[0] >= this.westChunk && | |
76 | + coord[1] <= this.northChunk && | |
77 | + coord[1] >= this.southChunk) { | |
78 | + | |
79 | + this.place(chunk, coord[0], coord[1]); | |
80 | + return; | |
81 | + } | |
82 | + // its out of range!!! | |
83 | + // get 'em boys!!!!! | |
84 | + this.loadedChunksByCoords.delete(coord); | |
85 | + this.loadedChunksByName.delete(coord.join('_')); | |
86 | + chunk.remove(); | |
87 | + }); | |
88 | + | |
89 | + // gathering what we need to load | |
90 | + const neededChunks = new Set(); | |
91 | + for (var x = this.westChunk; x < this.eastChunk; x++) { | |
92 | + for (var y = this.southChunk; y < this.northChunk; y++) { | |
93 | + const chunKey = [x, y]; // chunk + key = chunKey :) | |
94 | + const name = chunKey.join('_'); | |
95 | + // continue if its not available, or it is loaded | |
96 | + if (!this.availableChunks.has(name) || | |
97 | + this.loadedChunksByName.has(name)) continue; | |
98 | + neededChunks.add(chunKey); | |
99 | + } | |
100 | + } | |
101 | + // iterating over everything we need to load | |
102 | + const it = neededChunks.values(); | |
103 | + ViewFrame.intervalRef = setInterval(() => { | |
104 | + let round = it.next(); | |
105 | + if (!round.done) { | |
106 | + // load | |
107 | + const img = new Image(32, 32); | |
108 | + const name = round.value.join('_'); | |
109 | + | |
110 | + img.src = name + '.png'; | |
111 | + | |
112 | + decode(img, loadedImage => { | |
113 | + this.place(img, round.value[0], round.value[1]); | |
114 | + }); | |
115 | + this.loadedChunksByName.set(name, img); | |
116 | + this.loadedChunksByCoords.set(round.value, img); | |
117 | + } else { | |
118 | + clearInterval(ViewFrame.intervalRef); | |
119 | + this.rendering = false; | |
120 | + } | |
121 | + }, 4); | |
122 | +}; | |
123 | + | |
124 | +ViewFrame.prototype.place = function (img, x, y) { | |
125 | + x -= this.x; | |
126 | + y -= this.y; | |
127 | + x *= this.zoom; | |
128 | + y *= this.zoom; | |
129 | + x += this.width / 2; | |
130 | + y += this.height / 2; | |
131 | + | |
132 | + this.map.drawImage(img, Math.floor(x), Math.floor(y), this.zoom, this.zoom); | |
133 | +}; | |
134 | + | |
135 | +ViewFrame.prototype.updateInfobox = function (chunkName) { | |
136 | + const chunkMeta = this.availableChunks.get(chunkName); | |
137 | + this.infoboxSlots.forEach((l, k) => { | |
138 | + l.innerText = chunkMeta ? chunkMeta[k] : '0'; | |
139 | + }); | |
140 | +}; | |
\ No newline at end of file |
@@ -0,0 +1,62 @@ | ||
1 | +ViewFrame.initInfobox = function (ibox, iboxSlots) { | |
2 | + | |
3 | + ViewFrame.chunks | |
4 | + .chunkMetadataNames.forEach((item, i) => { | |
5 | + const slot = document.createElement('tr'); | |
6 | + const head = document.createElement('th'); | |
7 | + head.innerText = item; | |
8 | + const row = document.createElement('td'); | |
9 | + row.innerText = '0'; | |
10 | + iboxSlots[i] = row; | |
11 | + slot.append(head, row); | |
12 | + ibox.append(slot); | |
13 | + }); | |
14 | +}; | |
15 | + | |
16 | +ViewFrame.prototype.updateEdges = function () { | |
17 | + if (this.width != window.innerWidth || this.height != window.innerHeight) { | |
18 | + this.width = window.innerWidth; | |
19 | + this.map.canvas.width = this.width; | |
20 | + this.height = window.innerHeight; | |
21 | + this.map.canvas.height = this.height; | |
22 | + this.map.imageSmoothingEnabled = false; | |
23 | + } | |
24 | + const chunksWide = Math.ceil(this.width / this.zoom); | |
25 | + const chunksHigh = Math.ceil(this.height / this.zoom); | |
26 | + | |
27 | + this.east = this.x + chunksWide / 2; // this is fractional and is used to keep track of the edges of the window | |
28 | + this.eastChunk = Math.ceil(this.east); // this is not and is used to track the chunks that need to load | |
29 | + this.west = this.x - chunksWide / 2; | |
30 | + this.westChunk = Math.floor(this.west); | |
31 | + this.north = this.y + chunksHigh / 2; | |
32 | + this.northChunk = Math.ceil(this.north); | |
33 | + this.south = this.y - chunksHigh / 2; | |
34 | + this.southChunk = Math.floor(this.south); | |
35 | +}; | |
36 | + | |
37 | +ViewFrame.prototype.moveCenter = function (dx, dy) { | |
38 | + // to pan when we click on the map! | |
39 | + this.x += (dx - this.width / 2) / this.zoom; | |
40 | + this.y += (dy - this.height / 2) / this.zoom; | |
41 | +}; | |
42 | +ViewFrame.prototype.setCenter = function (x, y) { | |
43 | + this.x = x; | |
44 | + this.y = y; | |
45 | +}; | |
46 | + | |
47 | +ViewFrame.prototype.clear = function () { | |
48 | + this.loadedChunksByName.clear(); | |
49 | + this.loadedChunksByCoords.clear(); | |
50 | + if (this.chunkScript) this.chunkScript.remove(); | |
51 | + delete this.chunkScript; | |
52 | + delete ViewFrame.chunks; | |
53 | + this.map.clearRect(0, 0, window.innerWidth, window.innerHeight); | |
54 | +}; | |
55 | + | |
56 | +function decode(img, cb) { | |
57 | + img.decode() | |
58 | + .then(() => { | |
59 | + cb(img); | |
60 | + }) | |
61 | + .catch(() => {}); // so images arent added on error | |
62 | +} | |
\ No newline at end of file |
@@ -0,0 +1,93 @@ | ||
1 | +const vf = new ViewFrame(); | |
2 | +vf.reloadChunkList(); | |
3 | + | |
4 | +// the event handlers are in iifes so they dont make unneeded globals. | |
5 | +// resize, delay re-render to reduce lag. | |
6 | +(function () { | |
7 | + var id; | |
8 | + window.addEventListener('resize', () => { | |
9 | + clearTimeout(id); | |
10 | + id = setTimeout(() => { | |
11 | + vf.render(); | |
12 | + }, 500); | |
13 | + }); | |
14 | +}()); | |
15 | + | |
16 | +// panning | |
17 | +(function () { | |
18 | + var id; | |
19 | + vf.map.canvas.addEventListener('mousedown', event => { | |
20 | + clearTimeout(id); | |
21 | + vf.moveCenter(event.pageX, event.pageY); | |
22 | + id = setTimeout(() => { | |
23 | + vf.render(); | |
24 | + }, 250); | |
25 | + }); | |
26 | +}()); | |
27 | + | |
28 | + | |
29 | +// #### CONTROLS #### | |
30 | +// hovering | |
31 | +(function () { | |
32 | + var lastX = 0; | |
33 | + var lastY = 0; | |
34 | + vf.map.canvas.addEventListener('mousemove', event => { | |
35 | + // only count if the mouse moved more than a chunk | |
36 | + let x = Math.floor(vf.x + | |
37 | + (event.clientX - vf.width / 2) / vf.zoom); | |
38 | + let y = Math.floor(vf.y + | |
39 | + (event.clientY - vf.height / 2) / vf.zoom); | |
40 | + if (x == lastX && y == lastY) return; | |
41 | + lastX = x; | |
42 | + lastY = y; | |
43 | + vf.updateInfobox(x + '_' + y); | |
44 | + }); | |
45 | +}()); | |
46 | + | |
47 | +// scroll/zoom | |
48 | +(function () { | |
49 | + var id; | |
50 | + vf.map.canvas.addEventListener('wheel', event => { | |
51 | + clearTimeout(id); | |
52 | + vf.zoom += -Math.sign(event.deltaY); | |
53 | + id = setTimeout(() => { | |
54 | + vf.render(); | |
55 | + }, 250); | |
56 | + }); | |
57 | +}()); | |
58 | + | |
59 | +// reload the chunk list every six seconds | |
60 | +(function () { | |
61 | + setInterval(() => { | |
62 | + vf.reloadChunkList(); | |
63 | + }, 6000); | |
64 | +}()); | |
65 | +// | |
66 | +// var i = 500; | |
67 | +// setTimeout(() => { | |
68 | +// vf.map.dispatchEvent(new MouseEvent('mousedown', { | |
69 | +// clientX: 879, | |
70 | +// clientY: 926 | |
71 | +// })); | |
72 | +// }, i += 1000); | |
73 | +// | |
74 | +// setTimeout(() => { | |
75 | +// vf.map.dispatchEvent(new MouseEvent('mousedown', { | |
76 | +// clientX: 666, | |
77 | +// clientY: 924 | |
78 | +// })); | |
79 | +// }, i += 2000); | |
80 | +// | |
81 | +// setTimeout(() => { | |
82 | +// vf.map.dispatchEvent(new MouseEvent('mousedown', { | |
83 | +// clientX: 1090, | |
84 | +// clientY: 936 | |
85 | +// })); | |
86 | +// }, i += 2000); | |
87 | +// | |
88 | +// setTimeout(() => { | |
89 | +// vf.map.dispatchEvent(new MouseEvent('mousedown', { | |
90 | +// clientX: 29, | |
91 | +// clientY: 785 | |
92 | +// })); | |
93 | +// }, i += 2000); | |
\ No newline at end of file |
@@ -1,8 +1,10 @@ | ||
1 | 1 | using System; |
2 | 2 | using System.Collections.Concurrent; |
3 | 3 | using System.Collections.Generic; |
4 | +using System.Diagnostics; | |
4 | 5 | using System.IO; |
5 | 6 | using System.Linq; |
7 | +using System.Reflection; | |
6 | 8 | using System.Text; |
7 | 9 | using System.Text.RegularExpressions; |
8 | 10 | using System.Threading; |
@@ -38,6 +40,7 @@ namespace Automap | ||
38 | 40 | private ColumnsMetadata chunkTopMetadata; |
39 | 41 | private PointsOfInterest POIs = new PointsOfInterest(); |
40 | 42 | private EntitiesOfInterest EOIs = new EntitiesOfInterest(); |
43 | + private string jsonPreBuilt; | |
41 | 44 | |
42 | 45 | internal Dictionary<int, BlockDesignator> BlockID_Designators { get; private set; } |
43 | 46 | internal Dictionary<AssetLocation, EntityDesignator> Entity_Designators { get; private set; } |
@@ -56,7 +59,7 @@ namespace Automap | ||
56 | 59 | |
57 | 60 | public static string AutomapStatusEventKey = @"AutomapStatus"; |
58 | 61 | public static string AutomapCommandEventKey = @"AutomapCommand"; |
59 | - PersistedConfiguration cachedConfiguration; | |
62 | + //PersistedConfiguration cachedConfiguration; | |
60 | 63 | |
61 | 64 | public AutomapSystem(ICoreClientAPI clientAPI, ILogger logger, PersistedConfiguration config) |
62 | 65 | { |
@@ -74,7 +77,7 @@ namespace Automap | ||
74 | 77 | //Listen on bus for commands |
75 | 78 | ClientAPI.Event.RegisterEventBusListener(CommandListener, 1.0, AutomapSystem.AutomapCommandEventKey); |
76 | 79 | |
77 | - if (configuration.Autostart) | |
80 | + if (configuration.Autostart) | |
78 | 81 | { |
79 | 82 | CurrentState = CommandType.Run; |
80 | 83 | Logger.Debug("Autostart is Enabled."); |
@@ -97,6 +100,8 @@ namespace Automap | ||
97 | 100 | outputText.Write(staticMap.ToText()); |
98 | 101 | outputText.Flush(); |
99 | 102 | |
103 | + MakePreBuiltJSON(); | |
104 | + | |
100 | 105 | Prefill_POI_Designators(); |
101 | 106 | startChunkColumn = new Vec2i((ClientAPI.World.Player.Entity.LocalPos.AsBlockPos.X / chunkSize), (ClientAPI.World.Player.Entity.LocalPos.AsBlockPos.Z / chunkSize)); |
102 | 107 | chunkTopMetadata = new ColumnsMetadata(startChunkColumn); |
@@ -132,11 +137,11 @@ namespace Automap | ||
132 | 137 | Logger.VerboseDebug("Cartographer re-trigger from [{0}]", cartographer_thread.ThreadState); |
133 | 138 | #endif |
134 | 139 | |
135 | - if (cartographer_thread.ThreadState.HasFlag(ThreadState.Unstarted)) | |
140 | + if (cartographer_thread.ThreadState.HasFlag(System.Threading.ThreadState.Unstarted)) | |
136 | 141 | { |
137 | 142 | cartographer_thread.Start(); |
138 | 143 | } |
139 | - else if (cartographer_thread.ThreadState.HasFlag(ThreadState.WaitSleepJoin)) | |
144 | + else if (cartographer_thread.ThreadState.HasFlag(System.Threading.ThreadState.WaitSleepJoin)) | |
140 | 145 | { |
141 | 146 | //Time to (re)write chunk shards |
142 | 147 | cartographer_thread.Interrupt(); |
@@ -168,7 +173,7 @@ namespace Automap | ||
168 | 173 | if (!columnCounter.IsEmpty) |
169 | 174 | { |
170 | 175 | var tempSet = columnCounter.ToArray().OrderByDescending(kvp => kvp.Value); |
171 | - UpdateEntityMetadata( ); | |
176 | + UpdateEntityMetadata(); | |
172 | 177 | |
173 | 178 | foreach (var mostActiveCol in tempSet) |
174 | 179 | { |
@@ -200,9 +205,9 @@ namespace Automap | ||
200 | 205 | if (updatedPixels > 0) |
201 | 206 | { |
202 | 207 | |
203 | - #if DEBUG | |
208 | +#if DEBUG | |
204 | 209 | Logger.VerboseDebug("Wrote chunk shard: ({0}) - Edits#:{1}, Pixels#:{2}", mostActiveCol.Key, mostActiveCol.Value, updatedPixels); |
205 | - #endif | |
210 | +#endif | |
206 | 211 | updatedChunks++; |
207 | 212 | chunkTopMetadata.Update(chunkMeta); |
208 | 213 | columnCounter.TryRemove(mostActiveCol.Key, out ejectedItem); |
@@ -271,7 +276,7 @@ namespace Automap | ||
271 | 276 | } |
272 | 277 | |
273 | 278 | private void Reload_POI_Designators() |
274 | - { | |
279 | + { | |
275 | 280 | Logger.VerboseDebug("Connecting {0} Configured Block-Designators", configuration.BlockDesignators.Count); |
276 | 281 | foreach (var designator in configuration.BlockDesignators) |
277 | 282 | { |
@@ -305,7 +310,6 @@ namespace Automap | ||
305 | 310 | |
306 | 311 | } |
307 | 312 | |
308 | - //TODO: Rewrite as Newtonsoft JsonTextWriter !!! | |
309 | 313 | /// <summary> |
310 | 314 | /// Generates the JSON Metadata. (in Map object format ) |
311 | 315 | /// </summary> |
@@ -315,207 +319,84 @@ namespace Automap | ||
315 | 319 | |
316 | 320 | StreamWriter stream = new StreamWriter(jsonFilename, false, Encoding.UTF8); |
317 | 321 | |
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 | - | |
329 | - using (jsonWriter) | |
322 | + using (stream) | |
330 | 323 | { |
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"); | |
324 | + Stopwatch stopWatch = new Stopwatch(); | |
325 | + stopWatch.Start(); | |
346 | 326 | |
347 | - jsonWriter.WriteRaw("ViewFrame.chunks.chunkSize="); | |
348 | - jsonWriter.WriteValue(chunkSize); | |
349 | - jsonWriter.WriteRaw(";\n"); | |
327 | + stream.Write(jsonPreBuilt); | |
350 | 328 | |
351 | - jsonWriter.WriteRaw("ViewFrame.chunks.northMostChunk="); | |
352 | - jsonWriter.WriteValue(chunkTopMetadata.North_mostChunk); | |
353 | - jsonWriter.WriteRaw(";\n"); | |
329 | + stream.Write("ViewFrame.chunks.genTime='{0}';", | |
330 | + DateTimeOffset.UtcNow | |
331 | + ); | |
354 | 332 | |
355 | - jsonWriter.WriteRaw("ViewFrame.chunks.southMostChunk="); | |
356 | - jsonWriter.WriteValue(chunkTopMetadata.South_mostChunk); | |
357 | - jsonWriter.WriteRaw(";\n"); | |
333 | + stream.Write("ViewFrame.chunks.startCoords=[{0},{1}];", | |
334 | + startChunkColumn.X, startChunkColumn.Y | |
335 | + ); | |
358 | 336 | |
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"); | |
337 | + stream.Write("ViewFrame.chunks.bounds=[{0},{1},{2},{3}];", | |
338 | + chunkTopMetadata.North_mostChunk, | |
339 | + chunkTopMetadata.South_mostChunk, | |
340 | + chunkTopMetadata.West_mostChunk, | |
341 | + chunkTopMetadata.East_mostChunk | |
342 | + ); | |
366 | 343 | |
367 | 344 | |
368 | 345 | //MAP object format - [key, value]: key is "x_y" |
369 | - jsonWriter.WriteRaw("ViewFrame.chunks.chunkMetadata="); | |
370 | - jsonWriter.WriteStartConstructor("Map"); | |
371 | - jsonWriter.WriteStartArray( );//An array of... 2-component arrays | |
372 | - | |
346 | + stream.Write("ViewFrame.chunks.chunkMetadata=new Map(["); | |
373 | 347 | |
374 | 348 | foreach (var shard in chunkTopMetadata) |
375 | 349 | { |
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 | |
350 | + shard.Write(stream, ClientAPI); | |
351 | + stream.Write(","); | |
427 | 352 | } |
353 | + stream.Write("]);");// Close constructor of Map (chunkMetadata) | |
428 | 354 | |
429 | - jsonWriter.WriteEndArray( );//Enclose tuples of chunkMetadata | |
430 | - jsonWriter.WriteEndConstructor( );//Close constructor of Map (chunkMetadata) | |
431 | - jsonWriter.WriteRaw(";\n"); | |
432 | 355 | |
433 | - jsonWriter.WriteRaw("ViewFrame.chunks.pointsOfInterest="); | |
434 | - jsonWriter.WriteStartConstructor("Map"); | |
435 | - jsonWriter.WriteStartArray( );//An array of... 2-component arrays | |
356 | + stream.Write("ViewFrame.chunks.pointsOfInterest=new Map(["); | |
436 | 357 | |
437 | 358 | foreach (var poi in POIs) |
438 | 359 | { |
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( ); | |
360 | + poi.Write(stream, ClientAPI); | |
361 | + stream.Write(","); | |
457 | 362 | } |
458 | - jsonWriter.Write("]);"); | |
459 | 363 | |
460 | - jsonWriter.Write("ViewFrame.chunks.entitiesOfInterest=new Map(["); | |
364 | + stream.Write("]);"); | |
365 | + | |
366 | + stream.Write("ViewFrame.chunks.entitiesOfInterest=new Map(["); | |
461 | 367 | foreach (var eoi in EOIs) |
462 | 368 | { |
463 | - jsonWriter.WriteStartArray( ); | |
464 | - jsonWriter.WriteValue($"{poi.Location.X}_{poi.Location.Z}"); | |
369 | + eoi.Write(stream, ClientAPI); | |
370 | + stream.Write(","); | |
371 | + } | |
372 | + stream.Write("]);\n"); | |
465 | 373 | |
466 | - jsonWriter.WriteStartObject( ); | |
467 | - jsonWriter.WritePropertyName("prettyCoord"); | |
468 | - jsonWriter.WriteValue(poi.Location.PrettyCoords(ClientAPI)); | |
374 | + //stream.Write("//============= BlockID's for Rockmap / Rock-ratios ==============="); | |
469 | 375 | |
470 | - jsonWriter.WritePropertyName("notes"); | |
471 | - jsonWriter.WriteValue(poi.Notes);//Encoded to HTML Entities | |
376 | + //stream.Write("ViewFrame.chunks.rockLookup=new Map(["); | |
472 | 377 | |
473 | - jsonWriter.WritePropertyName("time"); | |
474 | - jsonWriter.WriteValue(poi.Timestamp); | |
378 | + //foreach (var entry in RockIdCodes) | |
379 | + //{ | |
380 | + // var block = ClientAPI.World.GetBlock(entry.Key); | |
475 | 381 | |
476 | - jsonWriter.WritePropertyName("chunkPos"); | |
477 | - jsonWriter.WriteValue($"{(poi.Location.X / chunkSize)}_{(poi.Location.Z / chunkSize)}"); | |
382 | + // stream.Write("["); | |
383 | + // stream.Write("'{0},", block.Code.Path); | |
478 | 384 | |
479 | - jsonWriter.WriteEndObject( ); | |
480 | - jsonWriter.WriteEndArray( ); | |
481 | - } | |
385 | + // stream.Write("["); | |
386 | + // stream.Write("'{0}',", entry.Value); | |
482 | 387 | |
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"); | |
388 | + // stream.Write("{0},", Lang.GetUnformatted(block.Code.Path)); | |
389 | + // //Color? | |
516 | 390 | |
517 | - jsonWriter.Flush(); | |
518 | - } | |
391 | + // stream.Write("]],"); | |
392 | + //} | |
393 | + | |
394 | + //stream.Write("]);\n"); | |
395 | + | |
396 | + stream.Flush(); | |
397 | + | |
398 | + stopWatch.Stop(); | |
399 | + Logger.Debug("Run time of chunk write {0}", stopWatch.Elapsed); | |
519 | 400 | } |
520 | 401 | |
521 | 402 | } |
@@ -695,13 +576,6 @@ namespace Automap | ||
695 | 576 | } |
696 | 577 | |
697 | 578 | chunkMeta.NonAirBlocks++; |
698 | - | |
699 | - ////Heightmap | |
700 | - //if (chunkMeta.HeightMap[X_index, Z_index] == 0) | |
701 | - //{ | |
702 | - // chunkMeta.HeightMap[X_index, Z_index] | |
703 | - // = (ushort) (Y_index + (targetChunkY * chunkSize)); | |
704 | - //} | |
705 | 579 | } |
706 | 580 | while (X_index++ < (chunkSize - 1)); |
707 | 581 | X_index = 0; |
@@ -721,9 +595,9 @@ namespace Automap | ||
721 | 595 | foreach (var loadedEntity in ClientAPI.World.LoadedEntities.ToArray()) |
722 | 596 | { |
723 | 597 | |
724 | - #if DEBUG | |
598 | +#if DEBUG | |
725 | 599 | //Logger.VerboseDebug($"ENTITY: ({loadedEntity.Value.Code}) = #{loadedEntity.Value.EntityId} {loadedEntity.Value.State} {loadedEntity.Value.LocalPos} <<<<<<<<<<<<"); |
726 | - #endif | |
600 | +#endif | |
727 | 601 | |
728 | 602 | var dMatch = Entity_Designators.SingleOrDefault(se => se.Key.Equals(loadedEntity.Value.Code)); |
729 | 603 | if (dMatch.Value != null) |
@@ -798,6 +672,65 @@ namespace Automap | ||
798 | 672 | } |
799 | 673 | |
800 | 674 | |
675 | + private void MakePreBuiltJSON() | |
676 | + { | |
677 | + var builder = new StringBuilder(512); | |
678 | + builder.Append("ViewFrame.chunks={};\n"); | |
679 | + builder.AppendFormat("ViewFrame.chunks.worldSeedNum='{0}';", | |
680 | + ClientAPI.World.Seed | |
681 | + ); | |
682 | + builder.AppendFormat("ViewFrame.chunks.chunkSize={0};", | |
683 | + chunkSize | |
684 | + ); | |
685 | + | |
686 | + builder.Append("ViewFrame.chunks.chunkMetadataNames=["); | |
687 | + var fields = typeof(ColumnMeta).GetFields(); | |
688 | + var attsToSort = new List<DisplayNameAttribute>(); | |
689 | + // this is so gross | |
690 | + foreach (var f in fields) | |
691 | + { | |
692 | + var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); | |
693 | + if (att != null) | |
694 | + { | |
695 | + attsToSort.Add((DisplayNameAttribute) att); | |
696 | + } | |
697 | + | |
698 | + } | |
699 | + foreach (var att in attsToSort.OrderBy(a => a.order)) | |
700 | + builder.AppendFormat("'{0}',", att.name); | |
701 | + builder.Append("];\n"); | |
702 | + | |
703 | + builder.Append("ViewFrame.chunks.pointsOfInterestNames=["); | |
704 | + fields = typeof(PointOfInterest).GetFields(); | |
705 | + attsToSort = new List<DisplayNameAttribute>(); | |
706 | + | |
707 | + foreach (var f in fields) | |
708 | + { | |
709 | + var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); | |
710 | + if (att != null) | |
711 | + attsToSort.Add((DisplayNameAttribute) att); | |
712 | + } | |
713 | + foreach (var att in attsToSort.OrderBy(a => a.order)) | |
714 | + builder.AppendFormat("'{0}',", att.name); | |
715 | + builder.Append("];\n"); | |
716 | + | |
717 | + builder.Append("ViewFrame.chunks.entityOfInterestNames=["); | |
718 | + fields = typeof(EntityOfInterest).GetFields(); | |
719 | + attsToSort = new List<DisplayNameAttribute>(); | |
720 | + | |
721 | + foreach (var f in fields) | |
722 | + { | |
723 | + var att = f.GetCustomAttribute(typeof(DisplayNameAttribute)); | |
724 | + if (att != null) | |
725 | + attsToSort.Add((DisplayNameAttribute) att); | |
726 | + } | |
727 | + foreach (var att in attsToSort.OrderBy(a => a.order)) | |
728 | + builder.AppendFormat("'{0}',", att.name); | |
729 | + builder.Append("];\n"); | |
730 | + | |
731 | + jsonPreBuilt = builder.ToString(); | |
732 | + } | |
733 | + | |
801 | 734 | #endregion |
802 | 735 | |
803 | 736 | } |