Neat Text Messages

This bundle is marked as high quality. It exceeds standards and is highly desirable.
A library I wrote as a replacement for the default Blizzard text message display, which I find quite lackluster. NeatTextMessages allows for much more customization such as placement, text alignment, text size, and display duration while keeping the main logic of how text messages are displayed and faded out. It also includes an option to put tooltip-like frames and icons around the text messages, reverse the message order, and allows you to setup multiple message windows.

The library is easy to import and is used just like the default text messages.

If you want to use boxed text messages like shown in the gif, you have to download the map and import the included files. Otherwise, you can simply copy the code below, but it is still advised to use the .fdf so that you have proper text shadow on the messages. GUI users can make use of the "Replace Blizzard Function Calls" feature.

Neat Text Messages supports 1.31, but you need to install TasFullScreenFrame to enable it.
Contents

Neat Text Messages (Map)

NeatMessageTemplates.toc (Binary)

NeatTextMessage.fdf (Binary)

NeatTextMessages (Lua) (Binary)

NeatTextMessages (vJASS) (Binary)

NeatTextMessages Lua (Map)

Reviews
Wrda
vJASS and Lua support along with the 1.31 support and widescreen support makes this even improved version. High Quality
Managed to find a way to rewrite it in a simpler way without causing any potential desyncs. Because no additional timers are created or destroyed on the clear functions, the hook replacement feature will also cause no desyncs unless the Blizzard DisplayText functions are called from local player code for no reason.
 
Level 37
Joined
Aug 6, 2015
Messages
786
Hmm, looks useful, but would like to have more settings, options Like :
  • Easily reduce/increase the window/text size
  • Change Text Shown Duration
  • Change the window positions or choose one from few already settled on different positions (left/right/bottom/top)

Also, the default position does interfere with the chat box a bit.
Screenshot_3.png
 
Level 37
Joined
Aug 6, 2015
Messages
786
You mean have the option to change the window/text size etc. during the game? Should be easy to implement a few functions to do that.

I can increase the default height a bit, sure.
In triggers when creating any text.
Like :
  • Variable 1 : Duration = N seconds
  • Variable 2 : Position = 1/2/3/4/5
  • Variable 3 : Size = 11.5
  • Variable 4 : Text = "Text"
RUN CC
 
Last edited:
In triggers when creating any text.
Like :
  • Variable 1 : Duration = N seconds
  • Variable 2 : Position = 1/2/3/4/5
  • Variable 3 : Size = 11.5
  • Variable 4 : Text = "Text"
RUN CC
I've written something to overwrite the default text formatting. See how this is.

Doesn't work with the GUI hook-feature. Maybe I'll figure out a way to make it compatible.
 

Wrda

Spell Reviewer
Level 28
Joined
Nov 18, 2012
Messages
2,010
JASS:
private function GetAdjustedStringLength takes string whichString returns integer
    local integer rawLength = StringLength(whichString)
    local integer adjustedLength = rawLength
    local integer j = 0
    loop
        exitwhen j > rawLength - 10
        if SubString(whichString, j, j+1) == "|" and StringCase(SubString(whichString, j+1, j+2), false) == "c" then
            set adjustedLength = adjustedLength - 10
            set j = j + 10
        else
            set j = j + 1
        endif
    endloop
    return adjustedLength
endfunction
I believe the condition can be simplified to this:
JASS:
if StringCase(SubString(whichString, j, j+2), false) == “|c” then
Also, you probably should check for the “|r” part too, since it ends the colour code.
In TextAddMessage function, you have call ChangeTextFormatting(i+1,messageFormat[i+1]), shouldn’t it be: call ChangeTextFormatting(i+1,messageFormat[i]), to follow the others?

I’d recommend struct names to start with an upper case later as in the JPAG.

It’s better to have a GUI trigger, perhaps near the “neat messages”, with all the variables pointing to some null value for easier copy pasting, than grabbing all the examples and do it manually.
Suggestion: perhaps allow these frames to use a different font :)?

It's a nice system with creative use of frames, allowing variation to game messages.

Approved
 
I believe the condition can be simplified to this:
JASS:
if StringCase(SubString(whichString, j, j+2), false) == “|c” then
My version avoids calling StringCase unless the first character matches, which will make it significantly faster.

