• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

String functions

Level 8
Joined
Aug 4, 2006
Messages
357
Introduction

This is a vJASS library of useful string functions made by me (MaskedPoptart). Since the total length of this post is quite long, let me start out by explaining the most useful feature of these functions. This feature uses the FindIndex, NumOccurances, and RemoveString functions.

Most Useful Feature – Function Testing in Chat

Let's face it: most of us never finish a map. Whether it's being too ambitious, not having enough time, or being stumped by bugs, something always comes up. Wouldn’t it be nice if there was an easy, quick way to test and debug your functions? Well, now there is! With simply one line of code, you can allow a function to be tested through in-game chat messages with whatever parameters you want (as long as your parameters can be converted from a string). This allows you to see the results of each function call immediately after you press the enter key! For example, we can allow ourselves to use the CreateUnit function in-game simply by writing
JASS:
 //! runtextmacro FunctionTesting5("CreateUnit", "player", "S2Player", "integer", "S2RawCode", "real", "S2R", "real", "S2R", "real", "S2R")
Now we can test the CreateUnit function with any player, unit-type id, and coordinates without having to switch back and forth between world editor and warcraft 3, waiting for the map to load each time.

So how exactly can I do it?

  • Create a new trigger window (Ctrl-T) with name: "String", convert it to custom text, and delete the whole contents.
  • Copy all the code in the hidden "String Functions" JASS block below, and paste it into your "String" trigger.
  • Repeat step 1 with name: "Function Testing"
  • Copy all the code in the hidden "FunctionTesting" JASS block below, and paste it into your "Function Testing" trigger.
  • At the bottom, run the text macro that matches the number of parameters your function has. For example, //! runtextmacro FunctionTesting4 for functions with 4 parameters. You will have to input the functionName, variable type of the first parameter (i.e. player), string to type of first parameter (i.e. S2Player), variable type of the second parameter (i.e. real), string to type of second parameter (i.e. S2R), etc. Make sure your function can be accessed from this trigger.
  • Repeat step 5 for all functions you want to test.
  • Once you start up warcraft 3, you should receive a message like "created textmacro for CreateUnit(player,integer,real,real,real)" for each function you textmacro'd.
  • Call your function like so: "CreateUnit( p0, hfoo, 0, 0, 0) ". Make sure you do not put quotes (" ") or apostrophes (' '). If you ran the textmacro correctly, your function should run. If nothing happens, make sure you put calls to BJDebugMsg inside your function.

JASS:
 //made by MaskedPoptart
//! textmacro FunctionTesting0 takes functionName
  scope $functionName$Testing initializer Init
//===========================================================================
    private function Actions takes nothing returns nothing
        call $functionName$()
    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger chat_event_trig = CreateTrigger(  )
        call TriggerRegisterPlayerChatEvent( chat_event_trig, Player(0), "$functionName$()", true )
        call TriggerAddAction( chat_event_trig, function Actions )
        debug call BJDebugMsg("created textmacro for $functionName$()")
    endfunction
endscope
//! endtextmacro

//! textmacro FunctionTesting1 takes functionName, type1, S2type1
scope $functionName$Testing initializer Init
    globals
        private string enteredString
        private integer esLength
        private boolean condition1
        private boolean condition2
        private integer tempInt1
        private $type1$ $type1$Param1
    endglobals
//========================================================================
    private function Conditions takes nothing returns boolean
        set enteredString = GetEventPlayerChatString()
        set condition1 = NumOccurances(enteredString, ",") == 0
        if(not(condition1))then
            return false
        endif
        set condition2 = FindIndex(enteredString, ")") == StringLength(enteredString)-1
        return condition2
    endfunction
//===========================================================================
    private function Actions takes nothing returns nothing
        set enteredString = RemoveString(enteredString, " ")
        set esLength = StringLength(enteredString)
        set tempInt1 = FindIndex(enteredString, "(") + 1
        set $type1$Param1 = $S2type1$(SubString(enteredString, tempInt1, esLength-1))

        call $functionName$($type1$Param1)

    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger chat_event_trig = CreateTrigger(  )
        call TriggerRegisterPlayerChatEvent( chat_event_trig, Player(0), "$functionName$(", false )
        call TriggerAddCondition( chat_event_trig, Condition( function Conditions ) )
        call TriggerAddAction( chat_event_trig, function Actions )
        debug call BJDebugMsg("created textmacro for $functionName$($type1$)")
    endfunction
endscope
//! endtextmacro

//! textmacro FunctionTesting2 takes functionName, type1, S2type1, type2, S2type2
scope $functionName$Testing initializer Init
    globals
        private string enteredString
        private integer esLength
        private boolean condition1
        private boolean condition2
        private integer tempInt1
        private integer tempInt2
        private $type1$ $type1$Param1
        private $type2$ $type2$Param2
    endglobals
//========================================================================
    private function Conditions takes nothing returns boolean
        set enteredString = GetEventPlayerChatString()
        set condition1 = NumOccurances(enteredString, ",") == 1
        if(not(condition1))then
            return false
        endif
        set condition2 = FindIndex(enteredString, ")") == StringLength(enteredString)-1
        return condition2
    endfunction
//===========================================================================
    private function Actions takes nothing returns nothing
        set enteredString = RemoveString(enteredString, " ")
        set esLength = StringLength(enteredString)
        set tempInt1 = FindIndex(enteredString, "(") + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type1$Param1 = $S2type1$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = esLength - 1
        set $type2$Param2 = $S2type2$(SubString(enteredString, tempInt1, tempInt2))

        call $functionName$($type1$Param1, $type2$Param2)

    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger chat_event_trig = CreateTrigger(  )
        call TriggerRegisterPlayerChatEvent( chat_event_trig, Player(0), "$functionName$(", false )
        call TriggerAddCondition( chat_event_trig, Condition( function Conditions ) )
        call TriggerAddAction( chat_event_trig, function Actions )
        debug call BJDebugMsg("created textmacro for $functionName$($type1$,$type2$)")
    endfunction
endscope
//! endtextmacro

//! textmacro FunctionTesting3 takes functionName, type1, S2type1, type2, S2type2, type3, S2type3
scope $functionName$Testing initializer Init
    globals
        private string enteredString
        private integer esLength
        private boolean condition1
        private boolean condition2
        private integer tempInt1
        private integer tempInt2
        private $type1$ $type1$Param1
        private $type2$ $type2$Param2
        private $type3$ $type3$Param3
    endglobals
