Ok, here are the changes needed to get this working. Firstly the code changes.
In zone.cpp ~line 1037 you'll find bool Database::PopulateZoneSpawnList(const char* zone_name, LinkedList<Spawn2*> &spawn2_list, int32 repopdelay) - replace that entire function with:
Code:
bool Database::PopulateZoneSpawnList(const char* zone_name, LinkedList<Spawn2*> &spawn2_list, int32 repopdelay) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int8 advlevel=CheckAdvLevel(zone->GetShortName());
//Killspree: Added advlevel to query - spawns are loaded from spawn2 where advlevel is = to the value returned by CheckAdvLevel() above.
MakeAnyLenString(&query, "SELECT id, spawngroupID, x, y, z, heading, respawntime, variance, pathgrid, timeleft FROM spawn2 WHERE zone='%s' AND advlevel=%i", zone_name, advlevel);
if (RunQuery(query, strlen(query), errbuf, &result))
{
safe_delete_array(query);
while((row = mysql_fetch_row(result)))
{
Spawn2* newSpawn = 0;
//if(GetInverseXY()==1) {
// newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[3]), atof(row[2]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]));
//}
//else {
newSpawn = new Spawn2(atoi(row[0]), atoi(row[1]), atof(row[2]), atof(row[3]), atof(row[4]), atof(row[5]), atoi(row[6]), atoi(row[7]), atoi(row[9]), atoi(row[8]));
//}
//newSpawn->Repop(repopdelay);
spawn2_list.Insert( newSpawn );
}
mysql_free_result(result);
}
else
{
cerr << "Error in PopulateZoneLists query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
return true;
}
Above that we'll add the new function, CheckAdvLevel():
Code:
int8 CheckAdvLevel(const char* shortname){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (database.RunQuery(query, MakeAnyLenString(&query, "SELECT advlevel FROM zone WHERE short_name='%s'",shortname), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1)
{
row = mysql_fetch_row(result);
int8 advlevel = atoi(row[0]);
mysql_free_result(result);
return advlevel;
}
else
{
mysql_free_result(result);
return 0;
}
mysql_free_result(result);
}
else
{
cerr << "Error in CheckAdvLevel query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return false;
}
return 0;
}
That's all you need to do to get zones spawning based on the advlevel field in the zones table code-wise. Now on to the function to update the advlevel. This is a perl function.
parser.cpp ~line 1133 add:
Code:
else if (!strcmp(strlwr(command),"setadvlevel")){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
int8 advlevel = atoi(arglist[0]);
int16 zoneid = atoi(arglist[1]);
if (!database.RunQuery(query, MakeAnyLenString(&query, "UPDATE zone SET advlevel = %i where zoneidnumber = %i", advlevel, zoneid), errbuf)) {
cerr << "Error in SetAdvLevel query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
safe_delete_array(query);
}
embparser.cpp ~line 504 add:
Code:
"sub setadvlevel{push(@cmd_queue,{func=>'setadvlevel',args=>join(',',@_)});}"
Now for database changes...you'll need to run the following in mysql.
For the zone table:
Code:
ALTER TABLE `zone` ADD `advlevel` INT(4) DEFAULT "0" NOT NULL AFTER `weather`
And for the spawn2 table:
Code:
ALTER TABLE `spawn2` ADD `advlevel` INT(4) DEFAULT "0" NOT NULL AFTER `timeleft`
How to use setadvlevel() quest function:
quest::setadvlevel("advlevelvalue","zoneid");
advlevelvalue is the value you want the advlevel to be set to in the zone table.
zoneid is the zoneid of the zone that the advlevel will be altered for in the zone table.
You'll want to have corresponding advlevel values in spawn2 for each value there will be in zone. So lets say we want to spawn NPCs for a level 6 to 10 range, level 11 to 15 range, level 16 to 20 range, and level 21 to 25 range. You'll want to set up exact copies of the spawns in spawn2, each with a different advlevel value and their appropriate spawngroupID.
Example:
a_rat(level 6) spawns at 0,0,0 in west freeport. It'll have the advlevel value of 1.
a_rat(level 13) spawns at 0,0,0 in west freeport. It'll have the advlevel value of 2.
a_rat(level 17) spawns at 0,0,0 in west freeport. It'll have the advlevel value of 3.
a_rat(level 22) spawns at 0,0,0 in west freeport. It'll have the advlevel value of 4.
Now here is the trick - only one of those four will spawn, based on the advlevel value set in the zone table. the advlevel values MUST match for that specific npc to spawn.
Once I work on instancing, I'll post the updated code. Nothing should change much, just where the db query looks for the advlevel.