Snippet Advanced Strings

Status
Not open for further replies.

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Darthfett presents:
Advanced Strings

I usually make my systems for whenever I find that I need to be able to do something, and there isn't something already out there. I like having my code relatively neat and easy to read through, so I decided to make an entire system out of common things I need to do with a string.

It started out because I'm creating a lot of text messages, but I don't want to overwhelm the player with a wall of white text. So I decided to make a mini library of common colors I used, with simple variable names for them, instead of an impossible to read |c00ff0000 "Yay" |r, etc.

Then, I started making commands for my map, but I wanted a lot of functionality, such as in my Multi Kick! system. It's never easy to explain to a player in a short message the "proper syntax" for putting in a command, so why not make your system easy for any player to use.

Here's the system, and an example of how I'm using it:

JASS:
//======================
//======================
//Created by Darthfett
//
//Version 1.65
//
//For use with Patch 1.24
//
//9/07/09
//======================
//======================

//======================
//Thanks to AceHart for finding lots of faster ways to do this,
//and for finding the StringCase function <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
//
//Thanks to Romek for pointing out the StringCase(string,true) != StringCase(string,false)
//comparison as a way of knowing whether a string is letters or not.
//Thanks to SerraAvenger for the idea of using GetHandleId on GetPlayerColor, and the idea of dynamic playercolors
//======================

library AdvStrings initializer Init

//=======================
//Commonly used strings
//=======================

globals
    constant string END =        &quot;|r&quot;
    
    //=========================
    //Example defining of strings:
    constant string LIGHTYELLOW = &quot;|cffffff00&quot;
    constant string YELLOW =      &quot;|cffffcc00&quot;
    constant string GREEN =       &quot;|cff00ff00&quot;
    constant string BLUE =        &quot;|cff0000ff&quot;
    constant string RED =         &quot;|cffff0000&quot;
    constant string BROWN =       &quot;|cffcc9933&quot;
    constant string ORANGE =      &quot;|cffff6400&quot;
    constant string DARKGREEN =   &quot;|cff009600&quot;
    constant string AQUA =        DARKGREEN
    constant string DARKBLUE =    &quot;|cff000096&quot;
    constant string DARKRED =     &quot;|cff960000&quot;
    constant string DARKTEAL =    &quot;|cff009696&quot;
    constant string DARKCYAN =    DARKTEAL
    constant string DARKORANGE =  &quot;|cffc86400&quot;
    constant string DARKGRAY =    &quot;|cff666666&quot;
    constant string DARKGREY =    DARKGRAY
    
    //Example Usage:
    //call BJDebugMsg(YELLOW + &quot;some string&quot; + END)
    //call BJDebugMsg(GREEN + &quot;don&#039;t kill&quot; + END + RED + &quot; that &quot; + END + GREEN + &quot;unit!&quot; + END)
    //=========================
endglobals

globals    
//These three are private on PURPOSE!  Use the P2CS,I2CS,P2CSN,I2CSN for the playerColorStr and playerColoredName functions.
    private string array playerColors         //EX: &quot;red&quot;, &quot;blue&quot;, ... &quot;lightblue&quot;... etc.
    private string array playerColorStr       //EX: &quot;|cffff0303&quot; 
    private string array playerColoredName    //EX: A player&#039;s name colored in their own unit colors
    
    //temp
    
    private integer temp
    private string array tempColors
    private string array tempColors2
endglobals

//=========================
//String-Type Comparisons -- System independent.  Copy and pasta as you need.
//=========================

function IsInt takes string s returns boolean
//Does not Auto-Inline (returns whether a string is an integer, for strings longer than 8, see isNumeric
    return I2S(S2I(s)) == s
endfunction

function IsNumeric takes string str returns boolean
//returns whether a string only contains numbers
    local integer i = 0
    local string s
    loop
        set s = SubString(str, i, i + 8)
        exitwhen s == &quot;&quot;
        if I2S(S2I(s)) != s then
            return false
        endif
        set i = i + 8
    endloop
    return true
endfunction    

function IsLetter takes string s returns boolean
//returns whether a character is a letter
    return I2S(S2I(s)) == s and StringCase(s,true) != StringCase(s,false)
endfunction