//========================================================================
    private function Conditions takes nothing returns boolean
        set enteredString = GetEventPlayerChatString()
        set condition1 = NumOccurances(enteredString, ",") == 2
        if(not(condition1))then
            return false
        endif
        set condition2 = FindIndex(enteredString, ")") == StringLength(enteredString)-1
        return condition2
    endfunction
//===========================================================================
    private function Actions takes nothing returns nothing
        set enteredString = RemoveString(enteredString, " ")
        set esLength = StringLength(enteredString)
        set tempInt1 = FindIndex(enteredString, "(") + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type1$Param1 = $S2type1$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type2$Param2 = $S2type2$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = esLength - 1
        set $type3$Param3 = $S2type3$(SubString(enteredString, tempInt1, tempInt2))

        call $functionName$($type1$Param1, $type2$Param2, $type3$Param3)

    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger chat_event_trig = CreateTrigger(  )
        call TriggerRegisterPlayerChatEvent( chat_event_trig, Player(0), "$functionName$(", false )
        call TriggerAddCondition( chat_event_trig, Condition( function Conditions ) )
        call TriggerAddAction( chat_event_trig, function Actions )
        debug call BJDebugMsg("created textmacro for $functionName$($type1$,$type2$,$type3$)")
    endfunction
endscope
//! endtextmacro

//! textmacro FunctionTesting4 takes functionName, type1, S2type1, type2, S2type2, type3, S2type3, type4, S2type4
scope $functionName$Testing initializer Init
    globals
        private string enteredString
        private integer esLength
        private boolean condition1
        private boolean condition2
        private integer tempInt1
        private integer tempInt2
        private $type1$ $type1$Param1
        private $type2$ $type2$Param2
        private $type3$ $type3$Param3
        private $type4$ $type4$Param4
    endglobals
//========================================================================
    private function Conditions takes nothing returns boolean
        set enteredString = GetEventPlayerChatString()
        set condition1 = NumOccurances(enteredString, ",") == 3
        if(not(condition1))then
            return false
        endif
        set condition2 = FindIndex(enteredString, ")") == StringLength(enteredString)-1
        return condition2
    endfunction
//===========================================================================
    private function Actions takes nothing returns nothing
        set enteredString = RemoveString(enteredString, " ")
        set esLength = StringLength(enteredString)
        set tempInt1 = FindIndex(enteredString, "(") + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type1$Param1 = $S2type1$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type2$Param2 = $S2type2$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type3$Param3 = $S2type3$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = esLength - 1 
        set $type4$Param4 = $S2type4$(SubString(enteredString, tempInt1, tempInt2))

        call $functionName$($type1$Param1, $type2$Param2, $type3$Param3, $type4$Param4)

    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger chat_event_trig = CreateTrigger(  )
        call TriggerRegisterPlayerChatEvent( chat_event_trig, Player(0), "$functionName$(", false )
        call TriggerAddCondition( chat_event_trig, Condition( function Conditions ) )
        call TriggerAddAction( chat_event_trig, function Actions )
        debug call BJDebugMsg("created textmacro for $functionName$($type1$,$type2$,$type3$,$type4$)")
    endfunction
endscope
//! endtextmacro

//! textmacro FunctionTesting5 takes functionName, type1, S2type1, type2, S2type2, type3, S2type3, type4, S2type4, type5, S2type5
scope $functionName$Testing initializer Init
    globals
        private string enteredString
        private integer esLength
        private boolean condition1
        private boolean condition2
        private integer tempInt1
        private integer tempInt2
        private $type1$ $type1$Param1
        private $type2$ $type2$Param2
        private $type3$ $type3$Param3
        private $type4$ $type4$Param4
        private $type5$ $type5$Param5
    endglobals
//========================================================================
    private function Conditions takes nothing returns boolean
        set enteredString = GetEventPlayerChatString()
        set condition1 = NumOccurances(enteredString, ",") == 4
        if(not(condition1))then
            return false
        endif
        set condition2 = FindIndex(enteredString, ")") == StringLength(enteredString)-1
        return condition2
    endfunction
//===========================================================================
    private function Actions takes nothing returns nothing
        set enteredString = RemoveString(enteredString, " ")
        set esLength = StringLength(enteredString)
        set tempInt1 = FindIndex(enteredString, "(") + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type1$Param1 = $S2type1$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type2$Param2 = $S2type2$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type3$Param3 = $S2type3$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = FindIndexFrom(enteredString, ",", tempInt1)
        set $type4$Param4 = $S2type4$(SubString(enteredString, tempInt1, tempInt2))
        set tempInt1 = tempInt2 + 1
        set tempInt2 = esLength - 1
        set $type5$Param5 = $S2type5$(SubString(enteredString, tempInt1, tempInt2))

        call $functionName$($type1$Param1, $type2$Param2, $type3$Param3, $type4$Param4, $type5$Param5)

    endfunction
//===========================================================================
    private function Init takes nothing returns nothing
        local trigger chat_event_trig = CreateTrigger(  )
        call TriggerRegisterPlayerChatEvent( chat_event_trig, Player(0), "$functionName$(", false )
        call TriggerAddCondition( chat_event_trig, Condition( function Conditions ) )
        call TriggerAddAction( chat_event_trig, function Actions )
        debug call BJDebugMsg("created textmacro for $functionName$($type1$,$type2$,$type3$,$type4$,$type5$)")
    endfunction
endscope
  //! endtextmacro
   
  //--------------------------------------------------------------------
  //------------------{  NO PARAMETER FUNCTIONS  }----------------------
  //--------------------------------------------------------------------
  //  runtextmacro FunctionTesting0( "functionName" )
   
   
  //--------------------------------------------------------------------
  //------------------{  1 PARAMETER FUNCTIONS  }-----------------------
  //--------------------------------------------------------------------
  //  runtextmacro FunctionTesting1( "functionName", "type1", "S2type1" )
   
   
  //--------------------------------------------------------------------
  //------------------{  2 PARAMETER FUNCTIONS  }-----------------------
  //--------------------------------------------------------------------
  //  runtextmacro FunctionTesting2( "functionName", "type1", "S2type1", "type2", "S2type2")
   
   
  //--------------------------------------------------------------------
  //------------------{  3 PARAMETER FUNCTIONS  }-----------------------
  //--------------------------------------------------------------------
  //  runtextmacro FunctionTesting3( "functionName", "type1", "S2type1", "type2", "S2type2", "type3", "S2type3")
   
   
  //--------------------------------------------------------------------
  //------------------{  4 PARAMETER FUNCTIONS  }-----------------------
  //--------------------------------------------------------------------
  //  runtextmacro FunctionTesting4( "functionName", "type1", "S2type1", "type2", "S2type2", "type3", "S2type3", "type4", "S2type4")
   
   
  //--------------------------------------------------------------------
  //------------------{  5 PARAMETER FUNCTIONS  }-----------------------
  //--------------------------------------------------------------------
  //  runtextmacro FunctionTesting5( "functionName", "type1", "S2type1", "type2", "S2type2", "type3", "S2type3", "type4", "S2type4", "type5", "S2type5")
