using System; using System.Collections.Generic; using System.Drawing; using System.Text; using System.Text.RegularExpressions; using HarmonyLib; using Vintagestory.API.Client; using Vintagestory.API.Common; using Vintagestory.API.Common.Entities; using Vintagestory.API.Config; using Vintagestory.API.MathTools; using Vintagestory.GameContent; namespace Automap { public static class DefaultDesignators { #region Defaults public static BlockDesignator Roads = new BlockDesignator( new AssetLocation("game", "stonepath"), Color.Yellow, EnumBlockMaterial.Gravel ); public static BlockDesignator GroundSigns = new BlockDesignator( new AssetLocation("game", "sign-ground"), Color.Teal, EnumBlockMaterial.Wood, DecodeSign ); public static BlockDesignator WallSigns = new BlockDesignator( new AssetLocation("game", "sign-wall"), Color.Teal, EnumBlockMaterial.Wood, DecodeSign ); public static BlockDesignator PostSigns = new BlockDesignator( new AssetLocation("game", "signpost"), Color.Teal, EnumBlockMaterial.Wood, DecodePostSign ); public static BlockDesignator Translocators = new BlockDesignator( new AssetLocation("game", "statictranslocator-normal"), Color.SteelBlue, EnumBlockMaterial.Metal, DecodeTranslocator ); public static BlockDesignator Teleporters = new BlockDesignator( new AssetLocation("game", "teleporterbase"), Color.SeaGreen, EnumBlockMaterial.Wood, DecodeTeleport ); public static EntityDesignator Traders = new EntityDesignator( new AssetLocation("game", "humanoid-trader"), Color.LightGoldenrodYellow, EnumEntityState.Active, KeepTrackOfMerchant ); public static BlockDesignator Wildbeehives = new BlockDesignator( new AssetLocation("game", "wildbeehive"), Color.Honeydew, EnumBlockMaterial.Other, NoteWildbeehive, false ); public static BlockDesignator PineResinLeaks = new BlockDesignator( new AssetLocation("game", "log-resin"), Color.DarkOrange, EnumBlockMaterial.Wood, NotePineResinLeak, false ); /// /// Not just blocks, but block-entities as well! /// /// The block designators. public static List DefaultBlockDesignators { get { return new List{ DefaultDesignators.Roads, DefaultDesignators.GroundSigns, DefaultDesignators.WallSigns, DefaultDesignators.PostSigns, DefaultDesignators.Translocators, DefaultDesignators.Teleporters, DefaultDesignators.Wildbeehives, DefaultDesignators.PineResinLeaks, }; } } public static List DefaultEntityDesignators { get { return new List{ DefaultDesignators.Traders, }; } } internal static Encoding SaferUnicodeEncoding = Encoding.GetEncoding(Encoding.UTF8.WebName, new EncoderReplacementFallback(@" "), new DecoderReplacementFallback(@" ")); #endregion #region Designators internal static void DecodeSign(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block) { #if DEBUG clientAPI.Logger.VerboseDebug("Sign Designator Invoked!"); #endif //sign Text into a POI field... BlockEntitySign signEntity = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntitySign; if (signEntity != null && !String.IsNullOrEmpty(signEntity.text)) { var textTemp = SaferUnicodeEncoding.GetBytes(signEntity.text); poi.AddReplace( new PointOfInterest { Name = "Sign", PrettyLocation = posn.PrettyCoords(clientAPI), Location = posn.Copy( ), Notes = SaferUnicodeEncoding.GetString(textTemp).Normalize(), Timestamp = DateTime.UtcNow, } ); } } internal static void DecodePostSign(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block) { #if DEBUG clientAPI.Logger.VerboseDebug("Post-sign Designator Invoked!"); #endif //sign post Text into a POI field... BlockEntitySignPost signEntity = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntitySignPost; if (signEntity != null && signEntity.textByCardinalDirection?.Length > 0) { var textTemp = SaferUnicodeEncoding.GetBytes(string.Join(",", signEntity.textByCardinalDirection)); poi.AddReplace( new PointOfInterest { Name = "Signpost", PrettyLocation = posn.PrettyCoords(clientAPI), Location = posn.Copy( ), Notes = SaferUnicodeEncoding.GetString(textTemp).Normalize(), Timestamp = DateTime.UtcNow, } ); } } internal static void KeepTrackOfMerchant(ICoreClientAPI clientAPI, EntitiesOfInterest poi, BlockPos posn, Entity entity) { //clientAPI.Logger.VerboseDebug("Trader: {0} @ {1}", entity.GetName(), posn); var traderJoe = entity as EntityTrader; var traderName = entity.GetBehavior( )?.DisplayName; string code; // this makes me ill switch (entity.Code.Path) { case "humanoid-trader-artisan": code = "{0} the artisan"; break; case "humanoid-trader-treasurehunter": code = "{0} the treasure hunter"; break; case "humanoid-trader-buildmaterials": code = "{0} the building materials trader"; break; case "humanoid-trader-clothing": code = "{0} the clothing merchant"; break; case "humanoid-trader-commodities": code = "{0} the commodities merchant"; break; case "humanoid-trader-foods": code = "{0} the foods supplier"; break; case "humanoid-trader-furniture": code = "{0} the furniture trader"; break; case "humanoid-trader-luxuries": code = "{0} the luxuries merchant"; break; case "humanoid-trader-survivalgoods": code = "{0} the survival goods supplier"; break; default: code = ""; break; } var message = string.Format(code, traderName); if (traderJoe.TradeProps != null) { message += $" - Gears: {traderJoe.TradeProps.Money}, "; } poi.AddReplace(new EntityOfInterest { Name = "Trader", PrettyLocation = posn.PrettyCoords(clientAPI), Location = posn.Copy( ), Notes = message, Timestamp = DateTime.UtcNow, EntityId = entity.EntityId }); } internal static void DecodeTranslocator(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block) { #if DEBUG clientAPI.Logger.VerboseDebug("TRANSLOCATOR Designator Invoked!"); #endif //Where to? and from! BlockEntityStaticTranslocator te = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntityStaticTranslocator; if (te != null) { //FIXME: Delayed rescan ? StringBuilder textTarget = new StringBuilder( ); //translocatorEntity.GetBlockInfo(clientAPI.World.Player, textTarget); textTarget.Append(te.FullyRepaired ? "Functional, " : "Broken, "); textTarget.Append(te.Activated ? "Online, " : "Offline, "); textTarget.Append(" Target: [ "); textTarget.Append(te.TargetLocation != null ? "Set ]" : "Invalid ]");//Or ABS coords? textTarget.AppendFormat(", Range ({0} ~ {1})", te.MinTeleporterRangeInBlocks, te.MaxTeleporterRangeInBlocks); poi.AddReplace( new PointOfInterest { Name = "Translocator", PrettyLocation = posn.PrettyCoords(clientAPI), Location = posn.Copy( ), Notes = textTarget.ToString( ), Timestamp = DateTime.UtcNow, Destination = te.TargetLocation != null ? new BlockPosJson(te.TargetLocation.Copy( )) : null } ); } } internal static void DecodeTeleport(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block) { #if DEBUG clientAPI.Logger.VerboseDebug("Teleport Designator Invoked!"); #endif BlockEntityTeleporter tele = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntityTeleporter; if (tele != null) { //TeleporterManager teleManager = clientAPI.ModLoader.GetModSystem(); TeleporterLocation location = AccessTools.FieldRefAccess(tele, @"tpLocation");//TeleporterLocation tpLocation; if (location != null) { StringBuilder textTarget = new StringBuilder( ); textTarget.Append(" Target: [ "); textTarget.Append($" '{location.SourceName}' @ {location.SourcePos?.PrettyCoords(clientAPI)} -> '{location.TargetName}' @ {location.TargetPos?.PrettyCoords(clientAPI)} ");//Or ABS coords? textTarget.Append(" ]"); poi.AddReplace( new PointOfInterest { Name = "Teleport", PrettyLocation = posn.PrettyCoords(clientAPI), Location = posn.Copy( ), Notes = textTarget.ToString( ), Timestamp = DateTime.UtcNow, Destination = location.TargetPos != null ? new BlockPosJson(location.TargetPos.Copy( )) : null } ); } } } internal static void NoteWildbeehive(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block) { #if DEBUG clientAPI.Logger.VerboseDebug("Wild bee hive Designator Invoked!"); #endif BlockEntityBeehive bees = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntityBeehive; if (bees != null) { EnumHivePopSize hiveSize = AccessTools.FieldRefAccess(bees, @"hivePopSize"); StringBuilder textTarget = new StringBuilder( ); textTarget.AppendLine($" Population: {(hiveSize != null? hiveSize.ToString() : "?")} "); poi.AddReplace( new PointOfInterest { Name = "Wildbeehive", PrettyLocation = posn.PrettyCoords(clientAPI), Location = posn.Copy( ), Notes = textTarget.ToString( ), Timestamp = DateTime.UtcNow, } ); } } internal static void NotePineResinLeak(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block) { #if DEBUG clientAPI.Logger.VerboseDebug("Resin leaking Pine tree Designator Invoked!"); #endif //Note:Due to how Block-Entities are handled...only Harvested resin is tracked.... poi.AddReplace( new PointOfInterest { Name = "PineResin", PrettyLocation = posn.PrettyCoords(clientAPI), Location = posn.Copy( ), Notes = String.Empty, Timestamp = DateTime.UtcNow, } ); } #endregion } }