OSDN Git Service

W.I.P. #2 Designators for POI - partly implimented, and more
[automap/automap.git] / Automap / Helpers.cs
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Drawing;
5 using System.Linq;
6
7 using Vintagestory.API.Client;
8 using Vintagestory.API.Common;
9 using Vintagestory.API.MathTools;
10
11 namespace Automap
12 {
13         public static class Helpers
14         {
15                 
16                 /// <summary>
17                 /// Hue, Saturation Value colorspace
18                 /// </summary>
19                 /// <returns>The color equiv.</returns>
20                 /// <param name="hue">0 - 360 for hue.</param>
21                 /// <param name="saturation"> 0 - 1 for saturation or value..</param>
22                 /// <param name="value"> 0 - 1 for saturation or value..</param>
23                 public static Color FromHSV(double hue, double saturation, double value)
24                 {
25                         int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;
26                         double f = hue / 60 - Math.Floor(hue / 60);
27
28                         value = value * 255;
29                         int v = Convert.ToInt32(value);
30                         int p = Convert.ToInt32(value * (1 - saturation));
31                         int q = Convert.ToInt32(value * (1 - f * saturation));
32                         int t = Convert.ToInt32(value * (1 - (1 - f) * saturation));
33
34                         if (hi == 0)
35                                 return Color.FromArgb(255, v, t, p);
36                         else if (hi == 1)
37                                 return Color.FromArgb(255, q, v, p);
38                         else if (hi == 2)
39                                 return Color.FromArgb(255, p, v, t);
40                         else if (hi == 3)
41                                 return Color.FromArgb(255, p, q, v);
42                         else if (hi == 4)
43                                 return Color.FromArgb(255, t, p, v);
44                         else
45                                 return Color.FromArgb(255, v, p, q);
46                 }
47
48                 public static string PrettyCoords(this BlockPos location, ICoreClientAPI ClientApi)
49                 {
50                         var start = ClientApi.World.DefaultSpawnPosition.AsBlockPos;
51
52                         return string.Format("X{0}, Y{1}, Z{2}", location.X - start.X, location.Y, location.Z - start.Z );
53                 }
54
55                 public static BlockPos AverageHighestPos(List<BlockPos> positions)
56                 {
57                         int x = 0, y = 0, z = 0, length = positions.Count;
58                         foreach (BlockPos pos in positions)
59                         {
60                                 x += pos.X;
61                                 y = Math.Max(y, pos.Y);//Mutant Y-axis, take "HIGHEST"
62                                 z += pos.Z;
63                         }
64                         return new BlockPos(x/ length, y, z / length);
65                 }
66
67                 public static BlockPos PickRepresentativePosition(List<BlockPos> positions)
68                 {
69                         var averagePos = AverageHighestPos( positions );
70                         if ( positions.Any( pos => pos.X == averagePos.X && pos.Y == averagePos.Y && pos.Z == averagePos.Z ) ) {
71                                 return averagePos;//lucky ~ center was it!
72                         }
73
74                         //Otherwise...pick one
75                         var whichever = positions.Last(poz => poz.Y == averagePos.Y);
76
77                         return whichever;
78                 }
79
80
81
82                 /// <summary>
83                 /// Find a BLOCK partial path match: BlockID
84                 /// </summary>
85                 /// <returns>Matching finds</returns>
86                 /// <param name="assetName">Asset name.</param>
87                 public static Dictionary<int, string> ArbitrarytBlockIdHunter(this ICoreAPI CoreApi ,AssetLocation assetName, EnumBlockMaterial? material = null)
88                 {
89                         Dictionary<int, string> arbBlockIDTable = new Dictionary<int, string>( );
90                         uint emptyCount = 0;
91
92                         if (CoreApi.World.Blocks != null) {
93
94                                 #if DEBUG
95                                 CoreApi.World.Logger.VerboseDebug(" World Blocks [Count: {0}]", CoreApi.World.Blocks.Count);
96                                 #endif
97                                 //If Brute force won't work; use GROOT FORCE!
98                                 //var theBlock = ClientApi.World.BlockAccessor.GetBlock(0);
99
100                                 if (!material.HasValue) {
101                                         foreach (Block blk in CoreApi.World.Blocks) {
102                                                 if (blk.IsMissing || blk.Id == 0 || blk.BlockId == 0) {
103                                                         emptyCount++;
104                                                 } else if (blk.Code != null && blk.Code.BeginsWith(assetName.Domain, assetName.Path)) {
105                                                         #if DEBUG
106                                                         //CoreApi.World.Logger.VerboseDebug("Block: [{0} ({1})] =  #{2}", blk.Code.Path, blk.BlockMaterial, blk.BlockId);
107                                                         #endif
108
109                                                         arbBlockIDTable.Add(blk.BlockId, blk.Code.Path);
110                                                 }
111                                         }
112                                 } else {
113                                         foreach (Block blk in CoreApi.World.Blocks) {
114                                                 if (blk.IsMissing || blk.Id == 0 || blk.BlockId == 0) {
115                                                         emptyCount++;
116                                                 } else if (blk.Code != null && material.Value == blk.BlockMaterial && blk.Code.BeginsWith(assetName.Domain, assetName.Path)) {
117                                                         #if DEBUG
118                                                         //CoreApi.World.Logger.VerboseDebug("Block: [{0} ({1})] =  #{2}", blk.Code.Path, blk.BlockMaterial, blk.BlockId);
119                                                         #endif
120
121                                                         arbBlockIDTable.Add(blk.BlockId, blk.Code.Path);
122                                                 }
123                                         }
124                                 }
125
126                                 #if DEBUG
127                                 CoreApi.World.Logger.VerboseDebug("Block gaps: {0}", emptyCount);
128                                 #endif
129                         }
130
131                         return arbBlockIDTable;
132                 }
133
134
135
136                 /// <summary>
137                 /// Chunk local index. Not block position!
138                 /// </summary>
139                 /// <remarks>Clamps to 5 bit ranges automagically</remarks>
140                 public static int ChunkBlockIndicie16(int X_index, int Y_index, int Z_index)
141                 {                       
142                         return ((Y_index & 31) * 32 + (Z_index & 31)) * 32 + (X_index & 31);
143                 }
144
145                 /// <summary>
146                 /// Chunk index converted from block position (in world)
147                 /// </summary>
148                 /// <returns>The block indicie.</returns>
149                 /// <param name="blockPos">Block position.</param>
150                 /// <remarks>Clamps to 5 bit ranges automagically</remarks>
151                 public static int ChunkBlockIndicie16(BlockPos blockPos)
152                 {
153                         //Chunk masked
154                         return ((blockPos.Y & 31) * 32 + (blockPos.Z & 31)) * 32 + (blockPos.X & 31);
155                 }
156         }
157 }
158