2 using System.Collections.Generic;
6 using Hjg.Pngcs.Chunks;
8 using Vintagestory.API.Client;
9 using Vintagestory.API.Common;
10 using Vintagestory.API.MathTools;
14 public static class Helpers
18 //Called once - thus it can only be in a static constructor.
19 PngChunk.FactoryRegister(PngMetadataChunk.ID, typeof(PngMetadataChunk));
23 /// Hue, Saturation Value colorspace
25 /// <returns>The color equiv.</returns>
26 /// <param name="hue">0 - 360 for hue.</param>
27 /// <param name="saturation"> 0 - 1 for saturation or value..</param>
28 /// <param name="value"> 0 - 1 for saturation or value..</param>
29 public static Color FromHSV(double hue, double saturation, double value)
31 int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;
32 double f = hue / 60 - Math.Floor(hue / 60);
35 int v = Convert.ToInt32(value);
36 int p = Convert.ToInt32(value * (1 - saturation));
37 int q = Convert.ToInt32(value * (1 - f * saturation));
38 int t = Convert.ToInt32(value * (1 - (1 - f) * saturation));
42 case 0: return Color.FromArgb(255, v, t, p);
43 case 1: return Color.FromArgb(255, q, v, p);
44 case 2: return Color.FromArgb(255, p, v, t);
45 case 3: return Color.FromArgb(255, p, q, v);
46 case 4: return Color.FromArgb(255, t, p, v);
47 default: return Color.FromArgb(255, v, p, q);
51 public static string PrettyCoords(this BlockPos location, ICoreClientAPI ClientApi)
53 var start = ClientApi.World.DefaultSpawnPosition.AsBlockPos;
55 return string.Format("X{0}, Y{1}, Z{2}", location.X - start.X, location.Y, location.Z - start.Z);
59 /// Chunk location to User display coordinate system
61 /// <returns>Friendly string</returns>
62 /// <param name="location">Chunk Coords.</param>
63 public static string PrettyCoords(this Vec2i location, ICoreClientAPI ClientApi)
65 var start = ClientApi.World.DefaultSpawnPosition.AsBlockPos;
66 var chunkSize = ClientApi.World.BlockAccessor.ChunkSize;
68 return string.Format("X{0}, Z{1}", (location.X * chunkSize) - start.X, (location.Y * chunkSize) - start.Z);
71 public static BlockPos AverageHighestPos(List<BlockPos> positions)
73 int x = 0, y = 0, z = 0, length = positions.Count;
74 foreach (BlockPos pos in positions)
77 y = Math.Max(y, pos.Y);//Mutant Y-axis, take "HIGHEST"
80 return new BlockPos(x / length, y, z / length);
83 public static BlockPos PickRepresentativePosition(List<BlockPos> positions)
85 var averagePos = AverageHighestPos(positions);
86 if (positions.Any(pos => pos.X == averagePos.X && pos.Y == averagePos.Y && pos.Z == averagePos.Z))
88 return averagePos;//lucky ~ center was it!
91 //Otherwise...pick one
92 var whichever = positions.Last(poz => poz.Y == averagePos.Y);
97 public static ushort RainHeight2DMap(this IMapChunk mapChunk, int x, int y, int chunkSize = 32)
99 //int num = posZ % this.chunksize * this.chunksize + posX % this.chunksize;
100 int index = (y % chunkSize) * chunkSize + (x % chunkSize);
101 return mapChunk.RainHeightMap[index];
106 /// Find a BLOCK partial path match: BlockID
108 /// <returns>Matching finds</returns>
109 /// <param name="assetName">Asset name.</param>
110 public static Dictionary<int, string> ArbitrarytBlockIdHunter(this ICoreAPI CoreApi, AssetLocation assetName, EnumBlockMaterial? material = null)
112 Dictionary<int, string> arbBlockIDTable = new Dictionary<int, string>();
115 if (CoreApi.World.Blocks != null)
119 CoreApi.World.Logger.VerboseDebug(" World Blocks [Count: {0}]", CoreApi.World.Blocks.Count);
121 //If Brute force won't work; use GROOT FORCE!
122 //var theBlock = ClientApi.World.BlockAccessor.GetBlock(0);
124 if (!material.HasValue)
126 foreach (Block blk in CoreApi.World.Blocks)
128 if (blk.IsMissing || blk.Id == 0 || blk.BlockId == 0)
132 else if (blk.Code != null && blk.Code.BeginsWith(assetName.Domain, assetName.Path))
135 //CoreApi.World.Logger.VerboseDebug("Block: [{0} ({1})] = #{2}", blk.Code.Path, blk.BlockMaterial, blk.BlockId);
138 arbBlockIDTable.Add(blk.BlockId, blk.Code.Path);
144 foreach (Block blk in CoreApi.World.Blocks)
146 if (blk.IsMissing || blk.Id == 0 || blk.BlockId == 0)
150 else if (blk.Code != null && material.Value == blk.BlockMaterial && blk.Code.BeginsWith(assetName.Domain, assetName.Path))
153 //CoreApi.World.Logger.VerboseDebug("Block: [{0} ({1})] = #{2}", blk.Code.Path, blk.BlockMaterial, blk.BlockId);
156 arbBlockIDTable.Add(blk.BlockId, blk.Code.Path);
162 CoreApi.World.Logger.VerboseDebug("Block gaps: {0}", emptyCount);
166 return arbBlockIDTable;
169 public static Mod Self(this ICoreClientAPI ownApi)
171 AutomapMod ownMod = ownApi.ModLoader.GetModSystem<AutomapMod>( );