Automap (client) [VS plugin mod]
修訂. | 1c8849af29a916822885541c010ffc4b7bb90d5a |
---|---|
大小 | 4,083 bytes |
時間 | 2022-05-02 03:22:25 |
作者 | melchior |
Log Message | 2nd Entity processing fix attempt
|
using System;
using System.Linq;
using Hjg.Pngcs;
using Vintagestory.API.Client;
using Vintagestory.API.Common;
using Vintagestory.API.MathTools;
namespace Automap
{
public class AlternateRenderer : AChunkRenderer
{
public const string Name = @"Alternate";
/// <summary>
/// V.G.D:'s Alternative renderer
/// </summary>
/// <param name="clientAPI">Client API.</param>
/// <param name="logger">Logger.</param>
public AlternateRenderer(ICoreClientAPI clientAPI, ILogger logger, bool seasonalColor) : base(clientAPI, logger)
{
}
public override void GenerateChunkPngShard(Vec2i chunkPos, IMapChunk mc, ColumnMeta metaData, ref ColumnsMetadata allCols, out uint pixelCount)
{
pixelCount = 0;
BlockPos tmpPos = new BlockPos();
Vec2i localpos = new Vec2i();
var chunksColumn = new IWorldChunk[ClientAPI.World.BlockAccessor.MapSizeY / chunkSize];
int topChunkY = mc.YMax / chunkSize;//Heywaitaminute -- this isn't a highest FEATURE, if Rainmap isn't accurate!
//Metadata of DateTime chunk was edited, chunk coords.,world-seed? Y-Max feature height
//Grab a chunk COLUMN... Topmost Y down...
for (int chunkY = 0; chunkY <= topChunkY; chunkY++)
{
chunksColumn[chunkY] = ClientAPI.World.BlockAccessor.GetChunk(chunkPos.X, chunkY, chunkPos.Y);
//What to do if chunk is a void? invalid?
}
//pre-create PNG line slices...
ImageLine[] lines = Enumerable.Repeat(new object(), chunkSize).Select(l => new ImageLine(this.PngWriter.ImgInfo)).ToArray();
ushort[] allMapYs = mc.RainHeightMap;
for (int posIndex = 0; posIndex < (chunkSize * chunkSize); posIndex++)
{
int currY = allMapYs[posIndex];
int localChunkY = currY / chunkSize;
if (localChunkY >= (chunksColumn.Length)) continue; //Out of range!
if (chunksColumn[localChunkY] == null) continue;
MapUtil.PosInt2d(posIndex, chunkSize, localpos);
int localX = localpos.X;
int localZ = localpos.Y;
chunksColumn[localChunkY].Unpack();
int blockId = chunksColumn[localChunkY].Blocks[MapUtil.Index3d(localX, currY % chunkSize, localZ, chunkSize, chunkSize)];
Block block = ClientAPI.World.Blocks[blockId];
tmpPos.Set(chunkSize * chunkPos.X + localX, currY, chunkSize * chunkPos.Y + localZ);
int red;
int green;
int blue;
//============ POI Population =================
if (BlockID_Designators.ContainsKey(blockId))
{
var desig = BlockID_Designators[blockId];
red = desig.OverwriteColor.R;
green = desig.OverwriteColor.G;
blue = desig.OverwriteColor.B;
ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
continue;
}
float b = GetSlope(localX, localZ, allMapYs);
int col = block.GetColor(ClientAPI, tmpPos);
int packedFormat = ColorUtil.ColorMultiply3Clamped(col, b);
red = ColorUtil.ColorB(packedFormat);
green = ColorUtil.ColorG(packedFormat);
blue = ColorUtil.ColorR(packedFormat);
ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
//chunkImage.SetPixel(localX, localZ, pixelColor);
pixelCount++;
}
for (int row = 0; row < this.PngWriter.ImgInfo.Rows; row++)
{
this.PngWriter.WriteRow(lines[row], row);
}
this.PngWriter.End();
}
private float GetSlope(int x, int y, ushort[] heightMap)
{
int baseY = heightMap[MapUtil.Index2d(x, y, chunkSize)];
float runningY = 0;
// check bounds. i hate this.
int locIndex;
if (x > 0)
{
locIndex = MapUtil.Index2d(x - 1, y, chunkSize);
runningY += (baseY - heightMap[locIndex]);
}
if (x < chunkSize - 1)
{
locIndex = MapUtil.Index2d(x + 1, y, chunkSize);
runningY += (baseY - heightMap[locIndex]);
}
if (y > 0)
{
locIndex = MapUtil.Index2d(x, y - 1, chunkSize);
runningY += (baseY - heightMap[locIndex]);
}
if (y < chunkSize - 1)
{
locIndex = MapUtil.Index2d(x, y + 1, chunkSize);
runningY += (baseY - heightMap[locIndex]);
}
runningY /= 4; // average now
runningY /= 5; // idk
return 1 + runningY;
}
}
}