PDA

View Full Version : Zone instancing


Rocker8956
09-13-2008, 01:55 AM
(Sorry, I would have put this in the old thread but I did not want to confuse anyone on how the code worked)

This code basically enables zone instancing

Select a zone you want to instance
Set that zone's insttype to 1
Select a character you want to access that zone
Set that character's
instZflagNum to a number greater than 1000
instZOrgID to the zoneID of the zone you picked
rinse and repeat with second character changing the instZflagNum (if you want them to go to a different zone)

Zone characters into the zone you picked.

K, here is my example
I want to instance blackburrow (has a zoneid of 17
I set blackburrow's insttype to 1 in the zone table
I want my toon MonkGod to access an instance of blackburrow
I set MonkGod's
instZflagNum to 1001
instZOrgID to 17


I then set the instZflagnum and insZordID on Aries, my other character.
changing the instZflagNum to 1002
Setting instZOrgID to 17


All that would be required to get this fully functional is a quest command that sets a character’s InstZflagNum and instZOrgID. I have a method for doing this but don’t know where to put the code. Anyone willing to help write it please let me know.

Anyhow here are the required changes. This was done against 1129 using PEQ database.
Please let me know what bugs you notice.

Required SQL

ALTER TABLE `zone` ADD column `insttype` tinyint (1) zerofill unsigned NOT NULL default '0';
ALTER table character_ ADD column `instZflagNum` int(10) unsigned NOT NULL default '0';
ALTER table character_ ADD column `instZOrgID` int(11) NOT NULL default '0';
INSERT INTO variables VALUES ('curInstFlagNum', 1000, 'Determines what instance flag will be handed out next', '2008-09-05 04:46:47');
INSERT INTO variables VALUES ('dfltInstZflag',1000, 'Used to determine if a zone is instanced, must be 1000 or greater', '2008-09-05 04:46:47');


World\Zoneserver.cpp
Line 498 insert

ztz->requested_zone_id = database.GetInstZoneID(ztz->requested_zone_id, ztz->name);

Line 508-509 insert

int server_id;
ztz->requested_zone_id = database.GetInstZoneID(ztz->requested_zone_id, ztz->name);
if ((server_id = zoneserver_list.TriggerBootup(ztz->requested_zone_id)))

Line 533 insert

zlog(WORLD__ZONE,"Processing ZTZ for ingress to zone for client %s\n", ztz->name);
ztz->current_zone_id = database.GetInstZoneID(ztz->current_zone_id, ztz->name); //Rocker8956 possible fix for wrong zone shutdown
ZoneServer *egress_server = zoneserver_list.FindByZoneID(ztz->current_zone_id);



World\Client.cpp
Line 644 insert

zoneID = database.GetInstZoneID(zoneID, GetCharName());


Zone\zoning.cpp
Line 122

//Checks if the zone can be instanced, character has a instance flag, and
//that the character is not zoning into an instance that is already loaded
if(database.GetInstType(target_zone_id) == 1){
int32 characterID = database.GetCharacterID(zc->char_name);
int32 instFlagNum = database.GetCharInstFlagNum(characterID);
if(instFlagNum >= database.GetDfltInstZFlag())
{
int32 charInstZOrgID = database.GetCharInstZOrgID(characterID);
// If instance flag matches then...
if(charInstZOrgID == target_zone_id)
{
//If instance zone is not in database then it is copied to database
if(!database.InstZoneLoaded(instFlagNum)) {
database.LoadInstZone(target_zone_id, instFlagNum);
}
target_zone_id = instFlagNum;
}
}
}


Common\database.h
Line 201 insert

int32 GetCharInstFlagNum(int32 charID);
int32 GetCharInstZOrgID(int32 charID);
int32 GetInstZoneID(int32 zoneID, const char* charName);
void DeleteInstZone(int32 instZoneID);
int32 GetDfltInstZFlag();


Common\database.cpp
Line 1173

const char* Database::GetZoneName(int32 zoneID, bool ErrorUnknown) {
if (zonename_array == 0) {
if (ErrorUnknown)
return "UNKNOWN";
else
return 0;
}
if (zoneID > GetDfltInstZFlag())
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZOrgID FROM character_ WHERE instZflagNum=%i", zoneID), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) > 0) {
row = mysql_fetch_row(result);
int8 tmp = atoi(row[0]);
mysql_free_result(result);
return zonename_array[tmp];
}
mysql_free_result(result);
}
else
{
cerr << "Error in instZOrgID query in database.cpp GetZoneName'" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}
else if (zoneID <= max_zonename) {
if (zonename_array[zoneID])
return zonename_array[zoneID];
else {
if (ErrorUnknown)
return "UNKNOWN";
else
return 0;
}
}
else {
if (ErrorUnknown)
return "UNKNOWN";
else
return 0;
}
}


End of Common\database.cpp insert

int32 Database::GetDfltInstZFlag(){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname = 'dfltInstZflag'"), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
int32 tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;
}
mysql_free_result(result);
}

else {
cerr << "Error in GetDfltInstZFlag query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}
int32 Database::GetCharInstFlagNum(int32 charID){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZflagNum FROM character_ WHERE id=%i", charID), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
int tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;
}
mysql_free_result(result);
}
else {
cerr << "Error in GetCharInstFlag Numquery '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}

int32 Database::GetCharInstZOrgID(int32 charID){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZOrgID FROM character_ WHERE id=%i", charID), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
int32 tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;

}
mysql_free_result(result);
}
else {
cerr << "Error in GetInstType query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}
int32 Database::GetInstZoneID(int32 zoneID, const char* charName) {
if (zoneID == 0)
return 0;
int32 charID = GetCharacterID(charName);
if (zoneID == GetCharInstZOrgID(charID))
{
zoneID = GetCharInstFlagNum(charID);
return zoneID;
}
else
return (zoneID);
}

void Database::DeleteInstZone(int32 instZoneID)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
if (RunQuery(query, MakeAnyLenString(&query, "DELETE FROM zone WHERE zoneidnumber=%i", instZoneID), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else {
cerr << "Error in DeleteInstZone query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}


Zone\zonedb.cpp
Append to the end

int32 ZoneDatabase::GetInstType(int32 zoneid) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (RunQuery(query, MakeAnyLenString(&query, "SELECT insttype FROM zone WHERE zoneidnumber=%i", zoneid), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
int8 tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;

}
mysql_free_result(result);
}

else {
cerr << "Error in GetInstType query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}
bool ZoneDatabase::InstZoneLoaded(int32 charInstFlagNum){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (RunQuery(query, MakeAnyLenString(&query, "SELECT zoneidnumber FROM zone WHERE zoneidnumber=%i", charInstFlagNum), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
return true;
}
else if (mysql_num_rows(result) == 0) {
return false;
}
mysql_free_result(result);
}

else {
cerr << "Error in isInstZoneLoad query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}



//Copies original zones information into a new zone entry replacing the old zoneidnumber with the instflagnum
void ZoneDatabase::LoadInstZone(int32 target_zone_ID, int32 instFlagNum){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int32 affected_rows = 0;
string tmpzonename = database.GetZoneName(target_zone_ID);
string temp;
const char* temp2;
stringstream tmpFlag; // used for converting int32 instFlagNum to a string

tmpFlag << instFlagNum;
temp = tmpFlag.str();
temp.append(tmpzonename);
temp2 = temp.c_str();

if (RunQuery(query, MakeAnyLenString(&query, "INSERT INTO zone (short_name, file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, zoneidnumber, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer) SELECT '%s', file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, %i, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer FROM zone WHERE zoneidnumber =%i", temp2,instFlagNum,target_zone_ID), errbuf, 0, &affected_rows)){
safe_delete_array(query);}
else {
cerr << "Error in LoadInstZone query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}


Zone\zoneDB.cpp line 13 insert

#include <string>
#include <sstream>



Zone\zonedb.h
line 194 change const char* zone_name to int32 zoneid

bool PopulateZoneSpawnList(int32 zoneid, LinkedList<Spawn2*> &spawn2_list, int32 repopdelay = 0);


Zone\Zonedb.h
At the end of Zone Related around line 181

int32 GetInstType(int32 zoneid);
bool InstZoneLoaded(int32 target_zone_ID);
void LoadInstZone(int32 target_zone_ID, int32 InstFlagNum);



Zone.cpp Line 1146 change short_name to zoneid

if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, delay))


Zone.cpp Line 779 change short_name to zoneid

if (!database.PopulateZoneSpawnList(zoneid, spawn2_list))



Zone.cpp Line 772 change short_name to zoneid

else if (tmp == 0) {
LogFile->write(EQEMuLog::Status, "No state saved, loading spawn2 points...");
if (!database.PopulateZoneSpawnList(zoneid, spawn2_list))
return false;
}


Zone\Zone.cpp line 616 bottom of Zone::Shutdown insert

zone->ResetAuth();
if (zone->GetZoneID() > database.GetDfltInstZFlag()){
database.DeleteInstZone(zone->GetZoneID());
}
safe_delete(zone);
dbasync->CommitWrites();
UpdateWindowTitle();



Zone\spawn2.cpp line 226

bool ZoneDatabase::PopulateZoneSpawnList(int32 zoneid, LinkedList<Spawn2*> &spawn2_list, int32 repopdelay) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

const char *zone_name = database.GetZoneName(zoneid);
int32 dfltInstZFlag = database.GetDfltInstZFlag();

MakeAnyLenString(&query, "SELECT id, spawngroupID, x, y, z, heading, respawntime, variance, pathgrid, timeleft, _condition, cond_value FROM spawn2 WHERE zone='%s'", zone_name);

if (RunQuery(query, strlen(query), errbuf, &result))
{
safe_delete_array(query);
while((row = mysql_fetch_row(result)))
{
Spawn2* newSpawn = 0;
if (zoneid > dfltInstZFlag){
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]), 0, atoi(row[8]), atoi(row[10]), atoi(row[11]));
}
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]), atoi(row[10]), atoi(row[11]));
}
//newSpawn->Repop(repopdelay);
spawn2_list.Insert( newSpawn );
}
mysql_free_result(result);
}
else
{
LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}