function IsLetters takes string s returns boolean
//returns whether a string only contains letters
    local integer i = 0
    local string str
    loop
        set str = SubString(s, i, i + 1)
        exitwhen str == &quot;&quot;
        if StringCase(s,true) == StringCase(s,false) then
            return false
        endif
        set i = i + 1
    endloop
    return true
endfunction

function IsMeta takes string s returns boolean
//returns whether a character is a metacharacter
    return I2S(S2I(s)) != s and StringCase(s,true) == StringCase(s,false)
endfunction

function IsMetas takes string s returns boolean
//returns whether a string only contains metacharacters
    local integer i = 0
    local string str
    if StringCase(s,true) != StringCase(s,false) then
        return false
    endif
    loop
        set str = SubString(s, i, i + 8)
        exitwhen str == &quot;&quot;
        if I2S(S2I(str)) != str then
            return false
        endif
        set i = i + 8
    endloop
    return true
endfunction

//===================
// String Formatting -- System independent.  Copy and pasta as you need.
//===================
            
function RemoveChar takes string s, string char returns string
//Removes all instances of one character from an entire string
    local integer i = 0
    local string str = &quot;&quot;
    local string c
    loop
        set c = SubString(s, i, i + 1)
        exitwhen c == &quot;&quot;
        if c != char then
            set str = str + c
        endif
        set i = i + 1
    endloop
    return str
endfunction

function RemoveNumbers takes string s returns string
//Remove all numeric characters from a string
    local integer i = 0
    local string str = &quot;&quot;
    local string c
    loop
        set c = SubString(s,i,i+1)
        exitwhen c == &quot;&quot;
        if I2S(S2I(c)) != c then
            set str = str + c
        endif
        set i = i + 1
    endloop
    return str
endfunction

function RemoveLetters takes string s returns string
//Remove all letters from a string
    local integer i = 0
    local string str = &quot;&quot;
    local string c
    loop
        set c = SubString(s,i,i+1)
        exitwhen c == &quot;&quot;
        if StringCase(c,true) == StringCase(c,false) then
            set str = str + c
        endif
        set i = i + 1
    endloop
    return str
endfunction

function RemoveMetas takes string s returns string
//Remove all meta characters from a string
    local integer i = 0
    local string str = &quot;&quot;
    local string c
    loop
        set c = SubString(s,i,i+1)   
        exitwhen c == &quot;&quot;
        if I2S(S2I(c)) == c or StringCase(c,true) != StringCase(c,false) then
            set str = str + c
        endif
        set i = i + 1
    endloop
    return str
endfunction

function RemoveUpper takes string str returns string
//Removes all uppercase letters from a string
    local integer i = 0
    local string s = &quot;&quot;
    local string c
    loop
        set c = SubString(str,i,i+1)
        exitwhen c == &quot;&quot;
        if StringCase(c,false) == c then
            set s = s + c
        endif
        set i = i + 1
    endloop
    return s
endfunction

function RemoveLower takes string str returns string
//Removes all lowercase letters from a string
    local integer i = 0
    local string s = &quot;&quot;
    local string c
    loop
        set c = SubString(str,i,i+1)
        exitwhen c == &quot;&quot;
        if StringCase(c,true) == c then
            set s = s + c
        endif
        set i = i + 1
    endloop
    return s
endfunction

function ReplaceString takes string str, string substr, string replacement returns string
//Finds all instances of substr in str, and replaces them with replacement
    local string new
    local integer i = 0
    local integer strlen = StringLength(str)
    local integer sublen = StringLength(substr)
    if sublen &gt; strlen then
        return str
    endif
    loop
        exitwhen i+sublen &gt; strlen
        if SubString(str,i,i+sublen) == substr then
            set new = new + SubString(str,i,i+sublen)
        else
            set new = new + SubString(str,i,i+1)
        endif
        set i = i + 1
    endloop
    return new + SubString(str,i,strlen)
endfunction

//================
// String Seeking -- System independent.  Copy and pasta as you need.
//================

function StringContainsString takes string str, string partial returns boolean
    //Returns true if the full string is contained inside.  Capitalization matters!
    local integer i = 0
    local integer l = StringLength(partial)
    local integer l2 = StringLength(str)
    loop
        exitwhen i &gt; l2
        if SubString(str,i,i+l) == partial then
            return true
        endif
        set i = i + 1
    endloop
    return false
