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
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.
function FindIndexFrom takesstring mainString, string stringToFind, integer startingIndex returnsinteger //returns the first (leftmost) index of "stringToFind" in "mainString" // after "startingIndex." (Starts looking at starting index) //returns -1 if "stringToFind" is not found //example: localstring fatty = "To be or not to be" localstring shorty = "be" localinteger index = FindIndexFrom(fatty, shorty, 4) call BJDebugMsg(index)//16
function FindIndex takesstring mainString, string stringToFind returnsinteger //returns the first (leftmost) index of "stringToFind" in "mainString" //returns -1 if "stringToFind" is not found
function FindLastIndexFrom takesstring mainString, string stringToFind, integer startingIndex returnsinteger //returns the last (rightmost) index of "stringToFind" in "mainString" // before "startingIndex." (Looks backwards from startingIndex) //returns -1 if "stringToFind" is not found //example: localstring big = "Am I a hot bot, or not?" localstring small = "ot" localinteger index = FindLastIndexFrom(big, small, 19) call BJDebugMsg(index)//12 function FindLastIndex takesstring mainString, string stringToFind returnsinteger //returns the last (rightmost) index of "stringToFind" in "mainString" //returns -1 if "stringToFind" is not found
function PlayerColor2ColorString takesplayercolor pc returnsstring //takes a playercolor handle (does anyone actually use those?) and // returns the corresponding color string (same form as above)
function GetPlayerColorString takesplayer p returnsstring //takes a player and returns the color string associated with him/her //in the form of "|cffRRGGBB" function GetPlayerNameColored takesplayer p returnsstring //returns the player’s name with appropriate color //example: GetPlayerNameColored(Player(0))//returns "|cffff0303World Edit|r"
function RemoveColorCode takesstring mainString returnsstring //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 takesinteger base10Num, integer newBase returnsstring //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 takesstring oldBaseString, integer oldBase returnsinteger //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 takesinteger red, integer green, integer blue returnsstring //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 takesstring str, integer r, integer g, integer b returnsstring //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"
function RemoveString takesstring mainString, string toRemove returnsstring //removes all occurances of toRemove from mainString //returns the new string //example: localstring silly = "aaaaheaaaalaloaa" set silly = RemoveString(silly, "a") call BJDebugMsg(silly)//"hello"
function NumOccurances takesstring mainString, string stringToFind returnsinteger //returns the number of times stringToFind is found in mainString //example: localstring str = "wefejwejdsfowe fj" localstring str2 = "we" localinteger num = NumOccurances(str, str2) call BJDebugMsg(num)//3
function S2B takesstring word returns Boolean //converts "true" into true and "false" into false //returns false if the string is not valid
function S2Player takesstring word returnsplayer //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 takesstring str returnsinteger //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)
function B2S takesboolean bool returnsstring //returns "true" or "false" //example usage: localboolean b = IsPlayerAlly(Player(0), Player(1)) call BJDebugMsg("Player 0 allied with Player 1? "+B2S(b))
function Player2S takesplayer p returnsstring //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 takesunit u returnsstring //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: localunit yourMom = CreateUnit(Player(0), 'hpea', 0, 0, 0) call BJDebugMsg(Unit2S(yourMom))//Peasant_92
function RawCode2S takesstring str returnsinteger //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.
privatefunction Init takesnothingreturnsnothing localinteger 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 takesplayercolor pc returnsstring localinteger 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 takesplayer p returnsstring return PlayerColor2ColorString(GetPlayerColor(p)) endfunction
function GetPlayerNameColored takesplayer p returnsstring return GetPlayerColorString(p)+GetPlayerName(p)+COLOR_ENDING endfunction
function IBase2S takesinteger base10Num, integer newBase returnsstring localinteger placeNum //number at current place localstring 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 takesstring oldBaseString, integer oldBase returnsinteger localinteger base10Num = 0 localinteger placeNum //number at current place localinteger placeIndex = 0//index of current place. 0 = one's place, etc. localinteger 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 takesinteger red, integer green, integer blue returnsstring localstring RR localstring GG localstring 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 takesstring str, integer r, integer g, integer b returnsstring return ConvertRGBToColorString(r,g,b)+str+COLOR_ENDING endfunction
function RemoveString takesstring mainString, string toRemove returnsstring localinteger i = 0 localstring currentString localinteger msLength = StringLength(mainString) localinteger 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 takesstring mainString, string stringToFind returnsinteger localinteger count = 0 localinteger i = 0 localinteger msLength = StringLength(mainString) localinteger 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 takesstring word returnsboolean if(word == "true")then returntrue endif returnfalse endfunction
function S2Player takesstring word returnsplayer return Player(S2I(SubString(word, 1, StringLength(word)))) endfunction
globals privateinteger MIN_RAW_CODE = ' '//32 privatestring RAW_CHARS = " !\"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~" endglobals function S2RawCode takesstring str returnsinteger localinteger rawCode = 0 localinteger placeNum //number at current place localinteger placeIndex = 0//index of current place. 0 = one's place, etc. localinteger 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
function Player2S takesplayer p returnsstring return"Player("+I2S(GetPlayerId(p))+")" endfunction
function Unit2S takesunit u returnsstring return GetUnitName(u)+ "_"+I2S(GetHandleId(u)-0x100000) endfunction
function RawCode2S takesinteger rawCode returnsstring localinteger placeNum //number at current place localstring 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
Changelog
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 by maskedpoptart; 11-28-2009 at 07:59 AM.
Reason: bug fix
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
function Unit2S takesunit u returnsstring 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"
function S2Player takesstring word returnsplayer localinteger tempInt1 = FindIndex(word, "(") localinteger tempInt2 = FindIndex(word, ")") localinteger playerNum if(tempInt1 == -1 or tempInt2 == -1)then returnnull 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.
function Convert255ToFF takesinteger number returnsstring function ConvertFFTo255 takesstring str returnsinteger
Please come up with better identifiers for those functions. I2HexString/HexString2I would be better.
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.
Quote:
Originally Posted by aznricepuff
I2HexString/HexString2I would be better.
done.
updated a bunch of stuff on the original post, and added FindLastIndex.
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
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:
function B2S takesboolean bool returnsstring if(bool)then return"true" endif return"false" endfunction
Some more stuff in general
function PlayerColor2ColorString takesplayercolor pc returnsstring
should be
function playerColor2ColorString takesplayercolor pc returnsstring
Follow camelcase style. First letter in a function or method is always lowercase where the rest are uppercase.
privateconstantstring hex = "0123456789abcdef"
Should be
privateconstantstring 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 =).
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.
-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.
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.
Quote:
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.
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.
Quote:
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.
Quote:
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,
Quote:
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-
Quote:
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.
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++ =).
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.
Quote:
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.
Quote:
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.
Your I2HexString and vice-versa should handle arbitrary lengths.
For that matter, why not just have I2SB and S2IB (I2SBase and S2IBase)? Then, for example, a hex string to an integer would be localinteger i = S2IB(<String>,16).
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.