Yup, we use that trick all the time - in the case of the spell script example above, convenience simply won out, since the spellinfo struct is in all our spells, not just the dozen or so persistent aoes. Here's a handy bunch of string manipulation functions for anyone who wants them, courtesy of acaos. Holler at me if I missed any included functions - these were culled from a 4k line include.
struct IntList {
int size;
int i0, i1, i2, i3, i4;
int i5, i6, i7, i8, i9;
};
struct StringList {
int size;
string s0, s1, s2, s3;
string s4, s5, s6, s7;
string s8, s9, s10, s11;
string s12, s13, s14, s15;
};
struct SubString {
string first, rest;
};
/* Replace the first (or all) occurrence of sFind in sStr with sRepl. */
string ReplaceString(string sStr, string sFind, string sRepl, int bAll=FALSE, int nLen=-1);
/* Return the specified digit nDigit of nInt. nDigit is the number of
* powers of 10 to use (hence, 0 = 1s, 1 = 10s, 2 = 100s, etc). */
int GetIntegerDigit(int nInt, int nDigit);
/* Set the specified digit nDigit of nInt. */
int SetIntegerDigit(int nInt, int nDigit, int nValue);
/* Return an IntList struct containing all the digits of nInt. */
struct IntList GetDigitList(int nInt);
/* Get a random floating-point number in the range [-1.0, 1.0]. If fRange
* is specified, a random number in the range [0.0, fRange] will be returned. */
float RandomFloat(float fRange=0.0);
/* Return the substring at the given index nIndex of sString, separating
* sString with sSep. */
string GetStringSubString(string sString, int nIndex, string sSep=" ");
/* Return the number of substrings sString would have if it were separated
* by sSep. */
int GetStringSubStrings(string sString, string sSep=" ");
/* Return a random string of sString separated by sSep. */
string GetRandomSubString(string sString, string sSep=" ");
/* Return a SubString struct containing the first substring of sString
* separated by sSep, as well as the remainder of sString. The idiom
* would be:
*
* struct SubString ss;
*
* ss.rest = sString;
*
* while (ss.rest != "") {
* ss = GetFirstSubString(ss.rest);
*
* (do things here)
* }
*/
struct SubString GetFirstSubString(string sString, string sSep = " ");
/* Return a StringList struct containing strings extracted from sString
* separated by sSep. */
struct StringList GetStringList(string sString, string sSep=" ", int nLimit=16);
/* Return an IntList struct containing integers extracted from sString
* separated by sSep. */
struct IntList GetIntList(string sString, string sSep=" ", int nLimit=10);
/* Return vPos in string form X, Y, Z. */
string GetPositionStringFromVector(vector vPos);
/* Return the position of lLoc in string form [X, Y, Z | F] */
string GetPositionStringFromLocation(location lLoc);
/* Return the position of oObject in string form [X, Y, Z | F] */
string GetPositionString(object oObject);
string ReplaceString(string sStr, string sFind, string sRepl, int bAll=FALSE, int nLen=-1) {
int nPos = FindSubString(sStr, sFind);
if (nPos
return sStr;
if (nLen
nLen = GetStringLength(sFind);
do {
sStr = GetStringLeft(sStr, nPos) + sRepl +
GetStringRight(sStr, GetStringLength(sStr) - (nPos + nLen));
if (!bAll)
break;
nPos = FindSubString(sStr, sFind);
} while (nPos >= 0);
return sStr;
}
int GetIntegerDigit(int nInt, int nDigit) {
switch (nDigit) {
case 0: nDigit = 1; break;
case 1: nDigit = 10; break;
case 2: nDigit = 100; break;
case 3: nDigit = 1000; break;
case 4: nDigit = 10000; break;
case 5: nDigit = 100000; break;
case 6: nDigit = 1000000; break;
case 7: nDigit = 10000000; break;
case 8: nDigit = 100000000; break;
case 9: nDigit = 1000000000; break;
default:
return 0;
}
return ((nInt / nDigit) % 10);
}
int SetIntegerDigit(int nInt, int nDigit, int nValue) {
if (nValue
nValue = 0;
else if (nValue > 9)
nValue = 9;
switch (nDigit) {
case 0: nDigit = 1; break;
case 1: nDigit = 10; break;
case 2: nDigit = 100; break;
case 3: nDigit = 1000; break;
case 4: nDigit = 10000; break;
case 5: nDigit = 100000; break;
case 6: nDigit = 1000000; break;
case 7: nDigit = 10000000; break;
case 8: nDigit = 100000000; break;
case 9: nDigit = 1000000000; break;
default:
return 0;
}
nInt -= ((nInt / nDigit) % 10) * nDigit;
nInt += nValue * nDigit;
return nInt;
}
struct IntList GetDigitList(int nInt) {
struct IntList ret;
ret.i0 = (nInt % 10);
ret.i1 = (nInt /= 10) % 10;
ret.i2 = (nInt /= 10) % 10;
ret.i3 = (nInt /= 10) % 10;
ret.i4 = (nInt /= 10) % 10;
ret.i5 = (nInt /= 10) % 10;
ret.i6 = (nInt /= 10) % 10;
ret.i7 = (nInt /= 10) % 10;
ret.i8 = (nInt /= 10) % 10;
ret.i9 = (nInt /= 10) % 10;
return ret;
}
float RandomFloat(float fRange=0.0) {
if (fRange > 0.0)
return (Random(FloatToInt(fRange * 1000)) / 1000.0);
return ((Random(10000001) - 5000000) / 5000000.0);
}
float RandomNormal(float fStdDev=1.0, float fMean=0.0) {
float u1, u2, v1, v2, s;
do {
u1 = RandomFloat();
u2 = RandomFloat();
v1 = (2.0 * u1) - 1.0;
v2 = (2.0 * u2) - 1.0;
s = (v1 * v1) + (v2 * v2);
} while (s > 1.0);
return (sqrt((-2.0 * log(s)) / s) * v1 * fStdDev) + fMean;
}
string GetStringSubString(string sString, int nIndex, string sSep=" ") {
int nSep, nStart = 0, nSkip = GetStringLength(sSep);
while (nIndex-- > 0) {
nSep = FindSubString(sString, sSep, nStart);
if (nSep
return "";
nStart = nSep + nSkip;
}
if ((nSep = FindSubString(sString, sSep, nStart))
nSep = GetStringLength(sString);
return GetSubString(sString, nStart, (nSep - nStart));
}
int GetStringSubStrings(string sString, string sSep=" ") {
int nCount = 1, nStart = 0;
int nSep = FindSubString(sString, sSep);
int nSkip = GetStringLength(sSep);
if (nSkip
return 1;
while (nSep >= 0) {
nCount++;
nSep = FindSubString(sString, sSep, nSep + nSkip);
}
return nCount;
}
string GetRandomSubString(string sString, string sSep=" ") {
int nCount = GetStringSubStrings(sString, sSep);
return GetStringSubString(sString, Random(nCount), sSep);
}
struct SubString GetFirstSubString(string sString, string sSep = " ") {
struct SubString ret;
int nSep = FindSubString(sString, sSep);
if (nSep
ret.first = sString;
ret.rest = "";
return ret;
}
ret.first = GetStringLeft(sString, nSep);
ret.rest = GetStringRight(sString, GetStringLength(sString) - (nSep + GetStringLength(sSep)));
return ret;
}
struct StringList GetStringList(string sString, string sSep=" ", int nLimit=16) {
int nCount = 0, nSep = 0, nStart = 0;
int nSkip = GetStringLength(sSep);
int nLen = GetStringLength(sString);
struct StringList sl;
if (nSkip
sl.size = 0;
return sl;
}
while (nSep
nSep = FindSubString(sString, sSep, nStart);
if (nSep
nSep = nLen;
switch (nCount & 1) {
case 0: switch (nCount++) {
case 0: sl.s0 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 2: sl.s2 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 4: sl.s4 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 6: sl.s6 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 8: sl.s8 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 10: sl.s10 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 12: sl.s12 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 14: sl.s14 = GetSubString(sString, nStart, (nSep - nStart)); break;
}
break;
case 1: switch (nCount++) {
case 1: sl.s1 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 3: sl.s3 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 5: sl.s5 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 7: sl.s7 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 9: sl.s9 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 11: sl.s11 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 13: sl.s13 = GetSubString(sString, nStart, (nSep - nStart)); break;
case 15: sl.s15 = GetSubString(sString, nStart, (nSep - nStart)); break;
}
break;
}
nStart = nSep + nSkip;
}
sl.size = nCount;
return sl;
}
struct IntList GetIntList(string sString, string sSep=" ", int nLimit=10) {
int nCount = 0, nSep = 0, nStart = 0;
int nLen = GetStringLength(sString);
int nSkip = GetStringLength(sSep);
struct IntList il;
if (nSkip
il.size = 0;
return il;
}
while (nSep
nSep = FindSubString(sString, sSep, nStart);
if (nSep
nSep = nLen;
switch (nCount++) {
case 0: il.i0 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 1: il.i1 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 2: il.i2 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 3: il.i3 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 4: il.i4 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 5: il.i5 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 6: il.i6 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 7: il.i7 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 8: il.i8 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
case 9: il.i9 = StringToInt(GetSubString(sString, nStart, (nSep - nStart))); break;
}
nStart = nSep + nSkip;
}
il.size = nCount;
return il;
}
string GetPositionStringFromVector(vector vPos) {
return FloatToString(vPos.x, 1, 2) + ", " +
FloatToString(vPos.y, 1, 2) + ", " +
FloatToString(vPos.z, 1, 2);
}
string GetPositionStringFromLocation(location lLoc) {
vector vPos = GetPositionFromLocation(lLoc);
return "[" + GetPositionStringFromVector(GetPositionFromLocation(lLoc)) +
" | " + FloatToString(GetFacingFromLocation(lLoc), 1, 0) + "]";
}
string GetPositionString(object oObject) {
return GetPositionStringFromLocation(GetLocation(oObject));
}
location GetLocationFromString(object oArea, string sLoc) {
float fFacing;
vector vVec;
vVec = Vector(StringToFloat(GetStringSubString(sLoc, 0, ",")),
StringToFloat(GetStringSubString(sLoc, 1, ",")),
StringToFloat(GetStringSubString(sLoc, 2, ",")));
fFacing = StringToFloat(GetStringSubString(sLoc, 3, ","));
return Location(oArea, vVec, fFacing);
}
If speed is not a concern (frankly... is it? We got uber CPUs today), we may even operate a conversion from integer to Hex, thus dropping from 10 to 8 digits per integer, culling 20 more bytes.
Nice. Speed is ALWAYS an issue. Given the size of strings that NWNX throws left and right, however (it uses large string groups as well, with a ~ delimiter), I wouldn't bother with the hex conversion in this case.
'>
Funky
Modifié par FunkySwerve, 19 octobre 2010 - 08:13 .