endfunction

function GetStringFirstIndex takes string s, string partial returns integer
//Searches through the string to find the SubString
//If found, it returns the start index
//returns 0 if not found
    local integer i = 0
    local integer l = StringLength(partial)
    local integer l2 = StringLength(s)
    loop
        exitwhen i &gt;= l2
        if SubString(s,i,i+l) == partial then
            return i
        endif
        set i = i + 1
    endloop
    return 0 //String does not contain string.
    //This should never happen if you first check that the string contains the string already.
endfunction

function GetStringLastIndex takes string str, string partial returns integer
    //Searches through the string to find the partial string.
    //If it finds it, it returns the integer after the index.
    //returns 0 if not found
    local integer i = 0
    local integer l = StringLength(partial)
    local integer l2 = StringLength(str)
    loop
        exitwhen i &gt; l2
        if SubString(str,i,i+l) == partial then
            return i + l
        endif
        set i = i + 1
    endloop
    return 0 //String does not contain string.  
    //This should never happen if you first check that the string contains the string already.
endfunction

function GetStringToChar takes string str, integer i, string char returns string
//Gets from i, the start of the substring, to the next instance of char, or til the end of the line.
    local integer j = i
    local integer l = StringLength(str)
    local string s = &quot;&quot;
    local string c
    loop
        set c = SubString(str,j,j+1)
        exitwhen c == &quot;&quot; or c == char
        set s = s + c
        set j = j + 1
    endloop
    return s
endfunction

//===============
//PlayerStrings -- All the playerstring functions require other functions in the library. NOT system indepenent!!
//===============

function P2CS takes player p returns string
//Player to Colored String returns the hex color code of the player&#039;s color
    return playerColorStr[GetHandleId(GetPlayerColor(p))]
endfunction

function I2CS takes integer i returns string
//Integer to Colored String returns the hex color code of the player&#039;s color
    return playerColorStr[GetHandleId(GetPlayerColor(Player(i)))]
endfunction

function P2CSN takes player p returns string
//Player to Colored String Name returns the colored player&#039;s Name
    return playerColorStr[GetHandleId(GetPlayerColor(p))] + GetPlayerName(p) + END
endfunction

function I2CSN takes integer i returns string
//Integer to Colored String Name returns the colored player&#039;s Name
    return playerColorStr[GetHandleId(GetPlayerColor(Player(i)))] + GetPlayerName(Player(i)) + END
endfunction

function S2P takes string argstr returns player
//String to Player returns a player from a Player&#039;s color (e.g. &quot;Blue&quot;, &quot;Light Blue&quot;, &quot;lIghtBlUe&quot;),
//a player&#039;s number (1 for red, 2 for blue),
//a player&#039;s name (e.g. &quot;Darthfett&quot;),
//or a piece of a player&#039;s name (e.g. &quot;Darth&quot;).
//Invalid names return Player(12) (Neutral Passive) in Debug Mode, or null when not in debug mode.
    local string s = RemoveChar(StringCase(argstr,false),&quot; &quot;)
    local integer i = 0
    local playercolor color
    
    if &quot;gray&quot; == s then
        loop
            exitwhen temp &gt;= 12
            if GetPlayerColor(Player(12)) == PLAYER_COLOR_LIGHT_GRAY then
                return Player(temp)
            endif
            set temp = temp + 1
        endloop
    endif
    
    set temp = S2I(s)
    if I2S(temp) == s then
        if temp &lt; 13 and temp &gt; 0 then
            return Player(temp-1)
        else
            debug call BJDebugMsg(&quot;ERROR: Advanced Strings - S2P: Invalid player number&quot;)
            debug return Player(12) //to avoid crashes
            return null
        endif
    endif
    
    set temp = 0
    loop
        exitwhen temp &gt;= 12
        if playerColors[temp] == s then
            set color = ConvertPlayerColor(temp)
            loop
                exitwhen i &gt;= 12
                if color == GetPlayerColor(Player(i)) then
                    return Player(i)
                endif
                set i = i + 1
            endloop
        endif
        set temp = temp + 1
    endloop
    
    set temp = 0
    loop
        exitwhen temp &gt;= 12
        if StringContainsString(RemoveChar(StringCase(GetPlayerName(Player(temp)),false),&quot; &quot;),s) then
            return Player(temp)
        endif
        set temp = temp + 1
    endloop
    debug call BJDebugMsg(&quot;ERROR: Advanced Strings - S2P: Invalid player string&quot;)
    debug return Player(12) //to avoid crashes
    return null