return true;
}

trevius
09-13-2008, 04:05 AM
Definitely some interesting stuff! I will have to check this out more when I get a bit more time. I think this code could definitely be useful at some point. I don't want you to feel like your submissions are getting ignored though. If this can be finalized and get the quest commands added, this could actually be some really useful code. With limited resources for creating content, some of the more popular custom servers may have bottlenecks in some zones that are very popular. Maybe adding 1 instance during peak times, or when needed, would help balance out players and content. So, a small server with limited content could still be enjoyed by many.

Anyway, it is definitely something worth looking into more. I was wondering why you named the setting "instZOrgID" instead of something like "instZoneID". I am all for anything that is clear and as simple as possible. So, naming settings after what they are used to set is IMO the best way.

Rocker8956
09-13-2008, 10:26 AM
Thank you for the reply Trevius.

If I get some time this weekend, after work and college, I will knock out some of the quest code to use for setting the instance flags and such. After looking at the questmgr.cpp it does not look like it would be too bad especially since a kind soul put instructions at the top.

The instZOrgID actually stands for Instance Zone’s Original Zone ID. It is used in the code to track what zone the instZflagNum (later used as the instance zone’s ID) belongs too. I couldn’t think of a better name for instZOrgID so I went with it but if we can come up with something a little more intuitive adjusting the code would not be difficult.

Rocker8956
09-16-2008, 10:25 AM
Please note this code is not tested, I have no experience writing quests so I am hoping someone with quest writing experience will test it for me.

This code adds a quest function that will set a character's instance flag. Sending that character to an instance the next time they zone into the zone of your choice.

It requires two bits of information. The character's ID and the zoneID of the zone you want instanced.

If there are any questions please let me know.

Anyhow here is the code.

Zone\perlparser.cpp
Near Line 1759 insert

XS(XS__setindinstflag);
XS(XS__setindinstflag)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: setindinstflag(charID, orginalZoneID)");

int32 charID = (int)SvIV(ST(0));
int32 orgZoneID = (int)SvIV(ST(1));

quest_manager.setindinstflag(charID, orgZoneID);

XSRETURN_EMPTY;
}


Zone\perlparser.cpp
Around Line 1899 insert

newXS(strcpy(buf, "setindinstflag"), XS__setindinstflag, file);


Zone\questmgr.h
Around line 150 insert

void setindinstflag(int32 charID, int32 orgZoneID);


Zone\questmgr.cpp
At the end insert

void QuestManager::setindinstflag(int32 charID, int32 orgZoneID)
{
database.setOneCharInstFlag(charID, orgZoneID);
}


Common\database.cpp
At the end insert

void Database::setOneCharInstFlag(int32 charID, int32 orgZoneID)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int instFlag;