Also, you probably should check for the “|r” part too, since it ends the colour code.
Right, fixed that.

I’d recommend struct names to start with an upper case later as in the JPAG.
This convention never really made sense to me, but alright, I changed it.

It’s better to have a GUI trigger, perhaps near the “neat messages”, with all the variables pointing to some null value for easier copy pasting, than grabbing all the examples and do it manually.
Done.
Suggestion: perhaps allow these frames to use a different font :)?
Everytime I tried stuff with custom fonts, it just crashed my map. Someone has to tell me what I'm doing wrong.

It's a nice system with creative use of frames, allowing variation to game messages.

Approved
Thank you! 👍
 
Updated the library with tons of new features:
  • Added the ability to create multiple message windows. For example, if you want to create a second window for in-game notifications like units dying etc., this might come in handy.
  • Added the ability to edit messages while they're being displayed.
  • Added the ability to create icons next to the message display. If you're telling a player to buy a certain item, putting an icon of it next to the message is a must! You might also want to spice up your warning messages by putting an exclamation mark next to them!
  • Added the ability to reverse the order of messages, so that they appear at the top of the window and move to the bottom as more are being added. Useful if you want to setup a second message window at the top of the screen!
 
Last edited:
Update:
  • Added a Lua version.

Will have one more update planned for the near future. It will add the ability to put on-click callbacks over the text messages. This could be great, for example, if you want to display warnings to the players and make them able to click on the warnings to jump to the relevant location.

Also, no one who downloaded this map in the last couple month could have informed me that I accidently uploaded a completely non-functioning version? Weak... :pmeh:
 
Level 2
Joined
May 31, 2021
Messages
7
for some unknown reason the text inside the box didn't fit.

1714493204981.png


here's the code
JASS:
private function init takes nothing returns nothing
    ....
   
    // Init Neat Message
    set nMsg = NeatFormat.create()
    set nMsg.horizontalAlignment = TEXT_JUSTIFY_LEFT

    ....
endfunction
JASS:
private function doSomething takes nothing returns nothing
    ....
    // Msg
    // call NeatMessage("test")
    call NeatMessageToPlayerFormatted(owner, "|cffffcc00NOTE:|r If you are unable to locate your unit, pressing |cffffcc00F1|r will select it.", nMsg)
    call DisplayTimedTextToPlayer(owner, 0, 0, 5, udg_playerColor[userId + 1] + GetPlayerName(owner) + "|r picked " + GetUnitName(pickedUnit) + "")
    ....
endfunction

but if I add NeatMessage() above of it, it works.
JASS:
    // Msg
    call NeatMessage("hello")
    call NeatMessageToPlayerFormatted(owner, "|cffffcc00NOTE:|r If you are unable to locate your unit, pressing |cffffcc00F1|r will select it.", nMsg)
    call DisplayTimedTextToPlayer(owner, 0, 0, 5, udg_playerColor[userId + 1] + GetPlayerName(owner) + "|r picked " + GetUnitName(pickedUnit) + "")

1714493832453.png
 
Last edited:
Found it, fixed it!

It had something to do with the text scale and text height changing at the same time. The frame gets resized to fit the new text, but the text frame also gets rescaled on the first created message, making the text too large to fit into the frame, which was aligned to fit the unscaled text. However, that doesn't explain why it doesn't happen when you later swap to a text format with a larger text size.

In any case, my logic was correct, just a weird frame thing. When initializing the frames, they now set up an empty message. One of the functions inside those methods does something to the frames that makes them behave. Who knows why. 🧐
 
Level 30
Joined
Jun 11, 2017
Messages
989
I see that vJass can replace all GUI-like calls for messages. Any chances for an LUA-like variant?
Cause I have some issues with using this API and don't see my NeatMessages. I'm trying to call my GUI trigger using NeatMessage() or calling a function that has this NeatMessage()...


UPD:
Well, it works on your LUA map, but on mine, it does not... Seems problem on my side.
UPD #2:
Well, works on my side now too. Anyway - if its needed, adding a GUI-replacement for the LUA version would be appreciated.
 
Last edited:
Level 30
Joined
Jun 11, 2017
Messages
989
Also next issue:

for some unknown reason the text inside the box didn't fit.

View attachment 471061