endfunction

function S2PI takes string argstr returns integer
//String to PlayerId returns the player number in a similar fashion to that of S2P.
//Invalid arguments in debug mode will return 12, for Player Neutral Passive, or -1 when not in debug mode.
    local string s = RemoveChar(StringCase(argstr,false),&quot; &quot;)
    local integer i = 0
    local playercolor color
    
    if &quot;gray&quot; == s then //simplest comparisons first is the most efficient way, as it means less calculations in some cases.
        loop
            exitwhen temp &gt;= 12
            if GetPlayerColor(Player(12)) == PLAYER_COLOR_LIGHT_GRAY then
                return temp
            endif
            set temp = temp + 1
        endloop
    endif
    
    set temp = S2I(s)    
    if I2S(temp) == s then
        if temp &lt; 13 and temp &gt; 0 then
            return temp-1
        else
            debug call BJDebugMsg(&quot;ERROR: Advanced Strings - S2PI: Invalid player number&quot;)
            return 0
        endif
    endif
    
    set temp = 0
    loop
        exitwhen temp &gt;= 12
        if playerColors[temp] == s then
            set color = ConvertPlayerColor(temp)
            loop
                exitwhen i &gt;= 12
                if color == GetPlayerColor(Player(i)) then
                    return i
                endif
                set i = i + 1
            endloop
        endif
        set temp = temp + 1
    endloop
    
    set temp = 0
    loop
        exitwhen temp &gt;= 12
        if StringContainsString(RemoveChar(StringCase(GetPlayerName(Player(temp)),false),&quot; &quot;),s) then
            return temp
        endif
        set temp = temp + 1
    endloop
    debug call BJDebugMsg(&quot;ERROR: Advanced Strings - S2PI: Invalid player number&quot;)
    return 0
endfunction

//======================
//Initializing Strings -- Used for the Player String functions
//======================
private function Init takes nothing returns nothing
//Variable Initializing

    set playerColors[0] = &quot;red&quot;
    set playerColors[1] = &quot;blue&quot;
    set playerColors[2] = &quot;teal&quot;
    set playerColors[3] = &quot;purple&quot;
    set playerColors[4] = &quot;yellow&quot;
    set playerColors[5] = &quot;orange&quot;
    set playerColors[6] = &quot;green&quot;
    set playerColors[7] = &quot;pink&quot;
    set playerColors[8] = &quot;grey&quot;
    set playerColors[9] = &quot;lightblue&quot;
    set playerColors[10] = &quot;darkgreen&quot;
    set playerColors[11] = &quot;brown&quot;
    
    set playerColorStr[0] = &quot;|cffff0303&quot;
    set playerColorStr[1] = &quot;|cff0042ff&quot;
    set playerColorStr[2] = &quot;|cff1ce6b9&quot;
    set playerColorStr[3] = &quot;|cff540081&quot;
    set playerColorStr[4] = &quot;|cfffffc01&quot;
    set playerColorStr[5] = &quot;|cfffeba0e&quot;
    set playerColorStr[6] = &quot;|cff20c000&quot;
    set playerColorStr[7] = &quot;|cffr55bb0&quot;
    set playerColorStr[8] = &quot;|cff959697&quot;
    set playerColorStr[9] = &quot;|cff7ebff1&quot;
    set playerColorStr[10] = &quot;|cff107246&quot;
    set playerColorStr[11] = &quot;|cff4e2a04&quot;
endfunction

endlibrary


The "i" variable would be set to the start index, after -zoom, and before the 1000, which is used in the GetStringToChar function. The GetStringToChar function then takes the string, and outputs the number, from the 1 to the 0, since it then reaches the end of the line, or a space.

This is useful when you want players to be able to type multiple commands in one line, such as "-ap -zoom1200" I will admit the example doesn't really work very well here, since zoom is a function you want to be able to say during chat without the game thinking it's a command, but when you need it for setting the number of rounds of a game, for example, it could be useful. :)