The String Library

Functions are separated into four categories: Important, Color, Chat Events, and Debugging.

  • Important functions are used within the library, so they need to be at the top.
  • Color functions are anything having to do with creating/removing color codes.
  • Chat Event functions help with handling chat events, or convert strings to other things.
  • Debugging functions convert things to strings, so you can put them in BJDebugMsg calls.

JASS:
//--------------------IMPORTANT FUNCTIONS------------------------
   
function FindIndexFrom takes string mainString, string stringToFind, integer startingIndex returns integer
//returns the first (leftmost) index of "stringToFind" in "mainString"
// after "startingIndex." (Starts looking at starting index) 
//returns -1 if "stringToFind" is not found
//example:
    local string fatty = "To be or not to be"
    local string shorty = "be"
    local integer index = FindIndexFrom(fatty, shorty, 4)
    call BJDebugMsg(index)   //16
   
function FindIndex takes string mainString, string stringToFind returns integer
//returns the first (leftmost) index of "stringToFind" in "mainString"
//returns -1 if "stringToFind" is not found


function FindLastIndexFrom takes string mainString, string stringToFind, integer startingIndex returns integer
//returns the last (rightmost) index of "stringToFind" in "mainString" 
// before "startingIndex." (Looks backwards from startingIndex)
//returns -1 if "stringToFind" is not found
//example:
    local string big = "Am I a hot bot, or not?"
    local string small = "ot"
    local integer index = FindLastIndexFrom(big, small, 19)
    call BJDebugMsg(index)   //12
   
function FindLastIndex takes string mainString, string stringToFind returns integer
//returns the last (rightmost) index of "stringToFind" in "mainString" 
//returns -1 if "stringToFind" is not found

   
//-----------------------COLOR FUNCTIONS ------------------------
   
function PlayerColor2ColorString takes playercolor pc returns string
//takes a playercolor handle (does anyone actually use those?) and 
// returns the corresponding color string (same form as above)

function GetPlayerColorString takes player p returns string
//takes a player and returns the color string associated with him/her
//in the form of "|cffRRGGBB"
   
function GetPlayerNameColored takes player p returns string
//returns the player’s name with appropriate color
//example:
    GetPlayerNameColored(Player(0))  //returns "|cffff0303World Edit|r"
   
function RemoveColorCode takes string mainString returns string
//takes in a string encased in a color code and returns that string
// without its color code
//example:
    RemoveColorCode("|cffea9b33HELLO|r")  //returns "HELLO"
   
function IBase2S takes integer base10Num, integer newBase returns string
//converts an integer (base 10) and a base into a string of numbers in
// that base. Returns the string.
//does not support bases over 16. does not support negative numbers.
//example: 
    IBase2S(134, 2)  //returns "10000110". (converts 134 to a base 2 (binary) string)
    IBase2S(134, 16)  //returns "86". (converts 134 to a base 16 (hexadecimal) string)
    IBase2S(212, 16)  //returns "d4". (converts 212 to a base 16 (hexadecimal) string)
   
function SBase2I takes string oldBaseString, integer oldBase returns integer 
//does the opposite of the previous function.
//does not support bases over 16. does not support negative numbers.
//example: 
    SBase2I("10000110", 2)  //returns 134.  (converts "10000110", a binary string, to a decimal number)
    SBase2I("86", 16)  //returns 134.  (converts "86", a hexadecimal string, to a decimal number)
    SBase2I("e3", 16) //returns 227.  (converts "e3", a hexadecimal string, to a decimal number)
   
function ConvertRGBToColorString takes integer red, integer green, integer blue returns string
//creates a color code prefix using the three integers
//0 is darkest, 255 is brightest for each color
//example:
    ConvertRBGToColorString(200,0,200)   //returns "|cffc800c8"
   
function GetColoredString takes string str, integer r, integer g, integer b returns string
//creates a color code prefix (using previous function) and returns
// str with the full color code, including ending
//example:
    GetColoredString("wee", 255, 192, 0)  //returns "|cffffc000wee|r"
   
   
//----------------------CHAT EVENT FUNCTIONS------------------------------
   
function RemoveString takes string mainString, string toRemove returns string
//removes all occurances of toRemove from mainString
//returns the new string
//example:
    local string silly = "aaaaheaaaalaloaa"
    set silly = RemoveString(silly, "a")
    call BJDebugMsg(silly)   //"hello"

function NumOccurances takes string mainString, string stringToFind returns integer
//returns the number of times stringToFind is found in mainString
//example:
    local string str = "wefejwejdsfowe fj"
    local string str2 = "we"
    local integer num = NumOccurances(str, str2)
    call BJDebugMsg(num)   //3
 
 
function S2B takes string word returns Boolean
//converts "true" into true and "false" into false
//returns false if the string is not valid
   
function S2Player takes string word returns player
//takes a string in the form of "pX" where X is an integer
// representing a player id
//returns Player(X)
//example:
    S2Player("p5")    //returns Player(5)
   
function S2RawCode takes string str returns integer
//takes a string and converts it into a rawcode integer
//A rawcode is any integer that you normally put ' ' around,
// such as a unit-type id or an ability id.
//example:
    S2RawCode("hfoo")    //returns 'hfoo' (unit id of Footman)
    S2RawCode("Aply")    //returns 'Aply' (ability id of Polymorph) 
    S2RawCode("pghe")    //returns 'pghe' (item id of Potion of Greater Healing)
    S2RawCode("@$$#")  //returns '@$$#' (custom rawcode)
   
//-----------------------DEBUG FUNCTIONS-------------------------
  
