• Listen to a special audio message from Bill Roper to the Hive Workshop community (Bill is a former Vice President of Blizzard Entertainment, Producer, Designer, Musician, Voice Actor) 🔗Click here to hear his message!
  • Read Evilhog's interview with Gregory Alper, the original composer of the music for WarCraft: Orcs & Humans 🔗Click here to read the full interview.

StrSynonyms

Level 11
Joined
Apr 29, 2007
Messages
826
Description:
Messages is a library used to ease the usage of strings for certain messages. Through wrappers you can easily access player names and more.
This is definately optional, it's totally up to you if you prefer:
JASS:
GetPlayerName(somePlayer) + "just owned" + GetPlayerName(someOtherPlayer)
or
JASS:
"%pnc(0)% just owned %pnc(1)%"
Ofcourse it looks different if you use variables for integers:
JASS:
"%pnc(" + someInteger + ")% just pwned %pnc(" + someOtherInteger")%"
Anyway, there are other things which make your life easier.
JASS:
"You recieved %gold%200|r gold."
"Game Time: %time%"
You can even specify custom strings:
JASS:
call RegisterCustomString("mapversion", "1.0")
call DisplayMessage(12, "%mapversion%", 10) //Will display 1.0 for 10 seconds
JASS:
//! zinc

    library StrSynonyms
    {
    
        /*********************************************************************************************************
        
        ~!                      StrSynonyms v1.2
        ~!                          by YourName
              
              
        ~!      W H A T  I S  T H I S  A B O U T ?
        ~           StrSynonyms (name by Anachron <3) is a library to give you a totally new experience of using strings.
        ~           It offers you a completely new syntax for using strings.
        ~           Things that looked like
        ~               GetPlayerName(somePlayer) + " just owned " + GetPlayerName(someOtherPlayer)
        ~           Might now look like this!
        ~               "%pnc(0)% just owned %pnc(0)%"
        
        ~!          This is ofcourse totally optional, you get no real advantage but a difference from the normal syntax!
        
        ~           It features a totally customizable syntax, you can specify everything your custom strings contain.
        ~           Your string enhancement could look like this
        ~               "You recieved %gold%200|r gold"
        ~           Or like this!
        ~               "You recieved ^gold200|r gold"
        ~           If you want something totally confusing
        ~               "#pnc{0}^ just owned #pnc{1}^"
        
        
        ~!      F E A T U R E S
        ~*          As already stated above, a totally custom syntax, also including custom strings.
        ~*          Various handy things like getting a player's name in color or getting a string for the currently
        ~            elapsed gametime.
        ~*          Some other helpful functions like replacing one string in another!
        
        
        ~!      A P I
        ~           All you have to do is to use a string.
        ~           The basic API is the following
        ~               STRING_START (default %)
        ~           +
        ~               STRING_TYPE  (like time)
        ~           +
        ~               STRING_BRACE (default (, isn't needed by a few things)
        ~           +
        ~               STRING_VALUE (optional, like above)
        ~           +
        ~               STRING_BRACE_END (default ), like above)
        ~           +
        ~               STRING_END   (default %)
        
        ~           Examples:
        ~*              %time%      - Get's replaced with the currently elapsed game time.
        ~*              %pnc(0)%    - Get's replaced with the colored player name of Player 1.
        ~*              %gold%      - Get's replaced with the color code of gold. (Warcraft-style ofcourse)
        
        ~           When you're done setting up your string, all you have to do is convert it.
        ~           This is done by using the ConvertString() function or directly per DisplayMessage().
        
        ~           Function list:
        ~*              ConvertString       (string convert) -> string
        ~*              DisplayMessage      (integer player, string message, real time)
        ~                   NOTE: If the player number is above 11, it will be displayed to all players.
        ~*              DisplayMessageXY    (integer player, string message, real time, real x, real y)
        ~*              DisplayMessageToForce && XY
        ~                   Same as above, but takes a force instead of a player.
        ~*              RegisterCustomString(string base, string replace)
        ~                   Registers a custom string, which get's converted from base to replace.
        
        
        ~!      C H A N G E L O G
        ~           v1.2
        ~*              Replaced custom strings with another system
        
        ~           v1.1
        ~*              Renamed from Messages to StrSynonyms (thanks Anachron)
        ~*              Removed player integer values
        ~*              Added custimazeables for:
        ~**                 String end
        ~**                 Brace start
        ~**                 Brace end
        ~*              Added force displaying.
        
        ~           v1.0
        ~*              Initial release
        
       ***********************************************************************************************************/
    
        //Best place to initialize your custom strings.
        //! textmacro STRSYNONYMS_INIT_CUSTOMS
        //! endtextmacro
    
        public
        {
            constant string STRING_MARK_START           = "%";
            constant string STRING_MARK_END             = "%";
            constant string STRING_VALUE_START          = "(";
            constant string STRING_VALUE_END            = ")";
        
            constant string STRING_PLAYER_NAME          = "p";
            constant string STRING_PLAYER_NAME_COLORED  = "pnc";
            constant string STRING_PLAYER_COLOR         = "pc";
            constant string STRING_GOLD                 = "gold";
            constant string STRING_LUMBER               = "lumber";
            constant string STRING_TIME                 = "time";
            
            constant string GOLD_COLOR                  = "FFDC00";
            constant string LUMBER_COLOR                = "00C850";
                     string CUSTOM_STRING                       [];
                     
                     string USER_STRINGS_BASE                   [];
                     string USER_STRINGS_REPLACE                [];
                     integer USER_STRINGS_COUNT         = 0;
        }
        
        
        string PlayerColor[];
        
        integer PlayerRed[];
        integer PlayerGreen[];
        integer PlayerBlue[];
        
        
        timer GameTime;
        integer Hours = 0, Minutes = 0, Seconds = 0;
        
        
        //Player name functions. Pretty basic, there are over 9000 systems for this already.
        //But oh well.
        public function GetPlayerNameColored(player p) -> string
        {
            return "|cff" + PlayerColor[GetPlayerId(p)] + GetPlayerName(p);
        }
        
        public function GetPlayerColorString(player p) -> string
        {
            return "|cff" + PlayerColor[GetPlayerId(p)];
        }
        
        //Might be useful for thins where you need integers to specify colors. (Unit tinting etc)
        public function GetPlayerColorRed(player p) -> integer
        {
            return PlayerRed[GetPlayerId(p)];
        }
        
        public function GetPlayerColorGreen(player p) -> integer
        {
            return PlayerGreen[GetPlayerId(p)];
        }
        
        public function GetPlayerColorBlue(player p) -> integer
        {
            return PlayerBlue[GetPlayerId(p)];
        }
        
        
        public function RegisterCustomString(string base, string replace) -> integer
        {
            USER_STRINGS_BASE[USER_STRINGS_COUNT] = base;
            USER_STRINGS_REPLACE[USER_STRINGS_COUNT] = replace;
            USER_STRINGS_COUNT += 1;
            return USER_STRINGS_COUNT-1;
        }
        
        
        //Returns the index where a certain string starts in another
        public function IndexOf(string from, string find) -> integer
        {
            integer l1 = StringLength(from), l2 = StringLength(find), i = 0;
            
            if (l1 >= l2)
            {
                while(i <= l1 && i+l2 <= l1)
                {
                    if (SubString(from, i, i+l2) == find)
                    {
                        return i;
                    }
                    
                    i += 1;
                }
            }
            
            return -1;
        }
        
        //Searches for a certain string in another and replaces it with a specified one.
        public function ReplaceString(string from, string search, string what) -> string
        {
            integer i = 0;
            
            while(i >= 0)
            {
                i = IndexOf(from, search);
                
                if (i >= 0)
                {
                    from = SubString(from, 0, i) + what + SubString(from, i+StringLength(search), StringLength(from));
                    i = IndexOf(from, search);
                }
            }
            
            return from;
        }
        
        
        //Converts a string with custom codes to a normal one.
        public function ConvertString(string what) -> string
        {
            integer i = 0;
            
            if (IndexOf(what, STRING_MARK_START) >= 0)
            {
                i = 0;
                while(i < 16)
                {
                        what = ReplaceString(what, STRING_MARK_START + STRING_PLAYER_NAME + STRING_VALUE_START + I2S(i) + STRING_VALUE_END + STRING_MARK_END, GetPlayerName(Player(i)));
                        what = ReplaceString(what, STRING_MARK_START + STRING_PLAYER_NAME_COLORED + STRING_VALUE_START + I2S(i) + STRING_VALUE_END + STRING_MARK_END, GetPlayerNameColored(Player(i)) + "|r");
                        what = ReplaceString(what, STRING_MARK_START + STRING_PLAYER_COLOR + STRING_VALUE_START + I2S(i) + STRING_VALUE_END + STRING_MARK_END, GetPlayerColorString(Player(i)));
                        i += 1;
                }
                    
                what = ReplaceString(what, STRING_MARK_START + STRING_GOLD + STRING_MARK_END, "|cff" + GOLD_COLOR);
                what = ReplaceString(what, STRING_MARK_START + STRING_LUMBER + STRING_MARK_END, "|cff" + LUMBER_COLOR);
                
                if (Seconds < 10)
                {
                    if (Minutes < 10)
                    {
                        what = ReplaceString(what, STRING_MARK_START + STRING_TIME + STRING_MARK_END, I2S(Hours)+":0"+I2S(Minutes)+":0"+I2S(Seconds));
                    }
                    else
                    {
                        what = ReplaceString(what, STRING_MARK_START + STRING_TIME + STRING_MARK_END, I2S(Hours)+":"+I2S(Minutes)+":0"+I2S(Seconds));
                    }
                }
                else
                {
                    if (Minutes < 10)
                    {
                        what = ReplaceString(what, STRING_MARK_START + STRING_TIME + STRING_MARK_END, I2S(Hours)+":0"+I2S(Minutes)+":"+I2S(Seconds));
                    }
                    else
                    {
                        what = ReplaceString(what, STRING_MARK_START + STRING_TIME + STRING_MARK_END, I2S(Hours)+":"+I2S(Minutes)+":"+I2S(Seconds));
                    }
                }
                
                if (USER_STRINGS_COUNT > 0)
                {
                    i = 0;
                    while(i < USER_STRINGS_COUNT)
                    {
                        what = ReplaceString(what, STRING_MARK_START + USER_STRINGS_BASE[i] + STRING_MARK_END, USER_STRINGS_REPLACE[i]);
                        i += 1;
                    }
                }
            }
            
            return what;
        }
        
        
        //Should be obvious.
        public function DisplayMessage(integer to, string what, real time)
        {
            what = ConvertString(what);
            
            if (to > 11)
            {
                DisplayTimedTextToPlayer(GetLocalPlayer(), 0, 0, time, what);
            }
            else
            {
                DisplayTimedTextToPlayer(Player(to), 0, 0, time, what);
            }
        }
        
        public function DisplayMessageXY(integer to, string what, real time, real x, real y)
        {
            what = ConvertString(what);
            
            if (to > 11)
            {
                DisplayTimedTextToPlayer(GetLocalPlayer(), x, y, time, what);
            }
            else
            {
                DisplayTimedTextToPlayer(Player(to), x, y, time, what);
            }
        }
        
        public function DisplayMessageToForce(force to, string what, real time)
        {
            integer i = 0;
            what = ConvertString(what);
            
            while(i < 12)
            {
                if (IsPlayerInForce(Player(i), to))
                {
                    DisplayTimedTextToPlayer(Player(i), 0, 0, time, what);
                }
                i += 1;
            }
        }
        
        public function DisplayMessageToForceXY(force to, string what, real time, real x, real y)
        {
            integer i = 0;
            what = ConvertString(what);
            
            while(i < 12)
            {
                if (IsPlayerInForce(Player(i), to))
                {
                    DisplayTimedTextToPlayer(Player(i), x, y, time, what);
                }
                i += 1;
            }
        }
        
        
        function onInit()
        {
            integer i = 12;
        
            PlayerColor[0]  = "FF0303";
            PlayerColor[1]  = "0042FF";
            PlayerColor[2]  = "1CE6B9";
            PlayerColor[3]  = "540081";
            PlayerColor[4]  = "FFFC01";
            PlayerColor[5]  = "FE8A0E";
            PlayerColor[6]  = "20C000";
            PlayerColor[7]  = "E55BB0";
            PlayerColor[8]  = "959697";
            PlayerColor[9]  = "7EBFF1";
            PlayerColor[10] = "106246";
            PlayerColor[11] = "4E2A04";
            
            
            PlayerRed[0]  = 0xFF;
            PlayerRed[1]  = 0x00;
            PlayerRed[2]  = 0x1C;
            PlayerRed[3]  = 0x54;
            PlayerRed[4]  = 0xFF;
            PlayerRed[5]  = 0xFE;
            PlayerRed[6]  = 0x20;
            PlayerRed[7]  = 0xE5;
            PlayerRed[8]  = 0x95;
            PlayerRed[9]  = 0x7E;
            PlayerRed[10] = 0x10;
            PlayerRed[11] = 0x4E;
            
            
            PlayerGreen[0]  = 0x03;
            PlayerGreen[1]  = 0x42;
            PlayerGreen[2]  = 0xE6;
            PlayerGreen[3]  = 0x00;
            PlayerGreen[4]  = 0xFC;
            PlayerGreen[5]  = 0x8A;
            PlayerGreen[6]  = 0xC0;
            PlayerGreen[7]  = 0x5B;
            PlayerGreen[8]  = 0x96;
            PlayerGreen[9]  = 0xBF;
            PlayerGreen[10] = 0x62;
            PlayerGreen[11] = 0x2A;
            
            
            PlayerBlue[0]  = 0x03;
            PlayerBlue[1]  = 0xFF;
            PlayerBlue[2]  = 0xB9;
            PlayerBlue[3]  = 0x81;
            PlayerBlue[4]  = 0x01;
            PlayerBlue[5]  = 0x0E;
            PlayerBlue[6]  = 0x00;
            PlayerBlue[7]  = 0xB0;
            PlayerBlue[8]  = 0x97;
            PlayerBlue[9]  = 0xF1;
            PlayerBlue[10] = 0x46;
            PlayerBlue[11] = 0x04;
            
            while(i < 16)
            {
                PlayerColor[i] = "111111";
                PlayerRed[i] = 0x11;
                PlayerGreen[i] = 0x11;
                PlayerBlue[i] = 0x11;
                
                i += 1;
            }
            
            GameTime = CreateTimer();
            TimerStart(GameTime, 1, true, function()
            {
                Seconds += 1;
                
                if (Seconds > 59)
                {
                    Seconds = 0;
                    Minutes += 1;
                    
                    if (Minutes > 59)
                    {
                        Minutes = 0;
                        Hours += 1;
                    }
                }
            });
            
            //! runtextmacro optional STRSYNONYMS_INIT_CUSTOMS();
        }
    }

