I have done some experiments with image tags in text buffer controls and found something I believe is a bug in
LocalizeString.
What I tried to achieve was putting a small icon in front of name links when the player is a friend or guild mate.
In order to do this, I post hooked the ZO_LinkHandler_CreateLink method and modified the link if applicable.
Lua Code:
local originalCreateLink = ZO_LinkHandler_CreateLink
ZO_LinkHandler_CreateLink = function(text, color, linkType, rawName, ...)
local link = originalCreateLink(text, color, linkType, rawName, ...)
if((linkType == DISPLAY_NAME_LINK_TYPE or linkType == CHARACTER_LINK_TYPE) and currentChannel > LINK_INDICATORS_DISABLED) then
if(linkType == DISPLAY_NAME_LINK_TYPE and not IsDecoratedDisplayName(rawName)) then
rawName = DecorateDisplayName(rawName)
end
link = AddChatIndicators(link, rawName, currentChannel)
end
return link
end
This works fine in general, but I noticed that it would corrupt the character name link in the friend status messages like this:
Code:
|t12:12:SocialIndicators/images/epact/friendicon.dds|t|H1:character:Some-Friend-Of-Mine^Mx[Some-Friend-Of-Mine.|h
So I started looking what could cause this issue and first put a d(link) after the AddChatIndicators line in the code above.
To my surprise it showed the correct output for the debug output, so it didn't seem to be something that happens in my own code.
Next I checked the spot where the output was generated which is in the EVENT_FRIEND_PLAYER_STATUS_CHANGED handler in chathandlers.lua.
Lua Code:
...
if(characterName ~= "") then
local characterNameLink = ZO_LinkHandler_CreateCharacterLink(characterName)
return zo_strformat(SI_FRIENDS_LIST_FRIEND_CHARACTER_LOGGED_ON, displayNameLink, characterNameLink)
else
...
There doesn't happen anything between creating the link and putting together the output which is returned by this function and the output doesn't get changed after it is returned and handled in the chat system, so I tried to eliminate some other potential causes and directly printed the message like this using ZAM-Notebook:
Lua Code:
local handlers = ZO_ChatSystem_GetEventHandlers()
d(handlers[EVENT_FRIEND_PLAYER_STATUS_CHANGED]("@SomeFriend", "Some-Friend-Of-Mine^Mx", PLAYER_STATUS_OFFLINE, PLAYER_STATUS_ONLINE)
For some reason it didn't corrupt the output like before but now simply didn't show the name at all after the icon.
The display name links are shown without a problem, so I next tried to see what makes them different.
I reduced my code to
Lua Code:
local icon = "|t12:12:|t"
local link = "|H1:character:Some-Friend-Of-Mine^Mx|h[Some-Friend-Of-Mine]|h"
d(LocalizeString("<<1>>", icon .. link))
which only shows a white box, but not the character link when called.
When I directly print the icon and link without putting it through LocalizeString it works fine.
I tried to replace each of the elements of the link individually and found that it does work as long as the caret (^) is not present.
Seeing as formatting works fine with only the character link and no icon and also how the display link didn't get influenced by the character link, I tried a few different combinations.
Lua Code:
local icon = "|t12:12:|t"
local link = "|H1:character:The-Bug-Is-Real^Mx|h[The-Bug-Is-Real]|h"
d(LocalizeString("1:<<1>>", link .. icon))
d(LocalizeString("2:<<1>><<2>>", link, icon))
d(LocalizeString("3:<<1>>", icon .. link))
d(LocalizeString("4:<<1>><<2>>", icon, link))
d(LocalizeString("5:<<1>>", link .. link))
d(LocalizeString("6:<<1>><<2>>", link, link))
d(LocalizeString("7:<<1>>", icon .. icon))
d(LocalizeString("8:<<1>><<2>>", icon, icon))
Without the caret it works as expected:
As soon as I put it in again, it won't work when there is a link and some other tag in the same argument:
Which leads me to believe that there is a bug in LocalizeString that causes this behavior.
Bonus bug:
I experimented with the icon tag to see if there is maybe a hidden fourth argument that allows me to change the color or something and randomly put in something like this:
Lua Code:
local icon = "|t12:12::cc0000|t"
Which caused the link to show up again similar to the first result in this post.
After playing around a bit more I reduced it to
Lua Code:
local icon = "|t12:12:c|t"
which seems to be the only letter that causes this behavior.
conclusion:
I don't expect this to be fixed any time soon, so I now use a workaround by replacing the formatter function and passing the icon and character link to zo_strformat separately. On the plus side this also allows me to reduce the look ups for one player as I can use the same icons for the player link and character link.
Lua Code:
local function InitializePlayerStatusMessageWorkaround()
local loggonMessage = GetString(SI_FRIENDS_LIST_FRIEND_CHARACTER_LOGGED_ON):gsub("<<2>>", "<<2>><<3>><<4>>")
local loggoffMessage = GetString(SI_FRIENDS_LIST_FRIEND_CHARACTER_LOGGED_OFF):gsub("<<2>>", "<<2>><<3>><<4>>")
local handlers = ZO_ChatSystem_GetEventHandlers()
handlers[EVENT_FRIEND_PLAYER_STATUS_CHANGED] = function(displayName, characterName, oldStatus, newStatus)
local wasOnline = oldStatus ~= PLAYER_STATUS_OFFLINE
local isOnline = newStatus ~= PLAYER_STATUS_OFFLINE
local oldChannel = currentChannel
currentChannel = LINK_INDICATORS_DISABLED
if(not wasOnline and isOnline) then
local friend, guild = GetLinkIndicators(displayName, LINK_INDICATORS_AUTO)
local displayNameLink = friend .. guild .. ZO_LinkHandler_CreateDisplayNameLink(displayName)
if(characterName ~= "") then
local characterNameLink = ZO_LinkHandler_CreateCharacterLink(characterName)
return zo_strformat(loggonMessage, displayNameLink, friend, guild, characterNameLink)
else
return zo_strformat(SI_FRIENDS_LIST_FRIEND_LOGGED_ON, displayNameLink)
end
elseif(wasOnline and not isOnline) then
local friend, guild = GetLinkIndicators(displayName, LINK_INDICATORS_AUTO)
local displayNameLink = friend .. guild .. ZO_LinkHandler_CreateDisplayNameLink(displayName)
if(characterName ~= "") then
local characterNameLink = ZO_LinkHandler_CreateCharacterLink(characterName)
return zo_strformat(loggoffMessage, displayNameLink, friend, guild, characterNameLink)
else
return zo_strformat(SI_FRIENDS_LIST_FRIEND_LOGGED_OFF, displayNameLink)
end
end
currentChannel = oldChannel
end
end
I hope this was interesting for someone and if you like it, I can write more post like this in the future. (I probably will, even if you don't like it
)