function B2S takes boolean bool returns string
//returns "true" or "false"
//example usage:
    local boolean b = IsPlayerAlly(Player(0), Player(1))
    call BJDebugMsg("Player 0 allied with Player 1? "+B2S(b))
   
function Player2S takes player p returns string
//takes a player and returns a string in the form of
//"Player(X)" where X is the player id.
//example usage: 
    call BJDebugMsg("Triggering Player is: "+Player2S(GetTriggerPlayer()))

function Unit2S takes unit u returns string
//returns the unit type name _ the unit's unique number.
//uses GetHandleId() from beta patch 1.23b (available in Westfall server)
//so it only works in 1.23b+. Replace GetHandleId with the H2I function
// if you use 1.23 or lower.
//example usage:
    local unit yourMom = CreateUnit(Player(0), 'hpea', 0, 0, 0)
    call BJDebugMsg(Unit2S(yourMom))    //Peasant_92
   
function RawCode2S takes string str returns integer
//takes a rawcode integer and converts it into a string
//A rawcode is any integer that you normally put ' ' around,
// such as an item-type id or a buff id.
//example:
    RawCode2S('hfoo')    //returns "hfoo" (human unit id of Footman)
    RawCode2S('Aply')    //returns "Aply" (ability id of Polymorph) 
    RawCode2S('pghe')    //returns "pghe" (item id of Potion of Greater Healing)
    RawCode2S(1969709426)    //returns "ugar" (undead unit id of Gargoyle)
//WARNING: do not input any integers that do not correspond to raw codes
// or the function will not work properly.
JASS:
library String initializer Init
//String functions v1.04
//made by MaskedPoptart
//--------------------IMPORTANT FUNCTIONS------------------------
  
    function FindIndexFrom takes string mainString, string stringToFind, integer startingIndex returns integer
        local integer msLength = StringLength(mainString)
        local integer sfLength = StringLength(stringToFind)
        local integer i = startingIndex
        if(sfLength > msLength or i < 0)then
            return -1
        endif
        loop
            exitwhen i > msLength - sfLength
            if(SubString(mainString, i, i+sfLength) == stringToFind)then
                return i
            endif
            set i = i + 1
        endloop
        return -1
    endfunction

    function FindIndex takes string mainString, string stringToFind returns integer
        return FindIndexFrom(mainString, stringToFind, 0)
    endfunction
  
    function FindLastIndexFrom takes string mainString, string stringToFind, integer startingIndex returns integer
        local integer msLength = StringLength(mainString)
        local integer sfLength = StringLength(stringToFind)
        local integer i = msLength-sfLength
        if(startingIndex < i)then
            set i = startingIndex
        endif
        if(sfLength > msLength)then
            return -1
        endif
        loop
            exitwhen i < 0
            if(SubString(mainString, i, i+sfLength) == stringToFind)then
                return i
            endif
            set i = i - 1
        endloop
        return -1
    endfunction

    function FindLastIndex takes string mainString, string stringToFind returns integer
        return FindLastIndexFrom(mainString, stringToFind, 2147483647)
    endfunction
  
//-----------------------COLOR FUNCTIONS ------------------------
    globals
        private playercolor array PLAYER_COLORS
        private string array PLAYER_COLOR_STRINGS
        private constant string HEX_CHARS = "0123456789abcdef"
        private string COLOR_ENDING = "|r"
    endglobals

    private function Init takes nothing returns nothing
        local integer i = 0
        loop
            exitwhen i >= 12
            set PLAYER_COLORS[i] = ConvertPlayerColor(i)
            set i = i + 1
        endloop
        set PLAYER_COLOR_STRINGS[0] = "|cffff0303"
        set PLAYER_COLOR_STRINGS[1] = "|cff0042ff"
        set PLAYER_COLOR_STRINGS[2] = "|cff1ce6b9"
        set PLAYER_COLOR_STRINGS[3] = "|cff540081"
        set PLAYER_COLOR_STRINGS[4] = "|cfffffc01"
        set PLAYER_COLOR_STRINGS[5] = "|cfffe8a0e"
        set PLAYER_COLOR_STRINGS[6] = "|cff20c000"
        set PLAYER_COLOR_STRINGS[7] = "|cffe55bb0"
        set PLAYER_COLOR_STRINGS[8] = "|cff959697"
        set PLAYER_COLOR_STRINGS[9] = "|cff7ebff1"
        set PLAYER_COLOR_STRINGS[10] = "|cff106246"
        set PLAYER_COLOR_STRINGS[11] = "|cff4e2a04"
        set PLAYER_COLOR_STRINGS[12] = "|cff272727"
        set PLAYER_COLOR_STRINGS[13] = "|cff272727"
        set PLAYER_COLOR_STRINGS[14] = "|cff272727"
    endfunction

    function PlayerColor2ColorString takes playercolor pc returns string
        local integer i = 0
        loop
            exitwhen i >= 12
            if(PLAYER_COLORS[i] == pc)then
                return PLAYER_COLOR_STRINGS[i]
            endif
            set i = i + 1
        endloop
        return PLAYER_COLOR_STRINGS[12]
    endfunction

    function GetPlayerColorString takes player p returns string
        return PlayerColor2ColorString(GetPlayerColor(p))
    endfunction

    function GetPlayerNameColored takes player p returns string
        return GetPlayerColorString(p)+GetPlayerName(p)+COLOR_ENDING
    endfunction


    //please use responsibly
    function RemoveColorCode takes string mainString returns string
        local integer msLength = StringLength(mainString)
        if(msLength<12)then
            return mainString
        endif
        return SubString(mainString, 10, msLength-2)
    endfunction

    function IBase2S takes integer base10Num, integer newBase returns string
        local integer placeNum //number at current place
        local string newBaseString = ""
        loop
            exitwhen base10Num == 0
            set placeNum = ModuloInteger(base10Num, newBase)
            set newBaseString = SubString(HEX_CHARS, placeNum, placeNum+1) + newBaseString
            set base10Num = base10Num / newBase
        endloop
        if(newBaseString == "")then
            return "0"
        endif
        return newBaseString
    endfunction

    function SBase2I takes string oldBaseString, integer oldBase returns integer
        local integer base10Num = 0
        local integer placeNum //number at current place
        local integer placeIndex = 0 //index of current place. 0 = one's place, etc.
        local integer i = StringLength(oldBaseString)-1
        loop
            exitwhen i < 0
            set placeNum = FindLastIndexFrom(HEX_CHARS, SubString(oldBaseString, i, i+1), oldBase-1)
            set base10Num = base10Num + placeNum*R2I(Pow(oldBase, placeIndex))
            set placeIndex = placeIndex + 1
            set i = i - 1
        endloop
        return base10Num
    endfunction

    function ConvertRGBToColorString takes integer red, integer green, integer blue returns string
        local string RR
        local string GG
        local string BB
        if(red>255)then
            set red = 255
        endif
        if(green>255)then
            set green = 255
        endif
        if(blue>255)then
            set blue = 255
        endif
        set RR = IBase2S(red, 16)
        set GG = IBase2S(green, 16)
        set BB = IBase2S(blue, 16)
        if(StringLength(RR)<2)then
            set RR = "0"+RR
        endif
        if(StringLength(GG)<2)then
            set GG = "0"+GG
        endif
        if(StringLength(BB)<2)then
            set BB = "0"+BB
        endif
        return "|cff"+RR+GG+BB
    endfunction

    function GetColoredString takes string str, integer r, integer g, integer b returns string
        return ConvertRGBToColorString(r,g,b)+str+COLOR_ENDING
    endfunction