if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname = 'curInstFlagNum'"), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
instFlag = atoi(row[0]);
mysql_free_result(result);
}
mysql_free_result(result);
}
else {
cerr << "Error in GetCurInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}

if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET instZflagNum=%i, instZOrgID=%i WHERE id=%i", instFlag, orgZoneID, charID), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else {
cerr << "Error in setCharInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}

instFlag++;

if (RunQuery(query, MakeAnyLenString(&query, "UPDATE variables SET value=%i WHERE varname='curInstFlagNum'", instFlag), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else {
cerr << "Error in incrCurInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}

}


Common\database.h
At the end insert

void setOneCharInstFlag(int32 charID, int32 orgZoneID);

Rocker8956
09-17-2008, 10:24 AM
Here is the code for setting a group’s instance flags through quests. This will allow the whole group to zone into the same instance.
Please note, I have no experience writing quests so this is untested. I appreciate any feedback.

zone\perlparser.cpp
Insert at the end around line 1914

newXS(strcpy(buf, "setgroupinstflag"), XS__setgroupinstflag, file);


zone\perparser.cpp
insert around line 1758

XS(XS__setgroupinstflag);
XS(XS__setgroupinstflag)
{
dXSARGS;
if (items != 2)
Perl_croak(aTHX_ "Usage: setgroupinstflag(charID, orginalZoneID)");

int32 charID = (int)SvIV(ST(0));
int32 orgZoneID = (int)SvIV(ST(1));

quest_manager.setgroupinstflag(charID, orgZoneID);

XSRETURN_EMPTY;
}


zone\questmgr.h
Insert around line 151

void setgroupinstflag(int32 charID, int32 orgZoneID);


zone\questmgr.cpp
Insert at the end

void QuestManager::setgroupinstflag(int32 charID, int32 orgZoneID)
{
database.setGroupInstFlagNum(charID, orgZoneID);
}


common\database.cpp
Insert at the end

void Database::setGroupInstFlagNum(int32 charID, int32 orgZoneID)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int32 groupid = 0;
int instFlag = 0;
int numCharsInGroup = 0; // Used to count number of characters in group

// Get the current instant flag number
if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname = 'curInstFlagNum'"), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
instFlag = atoi(row[0]);
mysql_free_result(result);
}
mysql_free_result(result);
}
else {
cerr << "Error in GetCurInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
// Find out what group the character is in
if (RunQuery(query, MakeAnyLenString(&query, "SELECT groupid from group_id where charid=%i", charID), errbuf, &result)) {
if((row = mysql_fetch_row(result)))
{
if(row[0])
groupid=atoi(row[0]);
}
else
printf("Unable to get group id, char not found!\n");
mysql_free_result(result);
}
else
printf("Unable to get group id: %s\n",errbuf);
safe_delete_array(query);
// Find out how many other characters are in the group
if (RunQuery(query, ("SELECT COUNT(charid) FROM group_id WHERE groupid=%i", groupid), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
if (row && row[0])
{
numCharsInGroup = atoi(row[0]);
mysql_free_result(result);
}
}
// Select the character IDs of the characters in the group
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from group_id where groupid='%i'", groupid), errbuf, &result))
{
int i = 0;
// Set each group members instflag
while ((i <= numCharsInGroup))
{
charID = atoi(row[i]);
if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET instZflagNum=%i, instZOrgID=%i WHERE id=%i", instFlag, orgZoneID, charID), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else {
cerr << "Error in setCharInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
i++;
}
safe_delete_array(query);
mysql_free_result(result);
}
// Increment the curInstFlagNum
instFlag++;

if (RunQuery(query, MakeAnyLenString(&query, "UPDATE variables SET value=%i WHERE varname='curInstFlagNum'", instFlag), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else {
cerr << "Error in incrCurInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}


common\database.h
Insert at the end

void setGroupInstFlagNum(int32 charID, int32 orgZoneID);

Rocker8956
09-19-2008, 07:30 PM
Some changes to the quest code plus a way to manually set a characters instflag.

Syntax for quest functions
setinstflag(charID, originalZoneID, type)
charID = character ID of the character requesting flag
originalZoneID = zoneID of the zone you want instanced (blackburrow would be 17)
type = 0 will flag only the requesting character
type = 1 will flag the requesting character’s group including that character
type = 2 will flag the requesting character’s raid including that character
setinstflagmanually(charID, originalZoneID, instFlag)
charID = character ID of the character requesting flag
originalZoneID = zoneID of the zone you want instanced (blackburrow would be 17)
instFlag = the instance flag you want to give the requesting character. Pick a number between 1000 and 1999. Try not to use the same one for different quests.

The setinstflagmanually will allow you to send characters to the same instance zone even if they are not in the same group or raid.

SQL changes

INSERT INTO variables VALUES ('curInstFlagNum', 2000, 'Determines what instance flag will be handed out next', '2008-09-05 04:46:47');

If you already inserted this into your database just change the value to 2000

Code changes
Get rid of my previous quest code. I combined the single, group, and raid flags into one quest function and added a way to manually set a character’s instance flag.

perparser.cpp
insert around line 1758

XS(XS__setinstflag);
XS(XS__setinstflag)
{
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: setinstflag(charID, orginalZoneID, type)");

int32 charID = (int)SvIV(ST(0));
int32 orgZoneID = (int)SvIV(ST(1));
int type = (int)SvIV(ST(2));

quest_manager.setinstflag(charID, orgZoneID, type);

XSRETURN_EMPTY;
}
XS(XS__setinstflagmanually);
XS(XS__setinstflagmanually)
{
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: setinstflagmanually(charID, orginalZoneID, instFlag)");

int32 charID = (int)SvIV(ST(0));
int32 orgZoneID = (int)SvIV(ST(1));
int instFlag = (int)SvIV(ST(2));

quest_manager.setinstflagmanually(charID, orgZoneID, instFlag);

XSRETURN_EMPTY;
}



Perlparser.cpp
Insert at the end around line 1916 (becomes line 1916 after previous insert of code into perparser.cpp)

newXS(strcpy(buf, "setinstflag"), XS__setinstflag, file);
newXS(strcpy(buf, "setinstflagmanually"), XS__setinstflagmanually, file);





questmgr.h
Insert around line 151

void setinstflag(int32 charID, int32 orgZoneID, int type);
void setinstflagmanually(int32 charID, int32 orgZoneID, int instFlag);

questmgr.cpp
Insert at the end

void QuestManager::setinstflag(int32 charID, int32 orgZoneID, int type)
{
if (type == 0)
database.setOneCharInstFlag(charID, orgZoneID);
else if(type == 1)
database.setGroupInstFlagNum(charID, orgZoneID);
else if(type == 2)
database.setRaidInstFlagNum(charID, orgZoneID);
}

void QuestManager::setinstflagmanually(int32 charID, int32 orgZoneID, int instFlag)
{
database.setCharInstFlag(charID, orgZoneID, instFlag);
}


database.cpp
Insert at the end

void Database::setOneCharInstFlag(int32 charID, int32 orgZoneID)
{
int instFlag = getCurInstFlagNum();

// Set character's instZoneFlag
setCharInstFlag(charID, orgZoneID, instFlag);

// Increment the curInstFlagNum
incrCurInstFlagNum(instFlag);

}

void Database::setGroupInstFlagNum(int32 charID, int32 orgZoneID)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int32 groupid = 0;
int instFlag = getCurInstFlagNum();
int numCharsInGroup = 0; // Used to count number of characters in group

// Find out what group the character is in
if (RunQuery(query, MakeAnyLenString(&query, "SELECT groupid from group_id where charid=%i", charID), errbuf, &result)) {
if((row = mysql_fetch_row(result)))
{
if(row[0])
groupid=atoi(row[0]);
}
else
printf("Unable to get group id, char not found!\n");
mysql_free_result(result);
}
else
printf("Unable to get group id: %s\n",errbuf);
safe_delete_array(query);
// Find out how many other characters are in the group
if (RunQuery(query, ("SELECT COUNT(charid) FROM group_id WHERE groupid=%i", groupid), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
if (row && row[0])
{
numCharsInGroup = atoi(row[0]);
mysql_free_result(result);
}
}
// Select the character IDs of the characters in the group
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from group_id where groupid='%i'", groupid), errbuf, &result))
{
int i = 0;
// Set each group members instflag
while ((i <= numCharsInGroup))
{
charID = atoi(row[i]);
setCharInstFlag(charID, orgZoneID, instFlag);
i++;
}
safe_delete_array(query);
mysql_free_result(result);
}
// Increment the curInstFlagNum
incrCurInstFlagNum(instFlag);
}

void Database::setRaidInstFlagNum(int32 charID, int32 orgZoneID)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int32 raidid = 0;
int instFlag = getCurInstFlagNum();
int numCharsInRaid = 0; // Used to count number of characters in raid

// Find out what raid the character is in
if (RunQuery(query, MakeAnyLenString(&query, "SELECT raidid from raid_members where charid=%i", charID), errbuf, &result)) {
safe_delete_array(query);
if((row = mysql_fetch_row(result)))
{
if(row[0])
raidid=atoi(row[0]);
mysql_free_result(result);
}
else
printf("Unable to get raidid, char not found!\n");
mysql_free_result(result);
}
else
printf("Unable to get raid id: %s\n",errbuf);
safe_delete_array(query);
// Find out how many other characters are in the raid
if (RunQuery(query, ("SELECT COUNT(charid) FROM raid_members WHERE raidid=%i", raidid), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
if (row && row[0])
{
numCharsInRaid = atoi(row[0]);
mysql_free_result(result);
}
}
// Select the character IDs of the characters in the raid
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from raid_members where raidid='%i'", raidid), errbuf, &result))
{
int i = 0;
// Set each group members instflag
while ((i <= numCharsInRaid))
{
charID = atoi(row[i]);
setCharInstFlag(charID, orgZoneID, instFlag);
i++;
}
safe_delete_array(query);
mysql_free_result(result);
}
// Increment the curInstFlagNum
incrCurInstFlagNum(instFlag);

}

void Database::incrCurInstFlagNum(int instFlag)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
// Increment the curInstFlagNum
instFlag++;
if (instFlag > 9999)
instFlag = 2000;

if (RunQuery(query, MakeAnyLenString(&query, "UPDATE variables SET value=%i WHERE varname='curInstFlagNum'", instFlag), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else {
cerr << "Error in incrCurInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}

int Database::getCurInstFlagNum()
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int instFlag = 0;

// Get the current instant flag number
if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname = 'curInstFlagNum'"), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
instFlag = atoi(row[0]);
mysql_free_result(result);
return instFlag;
}
else{
mysql_free_result(result);
cerr << "Error in GetCurInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return instFlag;
}

}
else {
cerr << "Error in GetCurInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return instFlag;
}
}
void Database::setCharInstFlag(int32 charID, int32 orgZoneID, int instFlag)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET instZflagNum=%i, instZOrgID=%i WHERE id=%i", instFlag, orgZoneID, charID), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else
{
cerr << "Error in setCharInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}


database.h
Insert at the end

void setOneCharInstFlag(int32 charID, int32 orgZoneID);
void setGroupInstFlagNum(int32 charID, int32 orgZoneID);
void setRaidInstFlagNum(int32 charID, int32 orgZoneID);
void incrCurInstFlagNum(int instFlag);
int getCurInstFlagNum();
void setCharInstFlag(int32 charID, int32 orgZoneID, int instFlag);

cavedude
09-21-2008, 02:34 PM
I haven't had a lot of time to play with this, but it looks like the group and raid types crash the zone when used. This happens whether you are in a group/raid or not. Here is the output:


#0 0x08155ec3 in Database::setGroupInstFlagNum (this=0x836ac24, charID=22,
orgZoneID=223) at /usr/include/stdlib.h:336
#1 0x08248eee in QuestManager::setinstflag (this=0x836a920, charID=1,
orgZoneID=0, type=1) at questmgr.cpp:1572
#2 0x08250883 in XS__setinstflag (my_perl=0x83c6f20, cv=0x8430954)
at perlparser.cpp:2174
#3 0xb79d22dd in Perl_pp_entersub () from /usr/lib/libperl.so.5.8
#4 0xb79d0a8f in Perl_runops_standard () from /usr/lib/libperl.so.5.8
#5 0xb797108e in ?? () from /usr/lib/libperl.so.5.8
#6 0x083c6f20 in ?? ()
#7 0xb7a4f14e in ?? () from /usr/lib/libperl.so.5.8
#8 0x00000000 in ?? ()

Your line numbers will probably differ from mine, so if something doesn't line up, just ask. I can tell you though that questmgr.cpp:1572 is database.setGroupInstFlagNum(charID, orgZoneID);
in my source. The raid dump is the same, just with the raid code. If you want that, just let me know.

Another small problem, /goto doesn't seem to work in instances. The red text pops telling you who you're going to, but you don't actually move. This may be unrelated to your code, but /goto does indeed work in normal zones.

The single player function works perfectly, and the instances themselves from what I can tell work great as well. I had a couple of toons in two instances of the same zone, and the spawns and quests worked great in each instance. No overlapping at all. Very impressive.

Now some suggestions, since your system forces instances to be dynamic (static versions of the zone are ignored, and can only be accessed by players without an instance flag) is there anyway that you can add a rule that will allow server ops to keep the instances open for a certain amount of time after the last player left it? If the op sets the rule to 10 minutes, then the zone stays open for 10 minutes after it became empty of players.

Also, could raid type 2 be changed to flag group members as well? The idea behind this is so we could just set everything to type 2. If a group comes along that aren't in a raid, they can get flagged with this single function instead of having an extra elsif in the script to check for non-raid groups.

Can a variable be added to enable Perl to check if a player is already flagged for an instance? Also, can a new Perl function be added that will delete the flags from a player/group/raid (set both columns to 0?)

Finally, I'm not sure how your system handles this, but what happens to players that join a raid/group after they've been flagged? Can it be made so that they inherit those flags?

Rocker8956
09-21-2008, 04:04 PM
I think I figured out where I messed up the group and raid instance flags. Database::setGroupInstFlagNum and Database::setRaidInstFlagNum will need replaced with the ones below.

Can you post, or send me, the quest script you are using to set these? I suck at quest writing so using yours would help me test them.

I like the idea of holding the zone open for a set amount of time. Also, I agree there needs to be ways to check if someone is already flagged, remove the flag, and inherit the flag of the group/raid leader. I also want to add a way to shutdown the zone after a certain amount of time (like ldons).

The only issue I could see with making the type 2 flag raids or groups is some server admins may want to limit how many people can be in the instance. Though I could make a type 3 that flags both.

It might take me a while to figure out why goto is not working in instances. But I will see.

void Database::setGroupInstFlagNum(int32 charID, int32 orgZoneID)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int32 groupid = 0;
int instFlag = getCurInstFlagNum();
int numCharsInGroup = 0; // Used to count number of characters in group

// Find out what group the character is in
if (RunQuery(query, MakeAnyLenString(&query, "SELECT groupid from group_id where charid=%i", charID), errbuf, &result)) {
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
groupid=atoi(row[0]);
}
else
printf("Unable to get group id, char not found!\n");
mysql_free_result(result);
}
else
printf("Unable to get group id: %s\n",errbuf);
safe_delete_array(query);
// Find out how many other characters are in the group
if (RunQuery(query, ("SELECT COUNT(charid) FROM group_id WHERE groupid=%i", groupid), errbuf, &result)) {
safe_delete_array(query);
row = mysql_fetch_row(result);
numCharsInGroup = atoi(row[0]);
mysql_free_result(result);
}
// Select the character IDs of the characters in the group
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from group_id where groupid='%i'", groupid), errbuf, &result))
{
row = mysql_fetch_row(result);

int i = 0;
// Set each group members instflag
while ((i <= numCharsInGroup))
{
charID = atoi(row[i]);
setCharInstFlag(charID, orgZoneID, instFlag);
i++;
}
safe_delete_array(query);
mysql_free_result(result);
}
// Increment the curInstFlagNum
incrCurInstFlagNum(instFlag);
}



void Database::setRaidInstFlagNum(int32 charID, int32 orgZoneID)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int32 raidid = 0;
int instFlag = getCurInstFlagNum();
int numCharsInRaid = 0; // Used to count number of characters in raid

// Find out what raid the character is in
if (RunQuery(query, MakeAnyLenString(&query, "SELECT raidid from raid_members where charid=%i", charID), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
raidid=atoi(row[0]);
mysql_free_result(result);
}
else
printf("Unable to get raidid, char not found!\n");
mysql_free_result(result);
}
else
printf("Unable to get raid id: %s\n",errbuf);
safe_delete_array(query);
// Find out how many other characters are in the raid
if (RunQuery(query, ("SELECT COUNT(charid) FROM raid_members WHERE raidid=%i", raidid), errbuf, &result)) {
row = mysql_fetch_row(result);
numCharsInRaid = atoi(row[0]);
mysql_free_result(result);
safe_delete_array(query);
}
// Select the character IDs of the characters in the raid
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from raid_members where raidid='%i'", raidid), errbuf, &result))
{
int i = 0;
row = mysql_fetch_row(result);
// Set each group members instflag
while ((i <= numCharsInRaid))
{
charID = atoi(row[i]);
setCharInstFlag(charID, orgZoneID, instFlag);
i++;
}
safe_delete_array(query);
mysql_free_result(result);
}
// Increment the curInstFlagNum
incrCurInstFlagNum(instFlag);
}

trevius
09-21-2008, 04:40 PM
Actually, why not just make an option to keep all dynamic zones up for X amount of time after the last player leaves? I wouldn't mind having that for my dynamic zones as well :)

cavedude
09-24-2008, 02:24 PM
I'm not going to sticky this one yet, I am still getting a zone crash with the newest code regarding the raid and group types. Could you post a diff to make sure I am not merging incorrectly?

Rocker8956
09-25-2008, 03:00 AM
I am fairly certainly you are merging it correctly. I just screwed up the code. Here are two I found this afternoon that need changed. Basically I had ‘%i’ when it should be %i
It is kinda hard to see but the %i is surrounded by two ‘

I will try to post a full diff by this weekend. I would do it sooner but work is killing me this week.

line 31 inside Database::setGroupInstFlagNum

// Select the character IDs of the characters in the group
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from group_id where groupid=%i", groupid), errbuf, &result))



line 33 inside Database::setRaidInstFlagNum

// Select the character IDs of the characters in the raid
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from raid_members where raidid=%i", raidid), errbuf, &result))



One side question though. Please don’t laugh to hard (this is my first time writing a quest) below is what I wrote for a quest to set these instance flags. It does not work. I know the quest::setinstflag($charid,18,0); is causing the problem since the says work. It never sets the flags in the database and just hangs at the setinstflag. I figured out it hangs there by swapping the quest::say and quest::setinstflag places. Any idea where I messed up the script? or is my code that wrong?

sub EVENT_SAY {
$charid = 0;
$charid = $client->CharacterID();
if($text=~/Hail/i){
quest::say("Greetings traveler, Do you want to go play in Blackburrow?"); }
if($text=~/yes/i){
quest::say("Oh wonderful! Do you want to play by yourself, in a group, or in a raid?"); }
if($text=~/self/i){
quest::say("You can now go play in your own little Blackburrow world.");
quest::setinstflag($charid,17,0); }
if($text=~/group/i){
quest::say("Your party can now go play in their own little Blackburrow world.");
quest::setinstflag($charid,17,1); }
if($text=~/raid/i){
quest::say("Your raid can now go play in their only little Blackburrow world.");
quest::setinstflag($charid,17,2); }
if($text=~/setme/i){
quest::say("Okay then GO PLAY!!!");
quest::setinstflagmanually($charid,17,1500); }
}

Andrew80k
09-25-2008, 10:14 AM
Your quest script is fine. It's your code that you use to call setinstflag that's messed up. I'd put some debug statements in there and try to figure out where it's giving you grief. I've REALLY been wanting to mess around with this but I'm so limited on time right now....

joligario
09-25-2008, 01:24 PM
Just out of curiosity, why are they int32 variables instead of just int? Could that make a difference when compiling between the different machines? Does it make a difference compiling on the different machines when typecasting an int -> int32?

Rocker8956
09-26-2008, 07:06 PM
Well I got it working. I will try to post a diff tonight or tomorrow. The quest functions got an overhaul.

Just out of curiosity, why are they int32 variables instead of just int? Could that make a difference when compiling between the different machines? Does it make a difference compiling on the different machines when typecasting an int -> int32?


I think most programming languages view int and int32 as the same thing. However, I took your suggestion and changed most of the int32 to int. Looks better and is easier to read even if it has little to no effect on the code.

AndMetal
09-26-2008, 07:23 PM
Just out of curiosity, why are they int32 variables instead of just int? Could that make a difference when compiling between the different machines? Does it make a difference compiling on the different machines when typecasting an int -> int32?

To understand int32, we need to look at common/types.h (http://eqemulator.cvs.sourceforge.net/eqemulator/EQEmuCVS/Source/common/types.h?view=markup):

typedef unsigned char int8;
typedef unsigned char byte;
typedef unsigned short int16;
typedef unsigned int int32;

typedef unsigned char uint8;
typedef signed char sint8;
typedef unsigned short uint16;
typedef signed short sint16;
typedef unsigned int uint32;
typedef signed int sint32;

As I understand (http://www.cplusplus.com/doc/tutorial/variables.html), int in C++ assumes signed by default on most compilers:
By default, if we do not specify either signed or unsigned most compiler settings will assume the type to be signed
You can certainly use int for 32-bit signed integers, but by using sint32 instead, you don't have to worry about compiler-specific assumptions, plus it can be easier to understand just browsing through the source.

Rocker8956
09-26-2008, 07:44 PM
Thanks AndMetal, I honestly didn’t know which method was preferred. Sorry, I don’t have the energy at the moment to switch the int and int32s around. Though I did learn something and now know in the future.

Here is a diff of all the required code. Hopefully I got it all.
With this the only required manual database entry is setting the zone insttype to 1.

Required SQL

ALTER TABLE `zone` ADD column `insttype` tinyint (1) zerofill unsigned NOT NULL default '0';
ALTER TABLE character_ ADD column `instZflagNum` int(10) unsigned NOT NULL default '0';
ALTER TABLE character_ ADD column `instZOrgID` int(11) NOT NULL default '0';
INSERT INTO variables VALUES ('curInstFlagNum', 2000, 'Determines what instance flag will be handed out next', '2008-09-05 04:46:47');
INSERT INTO variables VALUES ('dfltInstZflag',1000, 'Used to determine if a zone is instanced, must be 1000 or greater', '2008-09-05 04:46:47');


World\Zoneserver.cpp
Line 498 insert

ztz->requested_zone_id = database.GetInstZoneID(ztz->requested_zone_id, ztz->name);

Line 508-509 insert

int server_id;
ztz->requested_zone_id = database.GetInstZoneID(ztz->requested_zone_id, ztz->name);
if ((server_id = zoneserver_list.TriggerBootup(ztz->requested_zone_id)))

World\Zoneserver.cpp
Line 533 insert

zlog(WORLD__ZONE,"Processing ZTZ for ingress to zone for client %s\n", ztz->name);
ztz->current_zone_id = database.GetInstZoneID(ztz->current_zone_id, ztz->name); //Rocker8956 possible fix for wrong zone shutdown
ZoneServer *egress_server = zoneserver_list.FindByZoneID(ztz->current_zone_id);



World\Client.cpp
Line 644 insert

zoneID = database.GetInstZoneID(zoneID, GetCharName());


Zone\zoning.cpp
Line 122

//Checks if the zone can be instanced, character has a instance flag, and
//that the character is not zoning into an instance that is already loaded
if(database.GetInstType(target_zone_id) == 1){
int32 characterID = database.GetCharacterID(zc->char_name);
int32 instFlagNum = database.GetCharInstFlagNum(characterID);
if(instFlagNum >= database.GetDfltInstZFlag())
{
int32 charInstZOrgID = database.GetCharInstZOrgID(characterID);
// If instance flag matches then...
if(charInstZOrgID == target_zone_id)
{
//If instance zone is not in database then it is copied to database
if(!database.InstZoneLoaded(instFlagNum)) {
database.LoadInstZone(target_zone_id, instFlagNum);
}
target_zone_id = instFlagNum;
}
}
}


Common\database.h
Line 201 insert

int32 GetCharInstFlagNum(int32 charID);
int32 GetCharInstZOrgID(int32 charID);
int32 GetInstZoneID(int32 zoneID, const char* charName);
void DeleteInstZone(int32 instZoneID);
int32 GetDfltInstZFlag();
void setCharInstFlag(int charID, int orgZoneID, int instFlag);
void setGroupInstFlagNum(int charID, int orgZoneID, int instFlag);
void setRaidInstFlagNum(int charID, int orgZoneID, int instFlag);
void incrCurInstFlagNum(int instFlag);
int getCurInstFlagNum();


Common\database.cpp Replace Database::GetZoneName
Around Line 1173

const char* Database::GetZoneName(int32 zoneID, bool ErrorUnknown) {
if (zonename_array == 0) {
if (ErrorUnknown)
return "UNKNOWN";
else
return 0;
}
if (zoneID > GetDfltInstZFlag())
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZOrgID FROM character_ WHERE instZflagNum=%i", zoneID), errbuf, &result)) {
safe_delete_array(query);
if (mysql_num_rows(result) > 0) {
row = mysql_fetch_row(result);
int8 tmp = atoi(row[0]);
mysql_free_result(result);
return zonename_array[tmp];
}
mysql_free_result(result);
}
else
{
cerr << "Error in instZOrgID query in database.cpp GetZoneName'" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}
else if (zoneID <= max_zonename) {
if (zonename_array[zoneID])
return zonename_array[zoneID];
else {
if (ErrorUnknown)
return "UNKNOWN";
else
return 0;
}
}
else {
if (ErrorUnknown)
return "UNKNOWN";
else
return 0;
}
}

End of Common\database.cpp insert

int32 Database::GetDfltInstZFlag(){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname = 'dfltInstZflag'"), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
int32 tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;
}
mysql_free_result(result);
}

else {
cerr << "Error in GetDfltInstZFlag query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}
int32 Database::GetCharInstFlagNum(int32 charID){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZflagNum FROM character_ WHERE id=%i", charID), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
int tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;
}
mysql_free_result(result);
}
else {
cerr << "Error in GetCharInstFlag Numquery '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}

int32 Database::GetCharInstZOrgID(int32 charID){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
if (RunQuery(query, MakeAnyLenString(&query, "SELECT instZOrgID FROM character_ WHERE id=%i", charID), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
int32 tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;

}
mysql_free_result(result);
}
else {
cerr << "Error in GetInstType query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}
int32 Database::GetInstZoneID(int32 zoneID, const char* charName) {
if (zoneID == 0)
return 0;
int32 charID = GetCharacterID(charName);
if (zoneID == GetCharInstZOrgID(charID))
{
zoneID = GetCharInstFlagNum(charID);
return zoneID;
}
else
return (zoneID);
}

void Database::DeleteInstZone(int32 instZoneID)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
if (RunQuery(query, MakeAnyLenString(&query, "DELETE FROM zone WHERE zoneidnumber=%i", instZoneID), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else {
cerr << "Error in DeleteInstZone query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}
//Rocker8956
void Database::setGroupInstFlagNum(int charID, int orgZoneID, int instFlag)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int groupid = 0;

// Find out what group the character is in
if (RunQuery(query, MakeAnyLenString(&query, "SELECT groupid from group_id where charid=%i", charID), errbuf, &result))
{
if (mysql_num_rows(result) == 1)
{
row = mysql_fetch_row(result);
groupid=atoi(row[0]);
mysql_free_result(result);
safe_delete_array(query);
// Select the character IDs of the characters in the group
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid FROM group_id WHERE groupid=%i", groupid), errbuf, &result))
{
while((row = mysql_fetch_row(result)))
{
charID = atoi(row[0]);
setCharInstFlag(charID, orgZoneID, instFlag);
Sleep(0);
}
safe_delete_array(query);
mysql_free_result(result);
}
}
else
{
printf("Unable to get group id, char not found!\n");
mysql_free_result(result);
safe_delete_array(query);
}
}
else
{
printf("Unable to get group id: %s\n",errbuf);
mysql_free_result(result);
safe_delete_array(query);
}

}

void Database::setRaidInstFlagNum(int charID, int orgZoneID, int instFlag)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int raidid = 0;

// Find out what raid the character is in
if (RunQuery(query, MakeAnyLenString(&query, "SELECT raidid from raid_members where charid=%i", charID), errbuf, &result))
{
if (mysql_num_rows(result) == 1)
{
row = mysql_fetch_row(result);
raidid=atoi(row[0]);
mysql_free_result(result);
safe_delete_array(query);
// Select the character IDs of the characters in the raid
if (RunQuery(query, MakeAnyLenString(&query, "SELECT charid from raid_members where raidid=%i", raidid), errbuf, &result))
{
while((row = mysql_fetch_row(result)))
{
charID = atoi(row[0]);
setCharInstFlag(charID, orgZoneID, instFlag);
Sleep(0);
}
safe_delete_array(query);
mysql_free_result(result);
}
}
}
else
{
printf("Unable to get raid id: %s\n",errbuf);
mysql_free_result(result);
safe_delete_array(query);
}
}

void Database::incrCurInstFlagNum(int instFlag)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
// Increment the curInstFlagNum
instFlag++;
if (instFlag > 9999)
instFlag = 2000;

if (RunQuery(query, MakeAnyLenString(&query, "UPDATE variables SET value=%i WHERE varname='curInstFlagNum'", instFlag), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else
{
cerr << "Error in incrCurInstFlagNum query '" << query << "' " << errbuf << endl;
mysql_free_result(result);
safe_delete_array(query);
}
}

int Database::getCurInstFlagNum()
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int instFlag = 0;

// Get the current instant flag number
if (RunQuery(query, MakeAnyLenString(&query, "SELECT value FROM variables WHERE varname = 'curInstFlagNum'"), errbuf, &result))
{

if (mysql_num_rows(result) == 1)
{
row = mysql_fetch_row(result);
instFlag = atoi(row[0]);
mysql_free_result(result);
safe_delete_array(query);
return instFlag;
}
else
{
cerr << "Error in GetCurInstFlagNum query '" << query << "' " << errbuf << endl;
mysql_free_result(result);
safe_delete_array(query);
return instFlag;
}

}
else
{
cerr << "Error in GetCurInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
return instFlag;
}
}
void Database::setCharInstFlag(int charID, int orgZoneID, int instFlag)
{
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (RunQuery(query, MakeAnyLenString(&query, "UPDATE character_ SET instZflagNum=%i, instZOrgID=%i WHERE id=%i", instFlag, orgZoneID, charID), errbuf, &result))
{
safe_delete_array(query);
mysql_free_result(result);
}
else
{
cerr << "Error in setCharInstFlagNum query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}


Zone\zonedb.cpp
Append to the end

int32 ZoneDatabase::GetInstType(int32 zoneid) {
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (RunQuery(query, MakeAnyLenString(&query, "SELECT insttype FROM zone WHERE zoneidnumber=%i", zoneid), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
row = mysql_fetch_row(result);
int8 tmp = atoi(row[0]);
mysql_free_result(result);
return tmp;

}
mysql_free_result(result);
}

else {
cerr << "Error in GetInstType query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}
bool ZoneDatabase::InstZoneLoaded(int32 charInstFlagNum){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

if (RunQuery(query, MakeAnyLenString(&query, "SELECT zoneidnumber FROM zone WHERE zoneidnumber=%i", charInstFlagNum), errbuf, &result))
{
safe_delete_array(query);
if (mysql_num_rows(result) == 1) {
return true;
}
else if (mysql_num_rows(result) == 0) {
return false;
}
mysql_free_result(result);
}

else {
cerr << "Error in isInstZoneLoad query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
return 0;
}


//Copies original zones information into a new zone entry replacing the old zoneidnumber with the instflagnum
void ZoneDatabase::LoadInstZone(int32 target_zone_ID, int32 instFlagNum){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int32 affected_rows = 0;
string tmpzonename = database.GetZoneName(target_zone_ID);
string temp;
const char* temp2;
stringstream tmpFlag; // used for converting int32 instFlagNum to a string

tmpFlag << instFlagNum;
temp = tmpFlag.str();
temp.append(tmpzonename);
temp2 = temp.c_str();

if (RunQuery(query, MakeAnyLenString(&query, "INSERT INTO zone (short_name, file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, zoneidnumber, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer) SELECT '%s', file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, %i, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer FROM zone WHERE zoneidnumber =%i", temp2,instFlagNum,target_zone_ID), errbuf, 0, &affected_rows)){
safe_delete_array(query);}
else {
cerr << "Error in LoadInstZone query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}
}


Zone\zoneDB.cpp line 13 insert

#include <string>
#include <sstream>



Zone\zonedb.h
line 194 change const char* zone_name to int32 zoneid

bool PopulateZoneSpawnList(int32 zoneid, LinkedList<Spawn2*> &spawn2_list, int32 repopdelay = 0);


Zone\Zonedb.h
At the end of Zone Related around line 181

int32 GetInstType(int32 zoneid);
bool InstZoneLoaded(int32 target_zone_ID);
void LoadInstZone(int32 target_zone_ID, int32 InstFlagNum);



Zone.cpp Line 1146 change short_name to zoneid

if (!database.PopulateZoneSpawnList(zoneid, spawn2_list, delay))


Zone.cpp Line 779 change short_name to zoneid

if (!database.PopulateZoneSpawnList(zoneid, spawn2_list))



Zone.cpp Line 772 change short_name to zoneid

else if (tmp == 0) {
LogFile->write(EQEMuLog::Status, "No state saved, loading spawn2 points...");
if (!database.PopulateZoneSpawnList(zoneid, spawn2_list))
return false;
}


Zone\Zone.cpp line 616 bottom of Zone::Shutdown insert

zone->ResetAuth();
if (zone->GetZoneID() > database.GetDfltInstZFlag()){
database.DeleteInstZone(zone->GetZoneID());
}
safe_delete(zone);
dbasync->CommitWrites();
UpdateWindowTitle();



Zone\spawn2.cpp line 226

bool ZoneDatabase::PopulateZoneSpawnList(int32 zoneid, LinkedList<Spawn2*> &spawn2_list, int32 repopdelay) {
char errbuf[MYSQL_ERRMSG_SIZE];
char* query = 0;
MYSQL_RES *result;
MYSQL_ROW row;

const char *zone_name = database.GetZoneName(zoneid);
int32 dfltInstZFlag = database.GetDfltInstZFlag();

MakeAnyLenString(&query, "SELECT id, spawngroupID, x, y, z, heading, respawntime, variance, pathgrid, timeleft, _condition, cond_value FROM spawn2 WHERE zone='%s'", zone_name);

if (RunQuery(query, strlen(query), errbuf, &result))
{
safe_delete_array(query);
while((row = mysql_fetch_row(result)))
{
Spawn2* newSpawn = 0;
if (zoneid > dfltInstZFlag){
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]), 0, atoi(row[8]), atoi(row[10]), atoi(row[11]));
}
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]), atoi(row[10]), atoi(row[11]));
}
//newSpawn->Repop(repopdelay);
spawn2_list.Insert( newSpawn );
}
mysql_free_result(result);
}
else
{
LogFile->write(EQEMuLog::Error, "Error in PopulateZoneLists query '%s': %s", query, errbuf);
safe_delete_array(query);
return false;
}

return true;
}


Zone\perlparser.cpp
Insert at the end around line 1884

newXS(strcpy(buf, "setinstflag"), XS__setinstflag, file);
newXS(strcpy(buf, "setinstflagmanually"), XS__setinstflagmanually, file);



Zone\perparser.cpp
insert around line 1758

XS(XS__setinstflag);
XS(XS__setinstflag)
{
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: setinstflag(charID, orginalZoneID, type)");

int charID = (int)SvIV(ST(0));
int orgZoneID = (int)SvIV(ST(1));
int type = (int)SvIV(ST(2));

quest_manager.setinstflag(charID, orgZoneID, type);

XSRETURN_EMPTY;
}
XS(XS__setinstflagmanually);
XS(XS__setinstflagmanually)
{
dXSARGS;
if (items != 3)
Perl_croak(aTHX_ "Usage: setinstflagmanually(charID, orginalZoneID, instFlag)");

int charID = (int)SvIV(ST(0));
int orgZoneID = (int)SvIV(ST(1));
int instFlag = (int)SvIV(ST(2));

quest_manager.setinstflagmanually(charID, orgZoneID, instFlag);

XSRETURN_EMPTY;
}





Zone\questmgr.h
Insert around line 151

void setinstflag(int charID, int orgZoneID, int type);
void setinstflagmanually(int charID, int orgZoneID, int instFlag);


Zone\questmgr.cpp
Insert at the end

void QuestManager::setinstflag(int charID, int orgZoneID, int type)
{
int instFlag = database.getCurInstFlagNum();

if (type == 0)
{
database.setCharInstFlag(charID, orgZoneID, instFlag);
database.incrCurInstFlagNum(instFlag); // Increment the curInstFlagNum
}
else if(type == 1)
{
database.setGroupInstFlagNum(charID, orgZoneID, instFlag);
database.incrCurInstFlagNum(instFlag); // Increment the curInstFlagNum
}
else if(type == 2)
{
database.setRaidInstFlagNum(charID, orgZoneID, instFlag);
database.incrCurInstFlagNum(instFlag); // Increment the curInstFlagNum
}
else if(type == 3)
{
database.setCharInstFlag(charID, orgZoneID, instFlag);
database.setGroupInstFlagNum(charID, orgZoneID, instFlag);
database.setRaidInstFlagNum(charID, orgZoneID, instFlag);
database.incrCurInstFlagNum(instFlag); // Increment the curInstFlagNum
}
}

void QuestManager::setinstflagmanually(int charID, int orgZoneID, int instFlag)
{
say("Got to start of setinstflagmanually");
database.setCharInstFlag(charID, orgZoneID, instFlag);
}


Simple quest script to go with all this code.


sub EVENT_SAY {
$charid = 0;
$charid = $client->CharacterID();
if($text=~/Hail/i){
quest::say("Greetings traveler, Do you want to go play in Blackburrow?"); }
if($text=~/yes/i){
quest::say("Oh wonderful! Do you want to play by yourself, in a group, or in a raid?"); }
if($text=~/self/i){
quest::setinstflag($charid,17,0);
quest::say("You can now go play in your own little Blackburrow world."); }
if($text=~/group/i){
quest::say("Your party can now go play in their own little Blackburrow world.");
quest::setinstflag($charid,17,1); }
if($text=~/raid/i){
quest::say("Your raid can now go play in their only little Blackburrow world.");
quest::setinstflag($charid,17,2); }
if($text=~/guess/i){
quest::say("Your flags are set you can now go play in a Blackburrow world.");
quest::setinstflag($charid,17,3); }
if($text=~/manually/i){
quest::say("Okay your flag is set.");
quest::setinstflagmanually($charid,17,1500); }
}

Let me know if I missed something. I am going to go drink some beer.

joligario
09-26-2008, 08:14 PM
In your questmgr.cpp you might have some leftover debug code.

say("Got to start of setinstflagmanually");

Rocker8956
09-26-2008, 08:26 PM
Oops, your right. Good catch.

Zone\questmgr.cpp
at the end QuestManager::setinstflagmanually should be

void QuestManager::setinstflagmanually(int charID, int orgZoneID, int instFlag)
{
database.setCharInstFlag(charID, orgZoneID, instFlag);
}

Rocker8956
09-29-2008, 04:20 PM
Anyone have a chance over the weekend to test this out? I would like to get this portion tested before I add some other features.

One thing I noticed while testing it on my minilogin server: Using two characters from the same account in an instance causes one to get disconnected when the other zones out of the instance. I think this is related to how the client/emu interact and likely cannot be fixed since Sony intended only one character to be logged in on the same account at a time. Though, I do not know if this problem would occur on a public server.

Below are some things I want to implement once this code is tested.

Quest function to delete instance flags (reset them to zero)
Fix goto command so it works in instances
Quest function to get the average level of a group and raid
Hold dynamic and instance zones open for a set period of time.

There is probably already a short timer in the code that is triggered when a zone becomes empty so I will just need to find it and allow the time to be set from a database entry.

I had more but cannot remember them at the moment.

cavedude
09-29-2008, 04:26 PM
I didn't actually test the instances (though they worked for me earlier) However, I can confirm all the types flag me properly and don't cause a crash anymore. Nice work!

Rocker8956
09-30-2008, 08:26 PM
Yep more changes.

This is a fix for setinstflagmanually to allow manual flagging of raids, groups, and individuals. This also offers a way to delete instance flags by sending a orgZoneID of -1 and a instFlag of -1 to the function.

Please note if you have already setup quests to use the setinstflagmanually you will need to add a fourth parameter to it.

Format for quests - setinstflagmanually(charID, orginalZoneID, instFlag, type)

types
0 = individual
1 = group
2 = raid
3 = individual, group, and raid

Zone\perlparser.cpp
Find XS(XS__setinstflagmanually) replace with below code
(line is 1774 on mine but..)

XS(XS__setinstflagmanually);
XS(XS__setinstflagmanually)
{
dXSARGS;
if (items != 4)
Perl_croak(aTHX_ "Usage: setinstflagmanually(charID, orginalZoneID, instFlag, type)");

int charID = (int)SvIV(ST(0));
int orgZoneID = (int)SvIV(ST(1));
int instFlag = (int)SvIV(ST(2));
int type = (int)SvIV(ST(3));

quest_manager.setinstflagmanually(charID, orgZoneID, instFlag, type);

XSRETURN_EMPTY;
}


zone\questmgr.cpp
Find void QuestManager::setinstflagmanually and replace with below code
(line 1420 on mine)

void QuestManager::setinstflagmanually(int charID, int orgZoneID, int instFlag, int type)
{
if (type == 0)
{
database.setCharInstFlag(charID, orgZoneID, instFlag);
}
else if(type == 1)
{
database.setGroupInstFlagNum(charID, orgZoneID, instFlag);
}
else if(type == 2)
{
database.setRaidInstFlagNum(charID, orgZoneID, instFlag);
}
else if(type == 3)
{
database.setCharInstFlag(charID, orgZoneID, instFlag);
database.setGroupInstFlagNum(charID, orgZoneID, instFlag);
database.setRaidInstFlagNum(charID, orgZoneID, instFlag);
}
}

zone\questmgr.h
Find void setinstflagmanually and replace with below code
(line 151 on mine)

void setinstflagmanually(int charID, int orgZoneID, int instFlag, int type);

Rocker8956
10-16-2008, 02:47 PM
Some thoughts…
//Copies original zones information into a new zone entry replacing the old zoneidnumber with the instflagnum
void ZoneDatabase::LoadInstZone(int32 target_zone_ID, int32 instFlagNum){
char errbuf[MYSQL_ERRMSG_SIZE];
char *query = 0;
MYSQL_RES *result;
MYSQL_ROW row;
int32 affected_rows = 0;
string tmpzonename = database.GetZoneName(target_zone_ID);
string temp;
const char* temp2;
stringstream tmpFlag; // used for converting int32 instFlagNum to a string

tmpFlag << instFlagNum;
temp = tmpFlag.str();
temp.append(tmpzonename);
temp2 = temp.c_str();

if (RunQuery(query, MakeAnyLenString(&query, "INSERT INTO zone (short_name, file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, zoneidnumber, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer) SELECT '%s', file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, %i, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer FROM zone WHERE zoneidnumber =%i", temp2,instFlagNum,target_zone_ID), errbuf, 0, &affected_rows)){
safe_delete_array(query);}
else {
cerr << "Error in LoadInstZone query '" << query << "' " << errbuf << endl;
safe_delete_array(query);
}

The section of code in red bothers me because every time the zone table's columns change it will need updated. Anyone have a better method for copying one zones info and inserting it back into the database changing only the zonename and zoneidnumber? We may be able to simply eliminate this copy/paste as long as the code always queries the database based on the original zone id not the instance zone id.

(The shutdowndelay column needs added, I will add it tonight or tomorrow)

Also, I am reluctant to enable inheriting of instance flags in groups and raids because it may allow players to circumvent zone limitations. For example,

Group zones into an LDoN
1 member drops out of the group but stays in the LDoN
The group then invites another character.
He/she zones into the LDoN (because he/she now has the flag)
Now 7 characters are in the zone when the content was built for 6.

To keep players from doing this we would either have to boot them from the instance when they disband or have a hidden NPC check the zone every few minutes for players without the correct instance flag.
Any thoughts?

Another side note, I may have a fix for the goto command but I need to test it.

ChaosSlayer
10-16-2008, 03:07 PM
tecnicly speaking on LIVE after you zoned into LDON and someone Lds, camps, crashes etc- you CANNOT invite someone else from outside- the zone should remain LOCKED until adventure expires or forfeit, even if group inside got smaller

Rocker8956
10-17-2008, 02:10 PM
Fix to include shutdowndelay column in zone copy

zone\zonedb.cpp
Find ZoneDatabase::LoadInstZone(int32 target_zone_ID, int32 instFlagNum)

Replace Line 17 inside the function (line 1542 for whole file (Rev98 ))


if (RunQuery(query, MakeAnyLenString(&query, "INSERT INTO zone (short_name, file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, zoneidnumber, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer) SELECT '%s', file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, %i, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer FROM zone WHERE zoneidnumber =%i", temp2,instFlagNum,target_zone_ID), errbuf, 0, &affected_rows)){
With
if (RunQuery(query, MakeAnyLenString(&query, "INSERT INTO zone (short_name, file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, zoneidnumber, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer, shutdowndelay) SELECT '%s', file_name, long_name, safe_x, safe_y, safe_z, graveyard_id, min_level, min_status, %i, timezone, maxclients, weather, note, underworld, minclip, maxclip, fog_minclip, fog_maxclip, fog_blue, fog_red, fog_green, sky, ztype, zone_exp_multiplier, walkspeed, time_type, fog_red1, fog_green1, fog_blue1, fog_minclip1, fog_maxclip1, fog_red2, fog_green2, fog_blue2, fog_minclip2, fog_maxclip2, fog_red3, fog_green3, fog_blue3, fog_minclip3, fog_maxclip3, fog_red4, fog_green4, fog_blue4, fog_minclip4, fog_maxclip4, flag_needed, canbind, cancombat, canlevitate, castoutdoor, insttype, insttimer, shutdowndelay FROM zone WHERE zoneidnumber =%i", temp2,instFlagNum,target_zone_ID), errbuf, 0, &affected_rows)){

Hopefully we can find a way to copy the zone info without needing to update this query everytime the zone table changes.

ChaosSlayer, I think you are right about the LDoNs. Everyone had to be in the group before the LDoN task was accepted or they could not get into the zone. Though, I think GoD and OoW instances flags could be shared via the share task button.

Rezbee
02-04-2009, 01:18 AM
Thought I'd add... With the instancing ability we need to add a new check to the /goto <playername> command so it will check the characters_ table and replicate any instance flags on the GM before zoning. That way if someone is stuck in the geometry or bugged death or whatever a GM can zone into that instance and check.

drakelord
04-12-2009, 02:04 PM
Thought I'd add... With the instancing ability we need to add a new check to the /goto <playername> command so it will check the characters_ table and replicate any instance flags on the GM before zoning. That way if someone is stuck in the geometry or bugged death or whatever a GM can zone into that instance and check.

Has this been accomplished yet?