Comments, suggestions, and questions are all welcome! :D
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,494
> that gets rid of the IsStringNumber

Maybe.
Obviously though, it's not going to work on strings like "1293875478234756982137168905".
Still, doing that test on 8-9 characters blocks will be much faster than your weird double-loop.


EDIT:
Actually, I thought RemoveCaps would do what its name says, to remove caps.
However, it actually converts the string to lower case...
Ever seen StringCase?


And, on a related note, you could save a great deal of SubString calls by using an array of single character strings instead of your caps / nocaps / nums strings.


More EDITs:
JASS:
set nums[0] = &quot;0&quot;
set nums[1] = &quot;1&quot;
set nums[2] = &quot;2&quot;
set nums[3] = &quot;3&quot;
set nums[4] = &quot;4&quot;
set nums[5] = &quot;5&quot;
set nums[6] = &quot;6&quot;
set nums[7] = &quot;7&quot;
set nums[8] = &quot;8&quot;
set nums[9] = &quot;9&quot;

function isDigit_WithLoop takes string s returns boolean
    local integer i = 0
    loop
        if s == nums<i> then
            return true
        endif
        set i = i + 1
        exitwhen i &gt; 9
    endloop
    return false
endfunction

function isDigit takes string s returns boolean
    return s == &quot;0&quot; or s == &quot;1&quot; or s == &quot;2&quot; or s == &quot;3&quot; or s == &quot;4&quot; or s == &quot;5&quot; or s == &quot;6&quot; or s == &quot;7&quot; or s == &quot;8&quot; or s == &quot;9&quot;
endfunction

function RemoveAlpha takes string str returns string
    local integer i = 0
    local string s = &quot;&quot;
    local string c

    loop
        set c = SubString(str, i, i + 1)
        exitwhen c == null
        if isDigit(c) then
            s = s + c
        endif
        set i = i + 1
    endloop
    return s
endfunction

function RemoveChar takes string str,string char returns string
    local integer i = 0
    local string s = &quot;&quot;
    local string c

    loop
        set c = SubString(str, i, i + 1)
        exitwhen c == null
        if c != char then
            s = s + c
        endif
        set i = i + 1
    endloop
    return s
endfunction

function isNumeric takes string str returns boolean
    local integer i = 0
    local string s
    loop
        set s = SubString(str, i, i + 8)
        exitwhen s == null
        if I2S(S2I(s)) != s then
            return false
        endif
        set i = i + 8
    endloop
    return true
endfunction
</i>


Unverified and untested as usual :p
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Version 1.10 out. :p

Wow, AceHart. Lots of good ideas :)

>Obviously though, it's not going to work on strings like "1293875478234756982137168905".

But who really needs that? :p The only reason I can see someone needing to parse a string of numbers longer than 8, would be if they were going to break up the string into numbers later, in which case they can just do the I2S(S2I()).

>Actually, I thought RemoveCaps would do what its name says, to remove caps.
However, it actually converts the string to lower case...
Ever seen StringCase?

I was basically remaking that function, but slower... :rolleyes:

I've fixed the library so that it replaces the old RemoveCaps with StringCase(string,false), and I've made it so RemoveCaps removes capital letters, and the same with RemoveLowerCase().

>And, on a related note, you could save a great deal of SubString calls by using an array of single character strings instead of your caps / nocaps / nums strings.

I thought about it for the caps/nocaps, but I wanted to be lazy :p. Fixed it, and made all three into string arrays.

I have been confused in the past about whether local strings need to be nulled (set str = "") at the end of the function. I used to say yes, but recently I haven't seen anyone doing it. It hasn't come up before, but now that it has, it would be nice to be sure about it. :)

Do local strings need to be nulled?

I fixed a few of my new functions in this as well.
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,494
Want to be even more lazy in setup?

JASS:
local string abc = &quot;ABC...Z&quot;
local integer i = 0
loop
    set caps<i> = SubString(abc, i, i + 1)
    set nocaps<i> = SringCase(caps<i>, false)
    set i = i + 1
    exitwhen i &gt;= 26
endloop
</i></i></i>



Btw, isDigitLooped needs an array of digits, not a string.
 

AceHart