//----------------------CHAT EVENT FUNCTIONS------------------------------

    function RemoveString takes string mainString, string toRemove returns string
        local integer i = 0
        local string currentString
        local integer msLength = StringLength(mainString)
        local integer trLength = StringLength(toRemove)
        if(trLength > msLength)then
            return mainString
        endif
        loop
            exitwhen i+trLength > msLength
            set currentString = SubString(mainString, i, i+trLength)
            if(currentString == toRemove)then
                if(i+trLength <= msLength)then
                    set mainString = SubString(mainString, 0, i)+SubString(mainString, i+trLength, msLength)
                else
                    set mainString = SubString(mainString, 0, i)
                endif
                set i = i - trLength
            endif
            set i = i + 1
        endloop
        return mainString
    endfunction

    function NumOccurances takes string mainString, string stringToFind returns integer
        local integer count = 0
        local integer i = 0
        local integer msLength = StringLength(mainString)
        local integer sfLength = StringLength(stringToFind)
        loop
            exitwhen (i+sfLength) > msLength
            if(SubString(mainString, i, i+sfLength) == stringToFind)then
                set count = count + 1
            endif
            set i = i + 1
        endloop
        return count
    endfunction

    function S2B takes string word returns boolean
        if(word == "true")then
            return true
        endif
        return false
    endfunction 

    function S2Player takes string word returns player
        return Player(S2I(SubString(word, 1, StringLength(word))))
    endfunction
  
    globals
        private integer MIN_RAW_CODE = ' ' //32
        private string RAW_CHARS = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~"
    endglobals
    function S2RawCode takes string str returns integer
        local integer rawCode = 0
        local integer placeNum //number at current place
        local integer placeIndex = 0 //index of current place. 0 = one's place, etc.
        local integer i = StringLength(str)-1
        loop
            exitwhen i < 0
            set placeNum = MIN_RAW_CODE + FindIndex(RAW_CHARS, SubString(str, i, i+1))
            //the char at index 0 of RAW_CHARS has ASCII value 32, so we need to offset each FindIndex by 32.
            set rawCode = rawCode + placeNum*R2I(Pow(256., placeIndex))
            set placeIndex = placeIndex + 1
            set i = i - 1
        endloop
        return rawCode
    endfunction

//-----------------------DEBUG FUNCTIONS-------------------------

    function B2S takes boolean bool returns string
        if(bool)then
            return "true"
        endif
        return "false"
    endfunction

    function Player2S takes player p returns string
        return "Player("+I2S(GetPlayerId(p))+")"
    endfunction

    function Unit2S takes unit u returns string
        return GetUnitName(u)+ "_"+I2S(GetHandleId(u)-0x100000)
    endfunction

    function RawCode2S takes integer rawCode returns string
        local integer placeNum //number at current place
        local string str = ""
        if(rawCode < MIN_RAW_CODE)then
            return str
        endif
        loop
            exitwhen rawCode == 0
            set placeNum = ModuloInteger(rawCode, 256) - MIN_RAW_CODE
            set str = SubString(RAW_CHARS, placeNum, placeNum+1) + str
            set rawCode = rawCode / 256
        endloop
        return str
    endfunction
endlibrary

Dates are MM/DD/YY. Times are GMT-10:00

1.00 (06/24/09, 2:16am)

  • initial release
1.01 (06/24/09, 4:43pm)

  • added 8 color-related functions
  • added Player2S and S2Player
  • updated documentation
  • added example usage of chat event functions (11:23pm)
1.02 (06/25/09, 4:45pm)

  • added FindLastIndex
  • changed names (I2HexString/HexString2I)
  • improved S2Player
  • improved Unit2S
  • updated documentation, started changelog
1.03 (06/27/09, 5:00pm)

  • made kickass textmacros for testing functions through chat
  • added FindIndexFrom, FindLastIndexFrom
  • changed I2HexString/HexString2I to IBase2S, SBase2I
  • added S2Id (also kickass), and Id2S
  • moved Find functions to top of library, so they could be used by other functions
  • reorganized original post
  • a few other minor changes
1.03b (06/30/09, 2:55pm)

  • changed names (S2RawCode, RawCode2S)
  • a few minor changes (SBase2I, S2RawCode, RawCode2S)
1.03c (07/01/09, 1:45am)

  • improved S2RawCode, RawCode2S.
  • they now work with any sequence of standard ASCII chars.
1.03d (07/23/09, 10:31pm)

  • fixed a bug with ConvertRGBToColorString
  • IBase2S now returns "0" instead of ""
1.04 (11/27/09, 9:55pm)

  • Changed the name of "ConvertPlayerToColorString" to "GetPlayerColorString"
  • GetPlayerColorString and GetPlayerNameColored now work even if players do
    not have the default colors (i.e. if one team is all red, all their color strings will be red).

 
Last edited:
Level 31
Joined
Jul 10, 2007
Messages
6,306
yea... part of the MATH utility I'm working on has a convertBase function... you'll save me some work : P.

Actually, if you do convert base right, you wouldn't be using strings as they are rather slow... you'd be using complicated Number objects >: O... so, don't add convert base unless you want to continue the nifty trend of slow base conversion : D.

The other 2 sound fine tho ^_-.


btw, I'm not agreeing with malte on the remove string or w/e. The yea agrees to the base conversion : D
 
