Wc3C.net

Wc3C.net (http://www.wc3c.net/forums.php)
-   Scripts (http://www.wc3c.net/forumdisplay.php?f=737)
-   -   DisplayCenteredText (http://www.wc3c.net/showthread.php?t=102602)

Anitarf 09-17-2008 01:26 AM

DisplayCenteredText
 
This library requires Table.
It was developed based on my research posted here.

Collapse JASS:
library DisplayCenteredText initializer Init requires Table

//*****************************************************************
//*  DisplayCenteredText 2.0
//*
//*  written by: Anitarf
//*
//*  A set of functions for displaying centered game messages. The
//*  functions do two things in order to center the message: first,
//*  they add spaces at the start of the message string so the
//*  message is "pushed" to the center of the area available for
//*  game messages, which is about two thirds of the screen; and
//*  second, they display the message at a certain x offset so the
//*  above mentioned area gets centered on the screen.
//*
//*  The values used were experimentally determined and are only
//*  approximations, but results are very reliable in practice in
//*  nearly all game resolution and with almost all input strings.
//*
//*  The following functions are available:
//*
//*    function GetCenteredMessage takes string line returns string
//*    function DisplayCenteredTextToPlayer takes player toPlayer, real y, string message returns nothing
//*    function DisplayTimedCenteredTextToPlayer takes player toPlayer, real y, real duration, string message returns nothing
//*
//*  Note that if the string is too long to fit in the available
//*  area then the game will split it before displaying, centering
//*  won't work in this case, the solution is to give the functions
//*  shorter strings to work with.
//*
//*  Version 2.0 ignores colour codes when calculating the length
//*  of the string so coloured strings are properly centered now.
//*****************************************************************

    globals
        private constant real DEFAULT_CHAR_WIDTH = 156 //default width for all undefined characters
        private StringTable uppercase
        private StringTable lowercase
    endglobals

    private function Init takes nothing returns nothing
        set uppercase = StringTable.create()
        set lowercase = StringTable.create()

        // experimentally determined values, in 1/10000 of max message width
        // more info: [url]http://www.wc3campaigns.net/showthread.php?t=90599[/url]
        set uppercase["a"]= 206
        set uppercase["b"]= 162
        set uppercase["c"]= 183
        set uppercase["d"]= 193
        set uppercase["e"]= 153
        set uppercase["f"]= 122
        set uppercase["g"]= 204
        set uppercase["h"]= 200
        set uppercase["i"]=  77
        set uppercase["j"]=  80
        set uppercase["k"]= 183
        set uppercase["l"]= 148
        set uppercase["m"]= 264
        set uppercase["n"]= 200
        set uppercase["o"]= 225
        set uppercase["p"]= 156
        set uppercase["q"]= 237
        set uppercase["r"]= 179
        set uppercase["s"]= 156
        set uppercase["t"]= 151
        set uppercase["u"]= 187
        set uppercase["v"]= 183
        set uppercase["w"]= 282
        set uppercase["x"]= 204
        set uppercase["y"]= 179
        set uppercase["z"]= 179

        set lowercase["a"]= 151
        set lowercase["b"]= 159
        set lowercase["c"]= 147
        set lowercase["d"]= 162
        set lowercase["e"]= 159
        set lowercase["f"]=  98
        set lowercase["g"]= 176
        set lowercase["h"]= 159
        set lowercase["i"]=  65
        set lowercase["j"]=  77
        set lowercase["k"]= 147
        set lowercase["l"]=  68
        set lowercase["m"]= 227
        set lowercase["n"]= 156
        set lowercase["o"]= 166
        set lowercase["p"]= 162
        set lowercase["q"]= 162
        set lowercase["r"]=  98
        set lowercase["s"]= 126
        set lowercase["t"]= 100
        set lowercase["u"]= 159
        set lowercase["v"]= 159
        set lowercase["w"]= 229
        set lowercase["x"]= 159
        set lowercase["y"]= 159
        set lowercase["z"]= 147

        set lowercase["."]=  51
        set lowercase[","]=  55
        set lowercase[" "]=  80
        set lowercase["-"]= 104
    endfunction

    function GetCenteredMessage takes string line returns string
        local string char
        local integer i=0
        local real charwidth
        local real totalwidth=0.0

        loop //get the approximate width of the string
            set char = SubString(line, i, i+1)
            exitwhen char == ""
            if char=="|" then //ignore colour codes
                set char=SubString(line, i+1, i+2)
                if char=="c" then
                    set i=i+9
                elseif char=="r" then
                    set i=i+1
                endif
            else //get the width of the character
                if StringCase(char, false)==char then
                    set charwidth = lowercase[char]
                else
                    set charwidth = uppercase[char]
                endif
                if charwidth == 0.0 then
                    set charwidth = DEFAULT_CHAR_WIDTH
                endif
                set totalwidth=totalwidth+charwidth
            endif
            set i = i + 1
        endloop

        set i = R2I((5000.0-totalwidth/2)/lowercase[" "]) //number of spaces needed
        set char = ""
        loop
            exitwhen i<=3 //safety margin, better add one space too few than one space too many
            set char=char+" "
            set i=i-1
        endloop
        return char+line
    endfunction
    
    function DisplayCenteredTextToPlayer takes player toPlayer, real y, string message returns nothing
        call DisplayTextToPlayer(toPlayer, 0.25, y, GetCenteredMessage(message))
    endfunction
    function DisplayTimedCenteredTextToPlayer takes player toPlayer, real y, real duration, string message returns nothing
        call DisplayTimedTextToPlayer(toPlayer, 0.25, y, duration, GetCenteredMessage(message))
    endfunction

endlibrary

Vexorian 09-18-2008 08:51 PM

Ok.

It works, however it really does a lot of gamecache calls, I hope people don't call this too frequently on long texts.

Perhaps preloading a text's total width... Either way it is good enough for approval, it can't get much more efficient than this.

Ammorth 09-19-2008 12:37 AM

Gamecache is really the only "safe" way to get a value from a character. You could use a Str2Int return bug, but there are issues with saving/loading and unknowns with the string table (may change throughout the game).

Anitarf 09-21-2008 02:29 PM

I fixed one more error that we all missed, when I converted font width values from reals to integers so I could store them in Table I forgot to do the same with DEFAULT_CHAR_WIDTH.

Also, I see I forgot to put links to the libraries this script requires, will do so now.

BTW, it seems the forums automatically add url tags to links even within jass tags.

Here-b-Trollz 09-21-2008 03:06 PM

<>@#$%^&*()_+=:;{}[]~|'\"/`!?

Anitarf 09-21-2008 03:45 PM

Quote:

Originally Posted by Here-b-Trollz
<>@#$%^&*()_+=:;{}[]~|'\"/`!?

Too rare to care about, that's what DEFAULT_CHAR_WIDTH is for.

Here-b-Trollz 09-21-2008 04:06 PM

Oh, ok. But ~~~'s are more common than you think.

aaero 10-03-2008 05:37 AM

Thanks Anitarf! Using this system now. Very easy to use.

Some quick notes:

For amateur developers like me, you might want to include valid sample "y" values in your comments. The first value I tried was 150...needless to say, I couldn't see the message.

It doesn't actually seem to be centering for me, and I'm assuming it's because I'm on a widescreen. The values are a little off to the left. I doubt you can do anything about it...just thought I'd let you know. The effect is still good.

Anitarf 10-03-2008 12:06 PM

Quote:

Originally Posted by aaero
For amateur developers like me, you might want to include valid sample "y" values in your comments. The first value I tried was 150...needless to say, I couldn't see the message.

Oh, the y value is the same as for regular game messages, i.e. you typically want it to be 0. In general, it's value should be between zero and one I believe.

Quote:

It doesn't actually seem to be centering for me, and I'm assuming it's because I'm on a widescreen. The values are a little off to the left. I doubt you can do anything about it...just thought I'd let you know. The effect is still good.
Hmm, tricky. They were a bit to the left for me too when I was testing it in windowed mode, however in fullscreen (on 3:4 or 4:5 monitors) it was nicely centered in all resolutions, so I just assumed it was a window-mode issue.

Anyway, because I find widescreen monitors to be a stupid invention, I'll keep the current x offset value, but if you want you can always modify it in the DisplayCenteredTextToPlayer function, you could even make it a variable and allow players to change it in a menu or something.

aaero 10-04-2008 12:59 PM

Oh yeah, I found the right 'Y' value through trial and error. Any decent developer would probably already know. I'm going with .3 for most of my messages.

Like I said, don't worry about the wide screen. Nothing to be done about it anyway, unless like you said I want to go to the trouble of letting them change it. If I do, I'll be sure to share the code changes with you so you can update the script if you like.

Anitarf 08-12-2010 10:07 AM

Small update, the function now ignores colour codes when parsing strings so that coloured messages are now also accurately centered.


All times are GMT. The time now is 03:12 PM.

Powered by vBulletin (Copyright ©2000 - 2019, Jelsoft Enterprises Ltd).
Hosted by www.OICcam.com
IT Support and Services provided by Executive IT Services