//! endzinc
 
Last edited:
Level 8
Joined
Oct 3, 2008
Messages
367
Despite how many people might like it, is it actually useful? It's fluff. It doesn't really offer any new functionality or do anything that is very hard to do manually. We have string libraries that do what the string functions like ReplaceString in this do. It doesn't reduce the size of code by much. And, it's veddy veddy inefficient.
 
Level 8
Joined
Oct 3, 2008
Messages
367
:ugly:

What new functionality does this offer? What can't I do manually that this system offers or any of the uploaded string libraries offer?

If it saved obscene amounts of typing, sure. But it doesn't.

I'd might as well submit a wrapper for every WC3 native with shortened names. Oooh, useful.
 
It's actually that you can place an synonym anywhere in the string.

For example:
"%killer% has killed %defeated% for an bonus of %bonus% gold".
This string can be stored anywhere as constant and you will never have to replace the text inside the string.

Basically it changes the way you code, and it does allow you to not need to set a concrete value of an string member.
 
Level 12
Joined
Feb 11, 2008
Messages
809
Also it makes it much, much easier for GUI coders because it doesnt require much JASS knowledge and shortens strings a great amount instead of using game message triggers which are nothing but an annoyance.

once again i vote for approval :thumbs_up:
 
Level 8
Joined
Oct 3, 2008
Messages
367
By "shortening" strings, you mean making them nigh unreadable for the majority of the Jass community. It should make things even harder for GUIers converting to Jass. I really don't feel like sitting down and having to decipher string using scripts from now on.