Last edited:
Level 11
Joined
Feb 22, 2006
Messages
752
JASS:
function Unit2S takes unit u returns string
        return GetUnitName(u)+I2S(GetHandleId(u)-0x100000)
endfunction

maybe put a space between the name and the id, so we don't see ugly stuff like this:

"Footman12030495"
"Grunt95857568"

JASS:
function S2Player takes string word returns player
        local integer tempInt1 = FindIndex(word, "(")
        local integer tempInt2 = FindIndex(word, ")")
        local integer playerNum
        if(tempInt1 == -1 or tempInt2 == -1)then
            return null
        endif
        set playerNum = S2I(SubString(word, tempInt1+1, tempInt2))
        return Player(playerNum)
endfunction

I really don't see the point of this. Nobody ever types in "Player(0)" or "Player(5)" or w/e in-game. Even if it was for debug purposes, I wouldn't type that in; I'd go with just plain numerals or maybe "p1", "p2", etc. so I don't sit there typing unnecessarily long, awkward strings just to debug my map.

JASS:
function Convert255ToFF takes integer number returns string
function ConvertFFTo255 takes string str returns integer

Please come up with better identifiers for those functions. I2HexString/HexString2I would be better.
 
Level 8
Joined
Aug 4, 2006
Messages
357
aznricepuff said:
maybe put a space between the name and the id
done. (I used "_")
aznricepuff said:
Even if it was for debug purposes, I wouldn't type that in; I'd go with just plain numerals or maybe "p1", "p2", etc. so I don't sit there typing unnecessarily long, awkward strings just to debug my map.
done. S2Player now takes strings in the form of p0, p2, p11, etc.
aznricepuff said:
I2HexString/HexString2I would be better.
done.

updated a bunch of stuff on the original post, and added FindLastIndex.
 
Level 8
Joined
Aug 4, 2006
Messages
357
well you sure are a helpful son of a *****. I understood perfectly what he said, but I still think S2Anything functions serve a useful purpose in testing functions through chat events.
This is the first resource I am posting. It really doesn't matter to me how "pointless" you think it is. I am not posting this for people who would rather make their own string functions. This is more for people who do not know how to, or who don't have the time to, make functions such as these.
You know what? Maybe next time I make something that I think people will find useful, I will just keep it to myself. :p
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
Malte is always like that. Personally, I find your stuff nice for extremely fast tests in a testing state of a map : ).

Currently, for when testing my map, I just use the MFN user area and just write quick little quirks in there, but yea : D.

On the other note, the programming you do is pretty bad. The styling follows the terrible styling of Blizzard JASS functions and you have some extra things in there you don't need... you should do a little research on proper programming styling before you attempt to tackle some code writing. Of course, just about everyone in the wc3 community programs terribly in the way of styling.

Some other mistakes you made that are only made by amateurs include:
JASS:
      function B2S takes boolean bool returns string
          if(bool)then
              return "true"
          else
              return "false"
          endif
      endfunction

When it should be
JASS:
      function B2S takes boolean bool returns string
          if(bool)then
              return "true"
          endif
          return "false"
      endfunction

Some more stuff in general
JASS:
function PlayerColor2ColorString takes playercolor pc returns string

should be
JASS:
function playerColor2ColorString takes playercolor pc returns string

Follow camelcase style. First letter in a function or method is always lowercase where the rest are uppercase.

JASS:
private constant string hex = "0123456789abcdef"

Should be

JASS:
private constant string HEX = "0123456789abcdef"

constant variables are always all caps. If you have multiple words in a variable or w/e that's a constant, then use underscores like HEX_COLOR

Any object or w/e, like structs and interfaces, are always first letter capitalized following camelcase like this:
StructHello
vrs
structHello

when creating an instance of that struct, you normally declare it like this -.-

StructHello structHello


In short, just try and follow simple styling rules.. Lemme grab a whole guide to styling code for you : ). Even though this little guide says this is for Java, it really applies to any language. It's specific to java for things like classes where other languages might not have classes or w/e, but this style is used in all languages =).

http://java.sun.com/docs/codeconv/html/CodeConvTOC.doc.html

Keep in mind that a lot of that is specific to java, some of it is specific to non-JASS languages, but yea....

Also, some there are some other conventions more specific to JASS, but those are conventions that I kind of started up myself =). I'm actually writing on proper JASS design in a book called The Guide to MFN : D, but let's go over some of the basic rules that you didn't follow ^_-.


1. To ensure that your system, utility, library (compendium), or framework does not collide with other things within the map, it is always a good idea to name it as an acronym of its full name + the first letter of your first name or nickname.

2. To ensure that no code within what you have designed collides with anything in the map, keep all of your code in a library of your system name (acronym + first letter) in a public state if it's meant to be accessible or in a private state if it isn't. This means that people will be able to read code easier (STRM- or strings by maskedpoptart) as they will know exactly where a function comes from and who the author was, and they will be able to access code within the system more easily (call StringUtilities_hello() vrs call STRM_hello()).

3. Be sure to keep all of your system code in one area so that people don't have to browse through it for any user areas you might have defined for custom settings. This means if you have globals at the top that the users are meant to mess with, these globals should be declared in your system code area but set in a function within another area. This will ensure more proper organization of your code.

4. Be sure to make it as easy as possible for anything requiring your product to require it, meaning that there should be a library below your product that requires everything within it.

Example-
library BLOOM
endlibrary

library requiresBLOOM requires BLOOMCode, BLOOMCheese, BLOOMFlowers
endlibrary

-A system using BLOOM-
library MyLibrary requires requiresBLOOM
endlibrary

These are just some guidelines to proper design in vJASS =), and I believe that if you follow these guidelines, your string utility will be easier to use and easier to learn. It will also make it so that whenever there is code using it, anyone reading that code will know whenever that code is accessing your system.
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
Some other mistakes you made that are only made by amateurs include:
JASS:
      function B2S takes boolean bool returns string
          if(bool)then
              return "true"
          else
              return "false"
          endif
      endfunction
That's not a mistake... Nor is probably any faster. The only thing you can say is that it's a coding style, which doesn't matter.


Follow camelcase style. First letter in a function or method is always lowercase where the rest are uppercase.

No, fif you're going to follow the jass conventions, functions start with an uppercase letter. Only methods start with lowercase letters.

