2 using System.Collections;
3 using System.Collections.Generic;
7 using Vintagestory.API.Client;
8 using Vintagestory.API.Common;
9 using Vintagestory.API.MathTools;
13 public static class Helpers
17 /// Hue, Saturation Value colorspace
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)
25 int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;
26 double f = hue / 60 - Math.Floor(hue / 60);
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));
35 return Color.FromArgb(255, v, t, p);
37 return Color.FromArgb(255, q, v, p);
39 return Color.FromArgb(255, p, v, t);
41 return Color.FromArgb(255, p, q, v);
43 return Color.FromArgb(255, t, p, v);
45 return Color.FromArgb(255, v, p, q);
48 public static string PrettyCoords(this BlockPos location, ICoreClientAPI ClientApi)
50 var start = ClientApi.World.DefaultSpawnPosition.AsBlockPos;
52 return string.Format("X{0}, Y{1}, Z{2}", location.X - start.X, location.Y, location.Z - start.Z );
55 public static BlockPos AverageHighestPos(List<BlockPos> positions)
57 int x = 0, y = 0, z = 0, length = positions.Count;
58 foreach (BlockPos pos in positions)
61 y = Math.Max(y, pos.Y);//Mutant Y-axis, take "HIGHEST"
64 return new BlockPos(x/ length, y, z / length);
67 public static BlockPos PickRepresentativePosition(List<BlockPos> positions)
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!
74 //Otherwise...pick one
75 var whichever = positions.Last(poz => poz.Y == averagePos.Y);
83 /// Find a BLOCK partial path match: BlockID
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)
89 Dictionary<int, string> arbBlockIDTable = new Dictionary<int, string>( );
92 if (CoreApi.World.Blocks != null) {
95 CoreApi.World.Logger.VerboseDebug(" World Blocks [Count: {0}]", CoreApi.World.Blocks.Count);
97 //If Brute force won't work; use GROOT FORCE!
98 //var theBlock = ClientApi.World.BlockAccessor.GetBlock(0);
100 if (!material.HasValue) {
101 foreach (Block blk in CoreApi.World.Blocks) {
102 if (blk.IsMissing || blk.Id == 0 || blk.BlockId == 0) {
104 } else if (blk.Code != null && blk.Code.BeginsWith(assetName.Domain, assetName.Path)) {
106 //CoreApi.World.Logger.VerboseDebug("Block: [{0} ({1})] = #{2}", blk.Code.Path, blk.BlockMaterial, blk.BlockId);
109 arbBlockIDTable.Add(blk.BlockId, blk.Code.Path);
113 foreach (Block blk in CoreApi.World.Blocks) {
114 if (blk.IsMissing || blk.Id == 0 || blk.BlockId == 0) {
116 } else if (blk.Code != null && material.Value == blk.BlockMaterial && blk.Code.BeginsWith(assetName.Domain, assetName.Path)) {
118 //CoreApi.World.Logger.VerboseDebug("Block: [{0} ({1})] = #{2}", blk.Code.Path, blk.BlockMaterial, blk.BlockId);
121 arbBlockIDTable.Add(blk.BlockId, blk.Code.Path);
127 CoreApi.World.Logger.VerboseDebug("Block gaps: {0}", emptyCount);
131 return arbBlockIDTable;
137 /// Chunk local index. Not block position!
139 /// <remarks>Clamps to 5 bit ranges automagically</remarks>
140 public static int ChunkBlockIndicie16(int X_index, int Y_index, int Z_index)
142 return ((Y_index & 31) * 32 + (Z_index & 31)) * 32 + (X_index & 31);
146 /// Chunk index converted from block position (in world)
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)
154 return ((blockPos.Y & 31) * 32 + (blockPos.Z & 31)) * 32 + (blockPos.X & 31);