|
|
 |
 |
 |
 |
|
 |
 |
|
 |
 |
|
 |
|
 |
|
 |

09-17-2008, 10:24 AM
|
Hill Giant
|
|
Join Date: Sep 2007
Posts: 117
|
|
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
Code:
newXS(strcpy(buf, "setgroupinstflag"), XS__setgroupinstflag, file);
zone\perparser.cpp
insert around line 1758
Code:
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
Code:
void setgroupinstflag(int32 charID, int32 orgZoneID);
zone\questmgr.cpp
Insert at the end
Code:
void QuestManager::setgroupinstflag(int32 charID, int32 orgZoneID)
{
database.setGroupInstFlagNum(charID, orgZoneID);
}
common\database.cpp
Insert at the end
Code:
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
Code:
void setGroupInstFlagNum(int32 charID, int32 orgZoneID);
|
 |
|
 |
 |
|
 |

09-19-2008, 07:30 PM
|
Hill Giant
|
|
Join Date: Sep 2007
Posts: 117
|
|
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
Code:
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
Code:
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)
Code:
newXS(strcpy(buf, "setinstflag"), XS__setinstflag, file);
newXS(strcpy(buf, "setinstflagmanually"), XS__setinstflagmanually, file);
questmgr.h
Insert around line 151
Code:
void setinstflag(int32 charID, int32 orgZoneID, int type);
void setinstflagmanually(int32 charID, int32 orgZoneID, int instFlag);
questmgr.cpp
Insert at the end
Code:
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
Code:
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
Code:
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);
|
 |
|
 |
 |
|
 |

09-21-2008, 02:34 PM
|
 |
The PEQ Dude
|
|
Join Date: Apr 2003
Location: -
Posts: 1,988
|
|
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:
Code:
#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?
Last edited by cavedude; 09-21-2008 at 10:42 PM..
|
 |
|
 |
 |
|
 |

09-21-2008, 04:04 PM
|
Hill Giant
|
|
Join Date: Sep 2007
Posts: 117
|
|
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.
Code:
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);
}
Code:
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);
}
|
 |
|
 |

09-21-2008, 04:40 PM
|
 |
Developer
|
|
Join Date: Aug 2006
Location: USA
Posts: 5,946
|
|
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 
|

09-24-2008, 02:24 PM
|
 |
The PEQ Dude
|
|
Join Date: Apr 2003
Location: -
Posts: 1,988
|
|
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?
|
 |
|
 |

09-25-2008, 03:00 AM
|
Hill Giant
|
|
Join Date: Sep 2007
Posts: 117
|
|
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
Code:
// 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
Code:
// 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?
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::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); }
}
|
 |
|
 |
Posting Rules
|
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts
HTML code is Off
|
|
|
All times are GMT -4. The time now is 03:35 PM.
|
|
 |
|
 |
|
|
|
 |
|
 |
|
 |