Any object or w/e, like structs and interfaces, are always first letter capitalized following camelcase like this:
StructHello
vrs
structHello
That entirely depends on your own style. Again, if you follow plain jass rules, lowercase would be the most logical choice.

That's java. If you plan on using jass, you follow the jass rules, not the java rules. This means writing functions with capital letters and starting methods with lowercase letter. etc.


1. To ensure that your system, utility, library (compendium), or framework does not collide with other things within the map, it is always a good idea to name it as an acronym of its full name + the first letter of your first name or nickname.
I'm sorry, but I personally find that poop. I'd rather have to fix colliding names than ugly library names. Besides, if you use a properly chosen name for your library, there shouldn't be any collosions in the first place unless your library's purpose also collides, in which case one of the libraries is unnecessary.
 
Level 31
Joined
Jul 10, 2007
Messages
6,306
No, fif you're going to follow the jass conventions, functions start with an uppercase letter. Only methods start with lowercase letters.

Entirely untrue. JASS follows a standard programming convention. Actually, since it was written in C++, it probably follows the same convention as C++ does which is pretty much the same as Java, C, C#, and etc. Only JASS functions that are accessible normally to map makers are uppercase as there are no objects and it allows people to transition more easily into JASS (you capitalize the first letter of a sentence, so why not the first letter of a function). If you look at functions that aren't normally accessible, they are lowercase. JASS wasn't made to be a professional scripting language, so ease of use took precedence over proper styling on all public functions.

That entirely depends on your own style. Again, if you follow plain jass rules, lowercase would be the most logical choice.

own style- good god I hope not (quote from someone when I read out your sentence... I found it funny so I put it in).

Also,
jass rules, lowercase would be the most logical choice.

Where in JASS are there structs? Structs are not variables, they are objects. Considering JASS does follow standard conventions, do you think that structs would be lowercase or uppercase? Standard conventions are uppercase.

I'm sorry, but I personally find that poop. I'd rather have to fix colliding names than ugly library names. Besides, if you use a properly chosen name for your library, there shouldn't be any collisions in the first place unless your library's purpose also collides, in which case one of the libraries is unnecessary.

Here you are right, but like I said in the original post, that was one of my own little conventions : P. Would you rather type Hello_Little_Kitty_Red_Green_Blue_Silver_Edition_addTwo() or HKRGBSH_addTwo()? I'd rather type HKRGBSH_addTwo(), so this is really opinion based until the community takes some sort of stand on this. Normal conventions just state start with an uppercase, otherwise name them w/e the heck you want, lol. It was a way to stop collision and to make things within the system or w/e easy to access without typing out a huge line of code like
call pneuomoultramicroscopicsilicovolcanoconiosisSuperSystemByMe_ini()

By the way, it isn't in a standard style because other languages can use scopes. Because vJASS can't, I had the idea of acronyms ;p.

I personally wouldn't even use a system if you had to access it through such a huge line of code.

Final Notes
JASS follows standard coding conventions except for functions normally accessible to map makers. Only reason functions (ones accessible) were capitalized was because they didn't have objects. All variables follow common coding practices. All native types follow common coding practices. If they had structs or classes, they too would follow common naming practices and functions wouldn't be capp'd. If you notice, functions that aren't accessed by map makers normally are not capped and follow standard coding conventions (main and config to name a few). Actually, the if statements are kind of bad though : P.


The naming convention deal isn't a big issue, but it does make programming easier to read.

Also,
That's not a mistake... Nor is probably any faster. The only thing you can say is that it's a coding style, which doesn't matter.

Keyword: probably, and it saves you a line : P.

By the way-
That's java. If you plan on using jass, you follow the jass rules, not the java rules. This means writing functions with capital letters and starting methods with lowercase letter. etc.