Display message triggers? What?
 
Level 12
Joined
Feb 11, 2008
Messages
809
as in display message to player for x amount of seconds using different strings and color codes.

it would make it easier by making it shorter and so that you wouldnt have to keep refering back to color codes and other strings.....
 
Level 11
Joined
Apr 29, 2007
Messages
826
Depending on the length of the string, I would place the function call count somewhere in the hundreds if not thousands. Plenty of string leaks, too.

If you don't use up too many custom strings, you won't be calling a lot of functions (around 51).

Well it allows you to constantly use a synonym for something in your strings, like %LastPlayerWhoKilledXY%, as you can always update those custom strings on the desired events.

Another useful idea is using %gameversion%, you probably use this alot, and when you release a new version of your map, you might need to replace all of those and forget some of them. Won't happen with this.

Seriously, don't be so such a dickhead. As you can see some people clearly like it, and just because you "find it harder to read" doesn't mean anything. You should rate this objective.
Some people prefer coding in ASM, I for myself think it is a horrible language to code in, but I would never disapprove a program that is coded in ASM if I'd have to review it.
 
Level 8
Joined
Oct 3, 2008
Messages
367
For a decently long string (40 characters), those ReplaceString calls really pile on the function calls. A lot of em. Way more than 51.

Why would I ever need some mystical %gameversion% when I can have a well documented constant which is both more readable and more efficient?

As for %LastPlayerWhoKilled%, why not have a nice global variable which is both more readable and more efficient?

And yes, readability is very important. This is Jass, and things should look as if they were written in Jass.
 
First of all,

JASS:
    call RegisterCustomString("mapversion", "1.0")
    call DisplayMessage(12, "%mapversion%", 10) //Will display 1.0 for 10 seconds

Displayed %1.0%.
I also added a counter to each of your custom functions and incremented the counter on all native function calls.

The result was over 600 function calls for the map version example.
This is quite useless with these limitations, I'm afraid.

With a longer string (around 50 chars), the count was near 2,000.
 
Top