<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Helpers.cs" />
<Compile Include="Data\PointOfInterest.cs" />
- <Compile Include="Data\Designator.cs" />
+ <Compile Include="Data\BlockDesignator.cs" />
<Compile Include="Designators\DefaultDesignators.cs" />
<Compile Include="Data\ColumnMeta.cs" />
<Compile Include="Data\PngMetadataChunk.cs" />
<Compile Include="Renderers\IChunkRenderer.cs" />
<Compile Include="Renderers\StandardRenerer.cs" />
<Compile Include="Renderers\AlternateRenderer.cs" />
+ <Compile Include="Data\EntitiesOfInterest.cs" />
+ <Compile Include="Data\EntityDesignator.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="VS_libs\" />
namespace Automap
{
- public delegate void DesignatonAction(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block);
+ public delegate void BlockDesignatonAction(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block);
/// <summary>
/// Point of Interest Rule Designator
/// </summary>
- public class Designator
+ public class BlockDesignator
{
public Color OverwriteColor;
- public DesignatonAction SpecialAction;
+ public BlockDesignatonAction SpecialAction;
public AssetLocation Pattern;
public EnumBlockMaterial? Material;
public bool Enabled { get; set; }
- private Designator( )
+ private BlockDesignator( )
{
throw new NotSupportedException( );
}
- public Designator( AssetLocation pattern , Color overwriteColor, EnumBlockMaterial? material)
+ public BlockDesignator( AssetLocation pattern , Color overwriteColor, EnumBlockMaterial? material)
{
this.Pattern = pattern;
this.OverwriteColor = overwriteColor;
this.Enabled = true;
}
- public Designator(AssetLocation pattern, Color overwriteColor, EnumBlockMaterial? material ,DesignatonAction specialAct )
+ public BlockDesignator(AssetLocation pattern, Color overwriteColor, EnumBlockMaterial? material ,BlockDesignatonAction specialAct )
{
this.Pattern = pattern;
this.OverwriteColor = overwriteColor;
[ProtoMember(11)]
public ushort NonAirBlocks;
- [ProtoMember(12)]
+ //[ProtoMember(12,OverwriteList = true)]
+ [ProtoIgnore]
public ushort[ , ] HeightMap;
public ColumnMeta(Vec2i loc, int chunkSize = 32)
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+
+using System.Linq;
+
+using Vintagestory.API.Common.Entities;
+
+namespace Automap
+{
+ /// <summary>
+ /// Entities of interest.
+ /// </summary>
+ /// <remarks>Tracked by ID - these never leave.</remarks>
+ public class EntitiesOfInterest
+ {
+ private Dictionary<long, PointOfInterest> entitySet = new Dictionary<long, PointOfInterest>(50);
+
+
+ internal void Upsert(Entity something, string message = @"")
+ {
+ if (entitySet.ContainsKey(something.EntityId)) {
+ var movingPOI = entitySet[something.EntityId];
+ movingPOI.Location = something.Pos.AsBlockPos.Copy( );
+ movingPOI.Timestamp = DateTimeOffset.UtcNow;
+ }
+ else {
+ PointOfInterest newPOI = new PointOfInterest( );
+ newPOI.EntityId = something.EntityId;
+ newPOI.Location = something.Pos.AsBlockPos.Copy( );
+ newPOI.Timestamp = DateTimeOffset.UtcNow;
+ newPOI.Notes = message;
+ entitySet.Add(something.EntityId, newPOI );
+ }
+
+ }
+
+
+ public List<PointOfInterest> PointsList {
+ get
+ {
+ return entitySet.Values.ToList();
+ }
+ }
+
+ }
+}
+
--- /dev/null
+using System;
+using System.Collections.Generic;
+using System.Collections.ObjectModel;
+using System.Drawing;
+
+using Vintagestory.API.Client;
+using Vintagestory.API.Common;
+using Vintagestory.API.Common.Entities;
+using Vintagestory.API.MathTools;
+
+namespace Automap
+{
+ public delegate void EntityDesignatonAction(ICoreClientAPI clientAPI, EntitiesOfInterest poi, BlockPos posn, Entity entity);
+
+ /// <summary>
+ /// Point of Interest Rule Designator
+ /// </summary>
+ public class EntityDesignator
+ {
+ public Color OverwriteColor;
+ public EntityDesignatonAction SpecialAction;
+ public AssetLocation Pattern;
+ public EnumEntityState? StateCheck;//Needed?
+ public bool Enabled { get; set; }
+
+ private EntityDesignator( )
+ {
+ throw new NotSupportedException( );
+ }
+
+ public EntityDesignator(AssetLocation pattern, Color overwriteColor, EnumEntityState? state)
+ {
+ this.Pattern = pattern;
+ this.OverwriteColor = overwriteColor;
+ this.StateCheck = state;
+ this.Enabled = true;
+ }
+
+ public EntityDesignator(AssetLocation pattern, Color overwriteColor, EnumEntityState? state, EntityDesignatonAction specialAct)
+ {
+ this.Pattern = pattern;
+ this.OverwriteColor = overwriteColor;
+ this.StateCheck = state;
+ this.SpecialAction = specialAct;
+ this.Enabled = true;
+ }
+
+ public override string ToString( )
+ {
+ return Pattern.ToShortString( ) + "|" + OverwriteColor.Name + "|" + StateCheck ?? "";
+ }
+ }
+}
+
/// Actual Physical Point in space - that is interesting.
/// </summary>
public struct PointOfInterest
- {
- //public CollectibleObject Thing;
+ {
public string Notes;
public BlockPos Location;
public DateTimeOffset Timestamp;
+ public long? EntityId;
}
public class PointsOfInterest : KeyedCollection<BlockPos, PointOfInterest>
using Vintagestory.API.Client;
using Vintagestory.API.Common;
+using Vintagestory.API.Common.Entities;
using Vintagestory.API.MathTools;
using Vintagestory.GameContent;
{
public static class DefaultDesignators
{
- public static Designator Roads =
- new Designator(
+ public static BlockDesignator Roads =
+ new BlockDesignator(
new AssetLocation("game", "stonepath"),
Color.Yellow,
EnumBlockMaterial.Gravel
);
- public static Designator GroundSigns =
- new Designator(
+ public static BlockDesignator GroundSigns =
+ new BlockDesignator(
new AssetLocation("game", "sign-ground"),
Color.Teal,
EnumBlockMaterial.Wood,
DecodeSign
);
- public static Designator WallSigns =
- new Designator(
+ public static BlockDesignator WallSigns =
+ new BlockDesignator(
new AssetLocation("game", "sign-wall"),
Color.Teal,
EnumBlockMaterial.Wood,
DecodeSign
);
- public static Designator PostSigns =
- new Designator(
+ public static BlockDesignator PostSigns =
+ new BlockDesignator(
new AssetLocation("game", "signpost"),
Color.Teal,
EnumBlockMaterial.Wood,
DecodePostSign
);
- public static Designator Translocators =
- new Designator(
+ public static BlockDesignator Translocators =
+ new BlockDesignator(
new AssetLocation("game", "statictranslocator-normal"),
Color.Violet,
EnumBlockMaterial.Metal
//DecodeTranslocator
);
+ public static EntityDesignator Traders =
+ new EntityDesignator(
+ new AssetLocation("game", "humanoid-trader"),
+ Color.LightGoldenrodYellow,
+ EnumEntityState.Active,
+ KeepTrackOfMerchant
+ );
+
+
+ public static List<BlockDesignator> DefaultBlockDesignators( )
+ {
+ return new List<BlockDesignator>{
+ DefaultDesignators.Roads,
+ DefaultDesignators.GroundSigns,
+ DefaultDesignators.WallSigns,
+ DefaultDesignators.PostSigns,
+ };
+ }
+
+ public static List<EntityDesignator> DefaultEntityDesignators( )
+ {
+ return new List<EntityDesignator>{
+ DefaultDesignators.Traders,
+ };
+ }
+
internal static void DecodeSign(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
{
clientAPI.Logger.VerboseDebug("Sign Designator Invoked!");
}
}
+ internal static void KeepTrackOfMerchant(ICoreClientAPI clientAPI, EntitiesOfInterest poi, BlockPos posn, Entity entity)
+ {
+ clientAPI.Logger.VerboseDebug("Trader: {0} @ {1}", entity.GetName( ), posn);
-
+ var message = $"{entity.GetName( )}";
+ var traderJoe = entity as EntityTrader;
+ if (traderJoe.TradeProps != null) {
+ message = $"{traderJoe.GetName( )} Alive:{traderJoe.Alive} - Gears: {traderJoe.TradeProps.Money}, ";
+ }
+ poi.Upsert(entity, message);
+ }
}
}
{
public virtual ICoreClientAPI ClientAPI { get; protected set; }
public virtual ILogger Logger { get; protected set; }
- public virtual Dictionary<int, Designator> BlockID_Designators { get; set; }
+ public virtual Dictionary<int, BlockDesignator> BlockID_Designators { get; set; }
protected IChunkRenderer(ICoreClientAPI clientAPI, ILogger logger)
{
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?
//============ POI Population =================
- if (BlockID_Designators.ContainsKey(blockId)) {
+ if (BlockID_Designators.ContainsKey(blockId)) {
var desig = BlockID_Designators[blockId];
- red = desig.OverwriteColor.R;
- green = desig.OverwriteColor.G;
- blue = desig.OverwriteColor.B;
+
+ if (desig.Enabled)
+ {
+ red = desig.OverwriteColor.R;
+ green = desig.OverwriteColor.G;
+ blue = desig.OverwriteColor.B;
+ }
}
ImageLineHelper.SetPixel(lines[localZ], localX, red, green, blue);
using Vintagestory.API.Client;
using Vintagestory.API.Common;
+using Vintagestory.API.Common.Entities;
using Vintagestory.API.MathTools;
-
-
+using Vintagestory.Common;
namespace Automap
{
private ConcurrentDictionary<Vec2i, uint> columnCounter = new ConcurrentDictionary<Vec2i, uint>(3, 150 );
private ColumnsMetadata chunkTopMetadata;
private PointsOfInterest POIs;
+ private EntitiesOfInterest EOIs;
+
+ internal Dictionary<int, BlockDesignator> BlockID_Designators { get; private set;}
+ internal Dictionary<AssetLocation, EntityDesignator> Entity_Designators { get; private set; }
- internal Dictionary<int, Designator> BlockID_Designators { get; private set;}
internal bool Enabled { get; set; }
//Run status, Chunks processed, stats, center of map....
- internal uint nullChunkCount;
- internal uint updatedChunksTotal;
+ internal uint nullChunkCount, updatedChunksTotal;
internal Vec2i startChunkColumn;
private readonly int chunkSize;
ColumnMeta chunkMeta = CreateColumnMetadata(mostActiveCol,mapChunk);
PngWriter pngWriter = SetupPngImage(mostActiveCol.Key, chunkMeta);
+ UpdateEntityMetadata( );
ProcessChunkBlocks(mostActiveCol.Key, mapChunk, chunkMeta);
uint updatedPixels = 0;
private void Prefill_POI_Designators( )
{
this.POIs = new PointsOfInterest( );
- this.BlockID_Designators = new Dictionary<int, Designator>( );
+ this.EOIs = new EntitiesOfInterest( );
+ this.BlockID_Designators = new Dictionary<int, BlockDesignator>( );
+ this.Entity_Designators = new Dictionary<AssetLocation, EntityDesignator>( );
//Add special marker types for BlockID's of "Interest", overwrite colour, and method
- var standardDesignators = new List<Designator>{
- DefaultDesignators.Roads,
- DefaultDesignators.GroundSigns,
- DefaultDesignators.WallSigns,
- DefaultDesignators.PostSigns,
- };
-
- Install_POI_Designators(standardDesignators);
+ Install_POI_Designators(DefaultDesignators.DefaultBlockDesignators(), DefaultDesignators.DefaultEntityDesignators());
}
- private void Install_POI_Designators(ICollection<Designator> designators)
+ private void Install_POI_Designators(ICollection<BlockDesignator> blockDesig, List<EntityDesignator> entDesig)
{
- Logger.VerboseDebug("Connecting {0} configured Designators", designators.Count);
- foreach (var designator in designators) {
+ Logger.VerboseDebug("Connecting {0} standard Block-Designators", blockDesig.Count);
+ foreach (var designator in blockDesig) {
var blockIDs = Helpers.ArbitrarytBlockIdHunter(ClientAPI, designator.Pattern, designator.Material);
if (blockIDs.Count > 0) { Logger.VerboseDebug("Designator {0} has {1} associated blockIDs", designator.ToString( ), blockIDs.Count); }
foreach (var entry in blockIDs) {
}
}
this.ChunkRenderer.BlockID_Designators = BlockID_Designators;
+
+
+ Logger.VerboseDebug("Connecting {0} standard Entity-Designators", entDesig.Count);
+ foreach (var designator in entDesig) {
+ //Get Variants first, from EntityTypes...better be populated!
+ var matched = ClientAPI.World.EntityTypes.FindAll(entp => entp.Code.BeginsWith(designator.Pattern.Domain, designator.Pattern.Path));
+
+ foreach (var match in matched) {
+ Logger.VerboseDebug("Linked Entity: {0} Designator: {1}", match.Code, designator);
+ this.Entity_Designators.Add(match.Code, designator);
+ }
+
+
+
+ //EntityProperties props = ClientAPI.World.GetEntityType(designator.Pattern);
+ }
+
+
}
//TODO: Convert to RAZOR model
tableWriter.RenderEndTag( );//</table>
-
+
//############## POI list #####################
+ tableWriter.RenderBeginTag(HtmlTextWriterTag.P);
+ tableWriter.WriteLine("Points of Interest");
+ tableWriter.RenderEndTag( );
tableWriter.RenderBeginTag(HtmlTextWriterTag.Ul);
foreach (var poi in this.POIs) {
tableWriter.RenderBeginTag(HtmlTextWriterTag.Li);
- tableWriter.WriteEncodedText(poi.Timestamp.ToString("u"));
- tableWriter.WriteEncodedText(poi.Notes);
tableWriter.WriteEncodedText(poi.Location.PrettyCoords(this.ClientAPI));
+ tableWriter.WriteEncodedText(poi.Notes);
+ tableWriter.WriteEncodedText(poi.Timestamp.ToString("u"));
+ tableWriter.RenderEndTag( );
+ }
+
+ foreach (var eoi in this.EOIs.PointsList) {
+ tableWriter.RenderBeginTag(HtmlTextWriterTag.Li);
+ tableWriter.WriteEncodedText(eoi.Location.PrettyCoords(this.ClientAPI));
+ tableWriter.WriteEncodedText(eoi.Notes);
+ tableWriter.WriteEncodedText(eoi.Timestamp.ToString("u") );
tableWriter.RenderEndTag( );
}
mostActiveCol.Key.Y * chunkSize);
var climate = ClientAPI.World.BlockAccessor.GetClimateAt(equivBP);
- data.UpdateFieldsFrom(climate, mapChunk,TimeSpan.FromHours(ClientAPI.World.Calendar.TotalHours));
-
-
-
+ data.UpdateFieldsFrom(climate, mapChunk,TimeSpan.FromHours(ClientAPI.World.Calendar.TotalHours));
return data;
}
foreach (var shardFile in files) {
+
+ if (shardFile.Length < 1000) continue;
var result = chunkShardRegex.Match(shardFile.Name);
if (result.Success) {
int X_chunk_pos = int.Parse(result.Groups["X"].Value );
}
/// <summary>
- /// Does the heavy lifting of Scanning the whole (surface) chunk - creates Heightmap and Processes POIs, and stats...
+ /// Does the heavy lifting of Scanning the whole (surface) chunk - creates Heightmap and Processes POIs, Entities, and stats...
/// </summary>
/// <param name="key">Chunk Coordinate</param>
/// <param name="mapChunk">Map chunk.</param>
/// <param name="chunkMeta">Chunk metadata</param>
private void ProcessChunkBlocks(Vec2i key, IMapChunk mapChunk, ColumnMeta chunkMeta)
{
+ int topChunkY = mapChunk.YMax / chunkSize;
+ WorldChunk chunkData = ( Vintagestory.Common.WorldChunk )ClientAPI.World.BlockAccessor.GetChunk(key.X, topChunkY, key.Y);
+
+
+
+ }
+
+ private void UpdateEntityMetadata( )
+ {
+ Logger.Debug("Presently {0} Entities", ClientAPI.World.LoadedEntities.Count);
+ //Mabey scan only for 'new' entities by tracking ID in set?
+ foreach (var loadedEntity in ClientAPI.World.LoadedEntities.ToList()) {
+
+ #if DEBUG
+ //Logger.VerboseDebug($"ENTITY: ({loadedEntity.Value.Code}) = #{loadedEntity.Value.EntityId} {loadedEntity.Value.State} {loadedEntity.Value.LocalPos} <<<<<<<<<<<<");
+ #endif
+ var dMatch = Entity_Designators.SingleOrDefault(se => se.Key.Equals(loadedEntity.Value.Code));
+ if (dMatch.Value != null) {
+ if (dMatch.Value.Enabled) {
+ dMatch.Value.SpecialAction(ClientAPI, this.EOIs, loadedEntity.Value.LocalPos.AsBlockPos.Copy( ), loadedEntity.Value);
+ }
}
+ }
+
+
+ }
+
+