Your Friendly Neighborhood Admin
Reaction score
1,494
You'd save a bunch of extra strings and gain some speed too if
> if SubString(str,i,i+1) == caps[j] then
Stored that substring before the loop instead of getting it on each run.


return S2I(I2S(<string>)) == <string> and StringLength(<string>) == 1
 
Reaction score
341
You could change something like

JASS:
yellow + &quot;This system is &quot; + end


to

JASS:

private function ColorString takes string s, string color returns string
    return color + s + |r
endfunction

ColorString(&quot;This system is &quot;, &quot;yellow&quot;)
 

Flare

Stops copies me!
Reaction score
662
Why would you want to do that? Then you'd have to do
JASS:
call BJDebugMsg (ColourString (&quot;This&quot;, red) + ColourString (&quot;is&quot;, orange) + ColourString (&quot;very&quot;, yellow) + ColourString (&quot;awkward&quot;, green))

as opposed to
JASS:
call BJDebugMsg (red + &quot;This |r&quot; + orange + &quot;isn&#039;t +|r&quot; + yellow + &quot;as |r&quot; + green + &quot;awkward|r&quot;)


And if you did want a heavily coloured string, it'd be horribly inefficient (since you have a number of function calls that aren't required with the current method) and ugly
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
Well I went through most of the functions, and improved them.

Also added a few new ones:

-Functions to check if a character/string is only metacharacters (non-alphabet and non-numeric), numeric characters, or only alphabetic characters.

-Functions that remove capitalization, lower case letters, numbers, and metacharacters from strings.

-GetStringFirstIndex added to work like the GetStringLastIndex function

-Better names for functions, such as S2P (StringToPlayer), RemoveUpper, RemoveLower instead of GetPlayerFromFormattedString, RemoveCaps, RemoveLowerCase

-Also improved the debug functionality so that the S2P and S2PlayerId functions will return valid players (and an error message) when debug mode is enabled.

-Added a few extra color strings

