2 using System.Collections.Generic;
6 using System.Text.RegularExpressions;
10 using Vintagestory.API.Client;
11 using Vintagestory.API.Common;
12 using Vintagestory.API.Common.Entities;
13 using Vintagestory.API.Config;
14 using Vintagestory.API.MathTools;
15 using Vintagestory.GameContent;
19 public static class DefaultDesignators
23 public static BlockDesignator Roads =
25 new AssetLocation("game", "stonepath"),
27 EnumBlockMaterial.Gravel
30 public static BlockDesignator GroundSigns =
32 new AssetLocation("game", "sign-ground"),
34 EnumBlockMaterial.Wood,
38 public static BlockDesignator WallSigns =
40 new AssetLocation("game", "sign-wall"),
42 EnumBlockMaterial.Wood,
46 public static BlockDesignator PostSigns =
48 new AssetLocation("game", "signpost"),
50 EnumBlockMaterial.Wood,
54 public static BlockDesignator Translocators =
56 new AssetLocation("game", "statictranslocator-normal"),
58 EnumBlockMaterial.Metal,
62 public static BlockDesignator Teleporters =
64 new AssetLocation("game", "teleporterbase"),
66 EnumBlockMaterial.Wood,
70 public static EntityDesignator Traders =
72 new AssetLocation("game", "humanoid-trader"),
73 Color.LightGoldenrodYellow,
74 EnumEntityState.Active,
78 public static BlockDesignator Wildbeehives =
80 new AssetLocation("game", "wildbeehive"),
82 EnumBlockMaterial.Other,
87 public static BlockDesignator PineResinLeaks =
89 new AssetLocation("game", "log-resin"),
91 EnumBlockMaterial.Wood,
99 /// Not just blocks, but block-entities as well!
101 /// <returns>The block designators.</returns>
102 public static List<BlockDesignator> DefaultBlockDesignators
106 return new List<BlockDesignator>{
107 DefaultDesignators.Roads,
108 DefaultDesignators.GroundSigns,
109 DefaultDesignators.WallSigns,
110 DefaultDesignators.PostSigns,
111 DefaultDesignators.Translocators,
112 DefaultDesignators.Teleporters,
113 DefaultDesignators.Wildbeehives,
114 DefaultDesignators.PineResinLeaks,
119 public static List<EntityDesignator> DefaultEntityDesignators
123 return new List<EntityDesignator>{
124 DefaultDesignators.Traders,
129 internal static Encoding SaferUnicodeEncoding = Encoding.GetEncoding(Encoding.UTF8.WebName,
130 new EncoderReplacementFallback(@" "),
131 new DecoderReplacementFallback(@" "));
138 internal static void DecodeSign(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
141 clientAPI.Logger.VerboseDebug("Sign Designator Invoked!");
143 //sign Text into a POI field...
144 BlockEntitySign signEntity = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntitySign;
146 if (signEntity != null && !String.IsNullOrEmpty(signEntity.text)) {
148 var textTemp = SaferUnicodeEncoding.GetBytes(signEntity.text);
151 new PointOfInterest {
153 PrettyLocation = posn.PrettyCoords(clientAPI),
154 Location = posn.Copy( ),
155 Notes = SaferUnicodeEncoding.GetString(textTemp).Normalize(),
156 Timestamp = DateTime.UtcNow,
163 internal static void DecodePostSign(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
166 clientAPI.Logger.VerboseDebug("Post-sign Designator Invoked!");
168 //sign post Text into a POI field...
169 BlockEntitySignPost signEntity = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntitySignPost;
171 if (signEntity != null && signEntity.textByCardinalDirection != null && signEntity.textByCardinalDirection?.Length > 0) {
173 var textTemp = SaferUnicodeEncoding.GetBytes(string.Join(",", signEntity.textByCardinalDirection));
176 new PointOfInterest {
178 PrettyLocation = posn.PrettyCoords(clientAPI),
179 Location = posn.Copy( ),
180 Notes = SaferUnicodeEncoding.GetString(textTemp).Normalize(),
181 Timestamp = DateTime.UtcNow,
187 internal static void KeepTrackOfMerchant(ICoreClientAPI clientAPI, EntitiesOfInterest poi, BlockPos posn, Entity entity)
190 clientAPI.Logger.VerboseDebug("TRADER Designator Invoked!");
193 if (entity == null) return;
195 var traderName = entity.GetBehavior<EntityBehaviorNameTag>( )?.DisplayName ?? @"?";
197 //"game:tradingwindow-humanoid-trader-survivalgoods"
198 var langCodeKey = entity.Code.Domain + ":tradingwindow-" + entity.Code.Path;
201 clientAPI.Logger.VerboseDebug("Using Lang Key Code: \"{0}\"",langCodeKey);
203 if (Lang.AvailableLanguages[@"en"].HasTranslation(langCodeKey)) {
204 var rawLangResponse = Lang.GetL(@"en", langCodeKey, traderName);
205 message = rawLangResponse.Split("-".ToCharArray( ), 2).Last( ).TrimStart( );
208 poi.AddReplace(new EntityOfInterest {
210 PrettyLocation = posn.PrettyCoords(clientAPI),
211 Location = posn.Copy( ),
213 Timestamp = DateTime.UtcNow,
214 EntityId = entity.EntityId
218 internal static void DecodeTranslocator(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
221 clientAPI.Logger.VerboseDebug("TRANSLOCATOR Designator Invoked!");
223 //Where to? and from!
225 BlockEntityStaticTranslocator te = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntityStaticTranslocator;
228 //FIXME: Delayed rescan ?
229 StringBuilder textTarget = new StringBuilder( );
231 textTarget.Append(te.FullyRepaired ? "Functional, " : "Broken, ");
232 textTarget.Append(te.Activated ? "Online, " : "Offline, ");//Property hardcoded TRUE ?!
233 textTarget.Append(" Target: [ ");
234 textTarget.Append(te.TargetLocation != null ? "Set ]" : "Invalid ]");//Or ABS coords?
235 textTarget.AppendFormat(", Range ({0} ~ {1})", te.MinTeleporterRangeInBlocks, te.MaxTeleporterRangeInBlocks);
237 new PointOfInterest {
238 Name = "Translocator",
239 PrettyLocation = posn.PrettyCoords(clientAPI),
240 Location = posn.Copy( ),
241 Notes = textTarget.ToString( ),
242 Timestamp = DateTime.UtcNow,
243 Destination = te.TargetLocation != null ? new BlockPosJson(te.TargetLocation.Copy( )) : null
250 internal static void DecodeTeleport(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
253 clientAPI.Logger.VerboseDebug("Teleport Designator Invoked!");
257 BlockEntityTeleporter tele = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntityTeleporter;
261 //TeleporterManager teleManager = clientAPI.ModLoader.GetModSystem<TeleporterManager>();
262 TeleporterLocation location = AccessTools.FieldRefAccess<BlockEntityTeleporter, TeleporterLocation>(tele, @"tpLocation");//TeleporterLocation tpLocation;
264 if (location != null)
266 StringBuilder textTarget = new StringBuilder( );
267 textTarget.Append(" Target: [ ");
268 textTarget.Append($" '{location.SourceName}' @ {location.SourcePos?.PrettyCoords(clientAPI)} -> '{location.TargetName}' @ {location.TargetPos?.PrettyCoords(clientAPI)} ");//Or ABS coords?
269 textTarget.Append(" ]");
271 new PointOfInterest {
273 PrettyLocation = posn.PrettyCoords(clientAPI),
274 Location = posn.Copy( ),
275 Notes = textTarget.ToString( ),
276 Timestamp = DateTime.UtcNow,
277 Destination = location.TargetPos != null ? new BlockPosJson(location.TargetPos.Copy( )) : null
284 internal static void NoteWildbeehive(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
287 clientAPI.Logger.VerboseDebug("Wild bee hive Designator Invoked!");
290 BlockEntityBeehive bees = clientAPI.World.BlockAccessor.GetBlockEntity(posn) as BlockEntityBeehive;
293 EnumHivePopSize hiveSize = AccessTools.FieldRefAccess<BlockEntityBeehive, EnumHivePopSize>(bees, @"hivePopSize");
295 StringBuilder textTarget = new StringBuilder( );
296 textTarget.AppendLine($" Population: {(hiveSize != null? hiveSize.ToString() : "?")} ");
299 new PointOfInterest {
300 Name = "Wildbeehive",
301 PrettyLocation = posn.PrettyCoords(clientAPI),
302 Location = posn.Copy( ),
303 Notes = textTarget.ToString( ),
304 Timestamp = DateTime.UtcNow,
310 internal static void NotePineResinLeak(ICoreClientAPI clientAPI, PointsOfInterest poi, BlockPos posn, Block block)
313 clientAPI.Logger.VerboseDebug("Resin leaking Pine tree Designator Invoked!");
315 //Note:Due to how Block-Entities are handled...only Harvested resin is tracked....
317 new PointOfInterest {
319 PrettyLocation = posn.PrettyCoords(clientAPI),
320 Location = posn.Copy( ),
321 Notes = String.Empty,
322 Timestamp = DateTime.UtcNow,