untrue... the things Java set forth are pretty much used across most programming languages by most programmers. I say most because there are programming languages out there that really insist on there own style (not many widely known, either that or they have features that Java etc don't have), and there are many noob programmers out there who don't follow common programming styles (if they ever applied for a job, they'd lose maybe $20,000 to $100,000 a year from the interview just because they don't capitalize something right, I kid you not here). I'm not saying I'm a pro programmer, far from it (there are LOADS* of other styles that I don't know about... as you see, the thing I linked was pretty big), but eh : ).

Actually, I guess I'm referring to camel case style, which is used by Java. I targeted Java because it had a lot of stuff in there that was used across a variety of languages ; ).

Oh, and apparently I made a mistake in the styling of MFN macros ><. Treated them like functions/methods, but macros are supposed to be all uppercase o_O... gotta fix that.


And I suppose that the proper styling for JASS would be a combination of these-
http://geosoft.no/development/cppstyle.html#General (C++)
http://en.wikibooks.org/wiki/Visual_Basic/Coding_Standards#Variable_Names (Visual Basic)

a very weird combination... visual basic syntax warped into C++ declarations or w/e...

But I'm guessing it is really pure C++ and that the visual basic stuff was only used so that beginners could more easily understand programming (set for setting a variable, call for calling a function, function for starting and endfunction for ending, etc). This idea was actually probably similar to the idea that spawned uppercase first letter of a function. So I suppose the real styling is just C++ =).
 
Level 21
Joined
Aug 21, 2005
Messages
3,699
If you look at functions that aren't normally accessible, they are lowercase. JASS wasn't made to be a professional scripting language, so ease of use took precedence over proper styling on all public functions.

such as? There are no "private" native functions, since scope visibility qualifiers are a vJass feature. And I've never really seen anyone write a function starting with lowercase letters.

Where in JASS are there structs? Structs are not variables, they are objects. Considering JASS does follow standard conventions, do you think that structs would be lowercase or uppercase? Standard conventions are uppercase.
What's the difference between a variable and an object? What's the difference between a struct and a type? It's not because the "type" keyword is reserved for native types that structs should not follow those conventions.
A struct and a type, there's no real difference between them. At least if you can see past the implementation of structs as arrayed variables. It's not because a "unit" is a native type, that it's a primitive type, and there should theoretically be no difference between native defined composed types and user defined composed types.

JASS follows standard coding conventions except for functions normally accessible to map makers.

There's no such thing as "standard coding conventions". Even though many languages tend to follow the same rules, each language has their own conventions and even worse, organisations come up with their own coding conventions for languages. There are many languages that capitalize each word of a function, there are even languages that capitalize methods.
If vJass would be c++, ok. But it's not. So you better follow the conventions that were already set.

I myself don't follow the standard coding conventions either. I do write struct types with capital letters, and I do write my variables entirely lowercase. But if you're so interested in "standard coding conventions" you should use blizzard's coding conventions, which is:

- Every word in a function starts with a capital letter
- Any type is written in lowercase. Structs are types too. Object oriented types, not natively implemented, but still types. The implementation shouldn't influence the coding conventions.
- Every word in a variable starts with a capital letter, except for the first word (e.g. startLoc)
- (add-on) methods follow the previous rule
etc.

I have gotten used to my own style. But if you're to define "official" coding conventions, you better stick to blizzard's coding conventions as described above, and then extend those with vJass features. For simplicity's sake, if a function is written with capital letters on each word, don't make an exception for private functions.
 
Level 8
Joined
Aug 4, 2006
Messages
357
Hey guys. Updated the original post with a bunch of cool stuff, including: textmacros that allow real time testing of a function with only one line of code; IBase2S function, SBase2I function; Id2S function, S2Id function; FindIndexFrom function, FindLastIndexFrom function.

Also, thanks to Eleandor and Nestharus for clogging up the thread with irrelevant info ;D. By the way, I usually capitalize functions, make methods lower case, make constants all caps, and make instances lower case. I just forgot to make hex all caps (now it's changed). I also fixed the B2S function... don't know how I missed that... the S2B one was fine.
 
Level 8
Joined
Aug 4, 2006
Messages
357
Could one of the JASS moderators please give me some feedback on the new version and tell me if there is anything I can do to get this approved? I have time to fix things today and tomorrow, but I will be gone on a trip starting Thursday. I would like to be done with this library by then.

Thank you for your patience and understanding.
 
Level 11
Joined
Feb 22, 2006
Messages
752
JASS:
    function SBase2I takes string oldBaseString, integer oldBase returns integer
          local integer base10Num = 0
          local integer placeNum //number at current place
          local integer placeIndex = 0 //index of current place. 0 = one's place, etc.
          local integer i = StringLength(oldBaseString)-1
          loop
              exitwhen i < 0
              set placeNum = FindLastIndexFrom(HEX_CHARS, SubString(oldBaseString, i, i+1), oldBase-1)
              set base10Num = base10Num + placeNum*R2I(Pow(I2R(oldBase), I2R(placeIndex)))
              set placeIndex = placeIndex + 1
              set i = i - 1
          endloop
          return base10Num
     endfunction

You dont need those I2R() casts inside Pow().

And if you're not going to support negative numbers, make a note of it in the documentation.

And I don't like the function names S2Id and Id2S. Id seems too vague, could refer to a lot of things. Maybe S2RawCode/RawCode2S.
 
Level 8
Joined
Aug 4, 2006
Messages
357
Fixed all of the above. I seem to have trouble coming up with good function names... :/

I have some questions about raw codes that I am wondering if anyone can answer. I have found out that they are four-digit, base 256 integers. However, I can only find 62 possible characters to put in each digit (namely 0-9, A-Z, a-z). Did I miss any? What about the other 194 numbers that could be represented in each digit? Why didn't blizzard make them base 64 integers?
 
Level 11
Joined
Feb 22, 2006
Messages
752
The raw codes are just integers. The single quotations ' ' are standard CS notation for a cast from characters to integer. In the case of JASS, the cast follows ascii standards. BUT, blizz for some reason decided to only allow these casts for sequences of a single character or four characters. Any other number, and every compiler I've ever used gives you a syntax error (though I'm curious to see if a map would still work if the compiler ignores this limitation and compiles the code anyway).

You can use any of the ascii characters when doing these casts in JASS, as long as you only use one or four characters:

JASS:
call BJDebugMsg(I2S(')')) // displays 41
call BJDebugMsg(I2S('))))')) // displays 690563369
call BJDebugMsg(I2S('ff')) // syntax error!

You can also use non-alphanumeric characters in object raw codes, so you can have an ability with raw code '))))'.
 
Level 8
Joined
Aug 4, 2006
Messages
357
Thanks for the explanation. The S2RawCode and RawCode2S functions now work with any sequence of standard ASCII chars from 32 to 126. While the functions should work for a sequence of any length, world editor will only let you input sequences of one or four characters.
Let me know if there's anything else I can do to get this approved.


For some reason, TESH screws up with \" as an escape combination. It looks at the quote as a regular quote. Who do I contact about this?
 
Level 8
Joined
Aug 4, 2006
Messages
357
Hey guys, I am back from my trip. aznricepuff, I have done everything you asked since initial release. At the moment, I am not aware of any reason this resource should not be approved. It is quite useful and has no bugs that I am aware of. I would appreciate it if you could either approve it, tell me what I can do to get it approved, or tell me why it should not be approved. Thanks again.
 
Level 5
Joined
Jul 4, 2007
Messages
84
(Hope bumping stuff in the graveyard forum is a non-issue.)
Thank you for making this! It was super helpful to me, as a base for my much simpler RemoveNewlines snippet:
JASS:
function RemoveNewlines takes string s returns string
    local integer i = 0
    local integer l = StringLength(s)
    if(2 > l)then
        return s
    endif
    loop
        exitwhen i+2 > l
        if(SubString(s, i, i+2) == "|n")then
            if(i+2 <= l)then
                set s = SubString(s, 0, i)+SubString(s, i+2, l)
            else
                set s = SubString(s, 0, i)
            endif
            set i = i - 2
        endif
        set i = i + 1
    endloop
    return s
endfunction

I googled "war3 stringreplace HIVE" and found this graveyarded project. Still useful! Thanks.

Edit: Fewer safety checks version:
JASS:
function RemoveNewLines takes string s returns string
    local integer i = 0
    local integer l = StringLength(s)
    loop
        exitwhen i+2 > l
        if(SubString(s, i, i+2) == "|n")then
            if(i+2 <= l)then
                set s = SubString(s, 0, i)+SubString(s, i+2, l)
            endif
            set i = i - 2
        endif
        set i = i + 1
    endloop
    return s
endfunction

I'm using:
JASS:
function RemoveNewLine takes string s returns string
    local integer i = 0
    local integer l = StringLength(s)
    loop
        exitwhen i+2 > l
        if(SubString(s, i, i+2) == "|n")then
            return SubString(s, 0, i)+" "+SubString(s, i+2, l)
        endif
        set i = i + 1
    endloop
    return s
endfunction
Because there's only ever one newline in my use case.
 
Last edited:
Top