This kind of thing is something the bioware database is very poorly suited to doing. With NWNX-MySQL, it's very easy - in fact, we do a leaderboard for our arena this way. With the bioware database, it is prohibitively slow. You would have to store the variables in such a way that you could pull every such score up. The most likely way to do this is by an incrementing count in the variable name, something like ArenaKills1, ArenaKills2, and so on. You would then store both the name and the kill count in a string, separated by some kind of divider, in the variable value (it'd have to be a persistent string). One of the major reasons this is expensive is the sorting. Just to add an entry, you'd have to check every existing entry in the database with an incrementing count, so that you'd know where the current list ends, to know what number to put in the var name. You'd have to follow a similar procedure when posting the scores, to pull them all up.
Given the speed of the bioware database, this just isn't feasible, though you might look into Knat's database extender on the vault, since I think it's set up to handle such things as best as is possible.
Really, though, you want MySQL for something like this, if it's at all possible, because it's built to do things like this, and allows easy sorting. Here's the code for the command our players use to check the arena top scores:
string sSQL, sD1, sD2, sD3, sD4, sArenaReport;
int nX;
for (nX = 5; nX > 0; nX--) {
sSQL =
"SELECT monsters,helllevel,playercount,playernames FROM arena WHERE paragon = " + IntToString(nX) +
" ORDER BY monsters DESC, helllevel DESC, playercount LIMIT 5";
SQLExecDirect(sSQL);
sArenaReport = sArenaReport + COLOR_GOLD + "[Monster Level: " + IntToString(nX) + "]" + COLOR_END + NEWLINE;
while (SQLFetch() != SQL_ERROR)
sArenaReport += COLOR_GREEN + "[Monster Number: " + SQLGetData(1) + "]" + COLOR_BLUE + " [Area Level: " +
SQLGetData(2) + "]" + COLOR_PURPLE + " [Team: " + SQLDecodeSpecialChars(SQLGetData(4)) + "]" + COLOR_END +
NEWLINE;
}
SendMessageToPC(oCPC, sArenaReport);
Likewise, entering the data doesn't require any convoluted backflips either, as compared to the things you have to do to make the bioware db do this. Here's the entirety of the script that writes this data, which does so only when all the critters in the arena have been killed, and teleports the players out of the arena:
int GetAreAllSpawnsInAreaDead(object oArea) {
object oCritter = GetFirstObjectInArea(oArea);
while (GetIsObjectValid(oCritter)) {
if (GetLocalString(oCritter, "ES_Death") == "fky_arena_7death" && !GetIsDead(oCritter) && oCritter != OBJECT_SELF)
return FALSE;
oCritter = GetNextObjectInArea(oArea);
}
return TRUE;
}
void main() {
object oArea = GetArea(OBJECT_SELF);
if (GetAreAllSpawnsInAreaDead(oArea)) {
object oWay = GetWaypointByTag("HellGateExit");
location lWay = GetLocation(oWay);
object oDevice = GetNearestObjectByTag("HellGatePortal", oWay);
/* insert data into database */
int nParagon = GetLocalInt(oDevice, "Paragon");
int nHellLevel = GetLocalInt(oDevice, "HellLevel");
int nMonsters = GetLocalInt(oDevice, "Monsters");
int nPlayers = GetLocalInt(oDevice, "PlayerCount");
string sPlayerNames = GetLocalString(oDevice, "PlayerNames");
string sSQL =
"INSERT INTO arena (paragon, helllevel, monsters, playercount, recorddate, playernames) VALUES (" +
IntToString(nParagon) + ", " + IntToString(nHellLevel) + ", " + IntToString(nMonsters) + ", " +
IntToString(nPlayers) + ", DATE_ADD(NOW(), interval 7 day),'" + SQLEncodeSpecialChars(sPlayerNames) + "')";
SQLExecDirect(sSQL);
object oPC = GetFirstPC();
while (GetIsObjectValid(oPC)) {
if (GetArea(oPC) == oArea)
ForceJump(oPC, lWay);
oPC = GetNextPC();
}
}
}
If you have more questions, please feel free to ask, but no matter which option you pick, the setup is going to be complicated.
Funky