here's the code
JASS:
private function init takes nothing returns nothing
    ....
  
    // Init Neat Message
    set nMsg = NeatFormat.create()
    set nMsg.horizontalAlignment = TEXT_JUSTIFY_LEFT

    ....
endfunction
JASS:
private function doSomething takes nothing returns nothing
    ....
    // Msg
    // call NeatMessage("test")
    call NeatMessageToPlayerFormatted(owner, "|cffffcc00NOTE:|r If you are unable to locate your unit, pressing |cffffcc00F1|r will select it.", nMsg)
    call DisplayTimedTextToPlayer(owner, 0, 0, 5, udg_playerColor[userId + 1] + GetPlayerName(owner) + "|r picked " + GetUnitName(pickedUnit) + "")
    ....
endfunction

but if I add NeatMessage() above of it, it works.
JASS:
    // Msg
    call NeatMessage("hello")
    call NeatMessageToPlayerFormatted(owner, "|cffffcc00NOTE:|r If you are unable to locate your unit, pressing |cffffcc00F1|r will select it.", nMsg)
    call DisplayTimedTextToPlayer(owner, 0, 0, 5, udg_playerColor[userId + 1] + GetPlayerName(owner) + "|r picked " + GetUnitName(pickedUnit) + "")

View attachment 471062


Persists in the current LUA version, forcing me as user to create empty NeatMessage before first NeatMessage to use.
 
Update:
  • Added the REPLACE_BLIZZARD_FUNCTION_CALLS feature from the JASS version to the Lua version, using Bribe's Hook library.

It works in my tests. Can you pm me the relevant code so I can take a look?
Issue has been resolved. It was a version mismatch.
 
Level 30
Joined
Jun 11, 2017
Messages
989
If I were to guess, you're missing this script Get Handle Type
It has the HandleType variable.
Now it works! However when you change (yes, thank you, Blizzard) HUD size by new option, it will dramatically break the overall looks of NeatMessages.
Old ones became like that:
1731777777639.png

See smaller on top.

And new ones:
1731777793794.png

Like that. It also wraps up strangely by that after save & load.

UPD: The "HUD Scale" affects only if you play in Reforged mode, it doesn't do anything if play on SD. So solution is to force map to be SD only, I guess. At least for now.
1731777942506.png
 

Uncle

Warcraft Moderator
Level 73
Joined
Aug 10, 2018
Messages
7,866
Now it works! However when you change (yes, thank you, Blizzard) HUD size by new option, it will dramatically break the overall looks of NeatMessages.
Old ones became like that:

See smaller on top.

And new ones:

Like that. It also wraps up strangely by that after save & load.

UPD: The "HUD Scale" affects only if you play in Reforged mode, it doesn't do anything if play on SD. So solution is to force map to be SD only, I guess. At least for now.
I'm sure there's a way to fix these custom UI frames to work with the new UI scaling feature. But it's a little silly to think that this new and more importantly OPTIONAL feature would play nice with custom made UI, so I wouldn't blame Blizzard (for once). Mapmakers could already customize and scale UI before this update, this feature is basically meant for ladder games.
 
Level 30
Joined
Jun 11, 2017
Messages
989
I'm sure there's a way to fix these custom UI frames to work with the new UI scaling feature. But it's a little silly to think that this new and more importantly OPTIONAL feature would play nice with custom made UI, so I wouldn't blame Blizzard (for once). Mapmakers could already customize and scale UI before this update, this feature is basically meant for ladder games.
Well, this is another example that SD custom maps are superior to HD ones. Joking. :ogre_haosis:
 
We could probably make a GetLocalPlayerUIScale function by measuring the size of the ConsoleUIBackdrop. Question is whether the frames would all be placed correctly just by scaling them by the inverse of that value or if it's more complicated.

@Tasyen
aye, that works. One can use BlzFrameSetScale to mimic/counter UI Scale option the value one can get from xSize of "ConsoleUIBackdrop" /0.8.
Or one uses a parent that uses it, then the custom frame autouses it. if one is lucky it works flawless.

For Text frames it works better when one scales the direct parent, In TasTooltipbox first I tried to scale the super parent but then text & box had wrong Size/Position. Then I scaled the direct Parent of Text & box and now it plays along.

Edit: BlzFrameSetScale(frame, 1) makes the frame have normal scale.
 
Last edited:
Top