diff --git a/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs b/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs index 7b78b0423..30d11e5fe 100644 --- a/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs +++ b/Dalamud/Game/Chat/SeStringHandling/Payloads/MapLinkPayload.cs @@ -51,10 +51,13 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads get { // this truncates the values to one decimal without rounding, which is what the game does - var x = Math.Truncate(XCoord * 10.0f) / 10.0f; - var y = Math.Truncate(YCoord * 10.0f) / 10.0f; + // the fudge also just attempts to correct the truncated/displayed value for rounding/fp issues + // TODO: should this fudge factor be the same as in the ctor? currently not since that is customizable + const float fudge = 0.02f; + var x = Math.Truncate((XCoord+fudge) * 10.0f) / 10.0f; + var y = Math.Truncate((YCoord+fudge) * 10.0f) / 10.0f; - return $"( {x.ToString("0.0")}, {y.ToString("0.0")} )"; + return $"( {x.ToString("0.0")} , {y.ToString("0.0")} )"; } } @@ -88,12 +91,15 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads internal MapLinkPayload() { } - public MapLinkPayload(uint territoryTypeId, uint mapId, float niceXCoord, float niceYCoord) + public MapLinkPayload(uint territoryTypeId, uint mapId, float niceXCoord, float niceYCoord, float fudgeFactor = 0.05f) { this.territoryTypeId = territoryTypeId; this.mapId = mapId; - this.rawX = this.ConvertMapCoordinateToRawPosition(niceXCoord, Map.SizeFactor); - this.rawY = this.ConvertMapCoordinateToRawPosition(niceYCoord, Map.SizeFactor); + // this fudge is necessary basically to ensure we don't shift down a full tenth + // because essentially values are truncated instead of rounded, so 3.09999f will become + // 3.0f and not 3.1f + this.rawX = this.ConvertMapCoordinateToRawPosition(niceXCoord + fudgeFactor, Map.SizeFactor); + this.rawY = this.ConvertMapCoordinateToRawPosition(niceYCoord + fudgeFactor, Map.SizeFactor); } public MapLinkPayload(uint territoryTypeId, uint mapId, int rawX, int rawY) @@ -177,7 +183,7 @@ namespace Dalamud.Game.Chat.SeStringHandling.Payloads var scaledPos = ((((pos - 1.0f) * c / 41.0f) * 2048.0f) - 1024.0f) / c; scaledPos *= 1000.0f; - return (int)Math.Round(scaledPos); + return (int)scaledPos; } #endregion diff --git a/Dalamud/Game/Chat/SeStringHandling/SeStringUtils.cs b/Dalamud/Game/Chat/SeStringHandling/SeStringUtils.cs index cf30a296b..90b0e93b4 100644 --- a/Dalamud/Game/Chat/SeStringHandling/SeStringUtils.cs +++ b/Dalamud/Game/Chat/SeStringHandling/SeStringUtils.cs @@ -1,17 +1,19 @@ -using Dalamud.Data.TransientSheet; using Dalamud.Game.Chat.SeStringHandling.Payloads; +using Lumina.Excel.GeneratedSheets; using System; using System.Collections.Generic; using System.Linq; using System.Text; +using DalamudItem = Dalamud.Data.TransientSheet.Item; + namespace Dalamud.Game.Chat.SeStringHandling { public class SeStringUtils { public static SeString CreateItemLink(uint itemId, bool isHQ, string displayNameOverride = null) { - string displayName = displayNameOverride ?? SeString.Dalamud.Data.GetExcelSheet().GetRow((int)itemId).Name; + string displayName = displayNameOverride ?? SeString.Dalamud.Data.GetExcelSheet().GetRow((int)itemId).Name; if (isHQ) { displayName += " \uE03C"; @@ -33,5 +35,46 @@ namespace Dalamud.Game.Chat.SeStringHandling return new SeString(payloads); } + + public static SeString CreateMapLink(uint territoryId, uint mapId, float xCoord, float yCoord, float fudgeFactor = 0.05f) + { + var mapPayload = new MapLinkPayload(territoryId, mapId, xCoord, yCoord, fudgeFactor); + var nameString = $"{mapPayload.PlaceName} {mapPayload.CoordinateString}"; + + var payloads = new List(new Payload[] + { + mapPayload, + new UIForegroundPayload(0x01F4), + new UIGlowPayload(0x01F5), + new TextPayload("\uE0BB"), + new UIGlowPayload(0), + new UIForegroundPayload(0), + new TextPayload(nameString), + new RawPayload(new byte[] { 0x02, 0x27, 0x07, 0xCF, 0x01, 0x01, 0x01, 0xFF, 0x01, 0x03 }) + }); + + return new SeString(payloads); + } + + public static SeString CreateMapLink(string placeName, float xCoord, float yCoord, float fudgeFactor = 0.05f) + { + var mapSheet = SeString.Dalamud.Data.GetExcelSheet(); + + var matches = SeString.Dalamud.Data.GetExcelSheet().GetRows() + .Where(row => row.Name.ToLowerInvariant() == placeName.ToLowerInvariant()) + .ToArray(); + + foreach (var place in matches) + { + var map = mapSheet.GetRows().FirstOrDefault(row => row.PlaceName == place.RowId); + if (map != null) + { + return CreateMapLink(map.TerritoryType, (uint)map.RowId, xCoord, yCoord); + } + } + + // TODO: empty? throw? + return null; + } } }