as opposed to
JASS:
call BJDebugMsg (red + &quot;This |r&quot; + orange + &quot;isn&#039;t +|r&quot; + yellow + &quot;as |r&quot; + green + &quot;awkward|r&quot;)

which can be simplified even further like this:

JASS:
call BJDebugMsg(red + &quot;Error: &quot;+ end + green + &quot;This is &quot; + end + blue + &quot;super simple!&quot; + end)
 

SerraAvenger

Cuz I can
Reaction score
234
JASS:

//
    set PlayerColorStr[0] = &quot;|cffff0303&quot;
    set PlayerColorStr[1] = &quot;|cff0042ff&quot;
    set PlayerColorStr[2] = &quot;|cff1ce6b9&quot;
    set PlayerColorStr[3] = &quot;|cff540081&quot;
    set PlayerColorStr[4] = &quot;|cfffffc01&quot;
    set PlayerColorStr[5] = &quot;|cfffeba0e&quot;
    set PlayerColorStr[6] = &quot;|cff20c000&quot;
    set PlayerColorStr[7] = &quot;|cffr55bb0&quot;
    set PlayerColorStr[8] = &quot;|cff959697&quot;
    set PlayerColorStr[9] = &quot;|cff7ebff1&quot;
    set PlayerColorStr[10] = &quot;|cff107246&quot;
    set PlayerColorStr[11] = &quot;|cff4e2a04&quot;
    
    loop
        exitwhen i &gt;= 26
        set uc<i> = SubString(ABC,i,i+1)
        set lc<i> = StringCase(uc<i>,false) 
        //I&#039;m still a bit lazy, but at least it runs at map init <img src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" class="smilie smilie--sprite smilie--sprite7" alt=":p" title="Stick Out Tongue    :p" loading="lazy" data-shortname=":p" />
        set i = i + 1
    endloop
    set i = 0
    
    set PlayerColors[0] = &quot;Red&quot;
    set PlayerColors[1] = &quot;Blue&quot;
    set PlayerColors[2] = &quot;Teal&quot;
    set PlayerColors[3] = &quot;Purple&quot;
    set PlayerColors[4] = &quot;Yellow&quot;
    set PlayerColors[5] = &quot;Orange&quot;
    set PlayerColors[6] = &quot;Green&quot;
    set PlayerColors[7] = &quot;Pink&quot;
    set PlayerColors[8] = &quot;Gray&quot;
    set PlayerColors[9] = &quot;Light Blue&quot;
    set PlayerColors[10] = &quot;Dark Green&quot;
    set PlayerColors[11] = &quot;Brown&quot;
    
    loop
        exitwhen i &gt;= 12
        set ColoredPlayerNames<i> = PlayerColors<i> + PlayerNames<i> + end
        set i = i + 1
    endloop
</i></i></i></i></i></i>

This part still needs some work...
JASS:

set ColoredPlayerNames<i> = PlayerColors<i> + PlayerNames<i> + end        </i></i></i>

Wouldn't that be "YellowSerraAvenger" instead of "cffffcc01SerraAvenger" ?

JASS:

    set PlayerColors[0] = &quot;Red&quot;


Don't use static indicies here. Players can be in slot one and take green as their player color.

I'ld use this:
JASS:

// public function INIT etc etc pp
    local string array playerColorString
    local string array playerColor


// The stuff between the locals and the code...

    set playerColorStr[0] = &quot;|cffff0303&quot;
    set playerColorStr[1] = &quot;|cff0042ff&quot;
    set playerColorStr[2] = &quot;|cff1ce6b9&quot;
    set playerColorStr[3] = &quot;|cff540081&quot;
    set playerColorStr[4] = &quot;|cfffffc01&quot;
    set playerColorStr[5] = &quot;|cfffeba0e&quot;
    set playerColorStr[6] = &quot;|cff20c000&quot;
    set playerColorStr[7] = &quot;|cffr55bb0&quot;
    set playerColorStr[8] = &quot;|cff959697&quot;
    set playerColorStr[9] = &quot;|cff7ebff1&quot;
    set playerColorStr[10] = &quot;|cff107246&quot;
    set playerColorStr[11] = &quot;|cff4e2a04&quot;
    
// Strange ABC thingie

    set i = 0
    
    set playerColor[0] = &quot;Red&quot;
    set playerColor[1] = &quot;Blue&quot;
    set playerColor[2] = &quot;Teal&quot;
    set playerColor[3] = &quot;Purple&quot;
    set playerColor[4] = &quot;Yellow&quot;
    set playerColor[5] = &quot;Orange&quot;
    set playerColor[6] = &quot;Green&quot;
    set playerColor[7] = &quot;Pink&quot;
    set playerColor[8] = &quot;Gray&quot;
    set playerColor[9] = &quot;Light Blue&quot;
    set playerColor[10] = &quot;Dark Green&quot;
    set playerColor[11] = &quot;Brown&quot;
    
    loop
        exitwhen i &gt;= 12
        set ColoredPlayerNames<i> = PlayerColors[ H2I( GetPlayerColor( Player( i ) ) ) ] + PlayerNames<i> + end
        set i = i + 1
    endloop
</i></i>



best wishes, Davey
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
JASS:
set ColoredPlayerNames<i> = PlayerColors<i> + PlayerNames<i> + end        </i></i></i>

Wouldn't that be "YellowSerraAvenger" instead of "cffffcc01SerraAvenger" ?


Yes, I found the bug in my own system just before you posted this up here. Fixed in the new version. :p

JASS:
    set PlayerColors[0] = &quot;Red&quot;


Don't use static indicies here. Players can be in slot one and take green as their player color.

I'd use this:
JASS:
    loop
        exitwhen i &gt;= 12
        set ColoredPlayerNames<i> = PlayerColors[ H2I( GetPlayerColor( Player( i ) ) ) ] + PlayerNames<i> + end
        set i = i + 1
    endloop
</i></i>


Ingenious. I didn't know predefined functions that convert integer to handle really worked this way. +rep, added in the new version.

For anyone who doesn't feel like reading through his post to understand the bug, here's the changelog for v1.3.

Initialization has been sped up a bit, it now correctly identifies the color string arrays with players on maps where they can change their color before-game.

It now only works with Patch 1.24, as it uses GetHandleId (but can be easily reverted to H2I, if you replace it in the Init function.

I'm now going to document each function, so it's easier to see which functions require the use of the globals/Init function. I don't want to require people to copy the entire library over, when a simple function copy will do.

EDIT:

First post has been updated with the newest version. It has been recategorized into two libraries. The first library contains only standalone functions that do not require external variables or functions (You can copy these functions individually if you like).

The second library now contains all functions that require other variables, and/or functions, that may require other variables and/or functions (including those from the StringFuncs library). In order to make them work, it will be easiest to simply copy both libraries into your map.

Updated function naming, and updated the function documentation to reflect some possible crashes that could come from user-stupidity (Such as Player(S2PI("#^#@")) ).

With this version, I have also added the ReplaceString function which replaces all instances of a string in a string with a different string.
 

ZugZugZealot

New Member
Reaction score
33
You should do...
JASS:
constant string aqua =   darkgreen
Dark green is refered to as "aqua" in JASS. Or otherwise the game play constant for that player color is "PLAYER_COLOR_AQUA".
 

Romek

Super Moderator
Reaction score
963
In RemoveMetas, instead of the loop to check if a character is either a small or capital letter, how about doing this?
JASS:
if StringCase(char, false) == StringCase(char, true) then
 // It&#039;s a &#039;meta character&#039;

Numbers have already been filtered at this point.


I don't think it'd be wise to return -1 in S2PI.
JASS:
Player(S2PI(&quot;..&quot;))

wouldn't be too nice. :p
 

Darthfett

Aerospace/Cybersecurity Software Engineer
Reaction score
615
You should do...
JASS:
constant string aqua =   darkgreen
Dark green is refered to as "aqua" in JASS. Or otherwise the game play constant for that player color is "PLAYER_COLOR_AQUA".

The constants string area is really there as an example. It's meant to be added to and modified as needed. I'll add it in because it is in JASS, but just keep that in mind. ;)

In RemoveMetas, instead of the loop to check if a character is either a small or capital letter, how about doing this?
JASS:
if StringCase(char, false) == StringCase(char, true) then
 // It&#039;s a &#039;meta character&#039;

Numbers have already been filtered at this point.

Brilliant idea. :D Added, and improved the speed of all the Int/Meta/Letter functions. The ABCD.., abcd.., and 1234.. variables are no longer needed, they have been removed.


I don't think it'd be wise to return -1 in S2PI.
JASS:
Player(S2PI(&quot;..&quot;))

wouldn't be too nice. :p

Considering there's an S2P function, I'd say that this would be a stupid mistake by the user. However, to avoid crashing with arrays, I'll change it to 0. I also changed the GetStringFirstIndex and GetStringLastIndex to return 0 for invalid, rather than -1.

== Update to system version 1.60, due to the great increases in system performance and function-system independence. ==
 

trb92

Throwing science at the wall to see what sticks
Reaction score
142
JASS:
            debug call BJDebugMsg(&quot;ERROR: Kick System - String2Player: Invalid player number&quot;)

This doesn't look like a Kick System to me. Kicking is only one possible use of the functions here. This actually looks like the "Advanced Strings" system. The errors should reflect that to easily track down where the issue is. This is in the S2P function, and the S2PI also refers to "Kick System".
 

quraji

zap
Reaction score
144
JASS:
            debug call BJDebugMsg(&quot;ERROR: Kick System - String2Player: Invalid player number&quot;)

This doesn't look like a Kick System to me. Kicking is only one possible use of the functions here. This actually looks like the "Advanced Strings" system. The errors should reflect that to easily track down where the issue is. This is in the S2P function, and the S2PI also refers to "Kick System".

Probably an artifact left over from him designing this function for his "Multikick" system. :p
 

Jesus4Lyf

Good Idea™
Reaction score
397
May I be honest?
I don't like that this requires 1.24.

I'd like to use this in my map, but I want my map to work on both 1.23 and 1.24 (for randoms on LAN).

Honest.

And you know, I'm sure its avoidable. I think you only use GetHandleId from 1.24, and only use it to associate things with player colours? You could replace this with a loop... It's only up to 16 colours or whatever, I don't think the efficiency matters... Maybe you could have a flavour for compatability. :)
 
Status
Not open for further replies.
General chit-chat
Help Users
  • No one is chatting at the moment.

      The Helper Discord

      Staff online

      Members online

      Affiliates

      Hive Workshop NUON Dome World Editor Tutorials

      Network Sponsors

      Apex Steel Pipe - Buys and sells Steel Pipe.
      Top