Log in

View Full Version : Handin plugin confusion...


Kagehi
03-11-2008, 03:00 PM
Still don't have a server up and working, but been playing around on PEQ. I noticed things going wrong in one area, so decided to see what it would take to patch in the check_handin function to them, and in the process, try to figure out what the heck it does and how. I think I have a good grasp of it now, but I have two questions:

1. itemcount - is this being passed as a reference or a table? Regardless of which, does it automatically "unstack" items, or does it leave them stacked in a keyed table?

2. I noticed that the code in the plugin, as written, can't handle stuff like "1234 => 3". It will only look at the index key, not the *value*, when checking if it found an item, and determining if it was a success. This is a) imho stupid, and b) something they fixed in live, like two years ago, within probably less than 1-2 months before I stopped playing. While I suppose its sort of amusing seeing the problem appear in EQEmu too, its also annoying.

Needless to say, fixing this relies on what the answer to #1 is, and its not going to be as simple as just checking item numbers and hoping that the coder knew to explicitly ask for one item 2 times, instead of one items, of which you need 2. I.e. '1234 => 1, 1234 => 1' vs. '1234 => 2'. I see absolutely no way how the later, which is valid when doing a straight check, would work at all, when calling plugin:check_handin. If itemcount just returns a table, in the way its being passed, which shows the item, and how many where stacked, not separate items, then this is broken on both ends. If its passing a reference, then this is a bit easier, since one could just ask it, presumably, "How many of these are there, really, and does it match the number actually requested?" In fact, that method is hundreds of times preferable imho.

Sorry, but I just get nit picky about stuff like this. lol

Kagehi
03-11-2008, 05:33 PM
Ok. Did some tests in a nice text based client, which supports Perlscript. After some nightmares trying to figure out why it wasn't working, I got these results:


Looking for Found Result
---------- ------ ------
1234 => 1 1234 => 4 Fail
1234 => 4 1234 => 1 Fail
1234 => 1 1234 => 1 Success

This is obviously not as bad as I was expecting, but it still means that you can't, for example, ask for 1234 => 2, and have someone give you '1234 => 1, 1234 => 1'. Its not testing how many you have, just if the hashes are exact matches, with both the keys *and* the values. This is flawed imho, even if it does prevent huge errors.

AndMetal
03-11-2008, 05:57 PM
I think this all has to do with how the items are read.

If I'm not mistaken (one would have to look through the source to confirm), the server finds out what the Item IDs are for each slot & stores them as $item1, $item2, $item3, & $item4. Then, an array (table) is created from that info: %itemcount. I assume the logic is something like this:


%itemcount{$item1}++;
%itemcount{$item2}++;
%itemcount{$item3}++;
%itemcount{$item4}++;


That way, if you hand in 2 of the items, it increments the key, which is the Item ID, by 1.

I agree, the "better" way to do this is to do something like this:


%itemcount{%item1{id}} += %itemcount{%item1{stacksize}};
%itemcount{%item2{id}} += %itemcount{%item2{stacksize}};
%itemcount{%item3{id}} += %itemcount{%item3{stacksize}};
%itemcount{%item4{id}} += %itemcount{%item4{stacksize}};


That way, you can stack items AND have them ALL count for the quest.

However, the issue then becomes backwards compatibility. I would think the best way to handle that would be to keep $item1-4 as is, and change just %itemcount to handle the new logic.

Anyone up for digging through the source code?

Kagehi
03-12-2008, 04:27 AM
Well. Truth is, the code for handin is just broken. The return code does, sort of, what it *should be* doing. Handin does: "For every key+value in what I was given, is there an *identical* key+value in what I need?" No attempt is made to check if its the right item, but you just have too many. Item_return does: "For every key in what I am given, start with 0 items, and increment until I exceed the *value* of that key."

The code needed for handin is kind of more complicated though. It needs to combine its "did it exist at all", with its, "is it a match or not", parts, so that you do something like:

for every KEY in what I want do
Is there a key in what I was given that matches?
yes - is the value > than, = to, or < than what I need?
if equal, delete both keys and continue.
if >, then delete the hash key and decrease the given one by the hashes value.
if <, then delete the given key, subtracting its value from the hash, and return to step 2.
no - exit with fail.

When you run out of keys and values in the hash, you pass what ever is *left* of the given items to return_items.

The existing code works perfectly, as long as you don't turn in stacks, or your stacks are the *exact* size passed to the test, but otherwise, it just doesn't work as written.

Theeper
03-12-2008, 11:57 AM
Maybe you have an old version of the check_handin.pl, this version from PEQ works fine for me. It does check for more than one item at a time.

AFAIK, you can't pass stacked items to NPCs on the emu or on Live though.


# plugin::check_handin($item1 => #required_amount,...);
# autoreturns extra unused items on success
sub check_handin {
my $hashref = shift;
my %required = @_;
foreach my $req (keys %required) {
if ((!defined $hashref->{$req}) || ($hashref->{$req} != $required{$req})) {
return(0);
}
}
foreach my $req (keys %required) {
delete $hashref->{$req};
}
return 1;
}

sub return_items {
my $hashref = shift;
foreach my $k (keys(%{$hashref})) {
next if($k == 0);
my $r;
for($r = 0; $r < $hashref->{$k}; $r++) {
quest::summonitem($k);
}
delete $hashref->{$k};
}
}

1;

Kagehi
03-12-2008, 12:58 PM
I was pretty sure that Live did, at some point, fix it so that stacked items where treated as though they where handed in separately... I even remember people talking about the change, while I played. I suppose I could be wrong, but I am pretty sure it was a major deal at the time it happened.

As for the plugin. That is the code I have. The problem is, you **can** tell it to look for more than one item, and you *can* try to pass a stack to it, and it will work.

For example, if you use that code, and you do:

%itemcount = (59954 => 1, 86010 => 2, 13068 => 1);
if (check_handin(\%itemcount, 59954 => 1, 86010 => 2, 13068 => 1)) {
$world->note("Great!");}
else{
$world->note("Fail!");
}

It will return true and display "Great!".

NOTE: $world->note is the function in the text client I am using as a test bed to figure it out which prints to the output stream. Normally you would, of course, use print.

So, obviously, the code *is* checking stacks, but its comparing the literal stack you ask for "two of item 86010" to the literal stack of "I gave you two of item 86010". If you substitute any other value, in either the request list, or the items given hash, it fails.

I.e., if the intent is to not allow stacks, which I still say they changed in live in one of the more recent updates (I was on a progressive, so things changed all the time from patch to patch), then its **still** wrong, since it accepts them, just *only* if its an exact match to the request, as above. If you don't want stacks, then you need an additional check, which says:

If hashref->{$req} > 1 {return 0;}

*Before* you check for it. Otherwise, if someone takes existing code, like from Vahlara in the tutorialb area, and rewrites it to say, well, the above example, which is taken from that code, then there "lookfor" is going to be wanting a stack, and will fail *every time*, since people will be giving it:

$item1 = 59954
$item2 = 86010
$item3 = 86010
$item4 = 13068

But its expecting:

$item1 = 59954
$item2 = 86010 x 2
$item3 = 13068


See what I am saying?

Kagehi
03-12-2008, 01:36 PM
Ok. Been kind of carrying on a two sided conversation on this between here an the PEQ forum. As it stands, the code is *currently* working, since the server itself doesn't allow stacks on hand ins. So far so good. However, you are dead wrong about Live and handing in stacks. Just google the terms "everquest hand in stacks" and on the first page is a link to the Epic Ranger quest, in which the poster says, "Head back to Felwithe South, run to the mage guild, and hand in wings, 4 per stack in all 4 give slots, to Niola Impholder, a trainer in the Felwithe Mage guild."

Oops! I was sure I was right about that changing, but glad I can find confirmation. And its definitely EQ1, since handins are either handled as sales style menus, as quest counters, where you don't need them "in inventory" to hand them in (they are autoconsumed as collected, then updated in the quest data), or, in a few rare cases, taken direct from your inventory, as soon as the quest knows you have them, and you talk to the NPC who wanted them. A lot cleaner and less bug prone than EQ1s method imho.

So_1337
03-12-2008, 03:27 PM
Found a bit of information. I searched as hard as I could for patch notes that mentioned any change, but I sure couldn't. Have to settle for the historical 'accuracy' of Allakhazam comments =P

You mentioned turning in 4x4 stacks... I am not familiar with the quest you mentioned, but no quest I am familiar with allows you to get credit for stacked items (only the first one on the stack). For example, turning in 4 stacks of bone chips just gives you credit for 4 bone chips. If this wasn't taken into consideration for the 5k muffin quest, that would mean you gave 20 times as many muffins as necessary (you would only need 250). Anyhow, just a thought. *shrug*

It's not such a duh. If you've done the bone chip turn in in Cab, then you might think that stacking bone chips is allowed, since for that quest, it is.

Frankly, I don't understand why they coded it so you have to do individual items. If it requires 2, then stack 2 of htem.....or at least let me take just one out.

SOE is just one big carpal tunnel lawsuit waiting to happen.

Yah, people were factioning just waay to quick for them back when you could hand in 4 stacks of 4 things at a time. Was too much of a pain for them.

Seriously, I think they removed the stacking issue to enable the code that makes NPC's hand back items they don't want. Granted they won't hand back things stacked now, but at least they'll have back un-needed or accidentally given items. Wish they could find a way to have them hand back everything not needed so we can hand in stacks again.

I absolutely agree that it was changed at some point, but I recall it specifically being only certain quests that allowed it to happen. The bone chip turn-in for Cabilis faction (as mentioned above) is one of them, and I remember cheering when Chardok factioning (turning in salts and skins to the Herald) was changed to allow stacks as well.

I personally have no problem allowing stacks to be turned in. You've got the big green light as far as being true-to-Live goes. Can it be coded as such without breaking anything else? :wink:

Theeper
03-13-2008, 12:38 PM
%itemcount = (59954 => 1, 86010 => 2, 13068 => 1);


This will work fine on the emu. It won't fail if you handin all 4 items seperately.

There may be quests on Live that allow stacked handins, I don't remember ever doing one, but I probably did. I couldn't find one that did accept stacks on Zek last night. I will check the ones you mentioned though.

Theeper
03-13-2008, 12:54 PM
The proper syntax to use the plugin is like this though.

if (plugin::check_handin(\%itemcount,59954 => 1, 86010 => 2, 13068 => 1))

Kagehi
03-13-2008, 01:44 PM
Hmm. The comment made on PEQ forum was that one might want to match the function of the game "at the stage of the patch supported". I.e., if Ykesha didn't allow it, then it shouldn't be allowed for that quest set. This presents either a major, or a minor problem. Kind of depends. I haven't looked into how globals work, so I don't know if, due to them being stored in the DB, if you have to define them, before using them? Reason I wonder is, the easiest solution is to have a setting, which can be checked against, which if not found/set to false, will cause the code to treat things as "don't allow stacks".

This still means rewriting the hand in to make it work properly, both with requests for multiple items, like normal quests do automatically, and for stacks, when allowed (can check the same setting to determine if the handing in of a stack causes an immediate return 0).

Perl on the other hand is giving me hives. Feels like I am trying to code in regexp... lol Now, it seems that the variable that %itemcount gets shifted into becomes a "reference" to that variable. This is why 'delete blah->{blah};' works with it, instead of 'delete blah{blah};'. If you use the wrong one, Perl spits out a syntax error, in my tests. Now, the simplest solution is to do what I suggested before. I.e., decrement which ever one is higher, delete the one that hits zero, then pass the remains of the %itemcount back, once you are sure everything handed in right, so return_items can give everything back, minus the items taken. This means making a copy of the hash, so if you hit a fail condition, while doing this, we can simply substitute the copy for the current hash, then return, with it intact. Supposedly, its as simple as doing '%temp_copy = %hashref;', but since I already ran into a problem using the wrong delete, I figure it might be a good idea to ask if doing a hash copy with something that contains a "reference" to a hash, will produce a copy, or if its going to freak, because I am trying to copy the hash, not make a new reference.

I am so confused by the syntax conventions going on here... :(

Kagehi
03-13-2008, 01:55 PM
The proper syntax to use the plugin is like this though.

if (plugin::check_handin(\%itemcount,59954 => 1, 86010 => 2, 13068 => 1))

Umm... That is what I used. The issue here is that while the **server** correctly deals with the '86010 => 2' part, the handin doesn't. The code in the handin, if you turn in, lets say this:

$item1 = (59954 => 1);
$item2 = (86010 => 1);
$item3 = (86010 => 1);
$item4 = (13068 => 1);

will do this:

Is '86010 => 2' found in $hashref? Well, no, its *not* found in there, since the hash only contains '86010 => 1'. Now, if you pass it the same as above, but you pass a stack for $item2, which is '86010 => 2', then handin says, "Yep, that exact key+value combination is in there.", but then the server code says, "No way! Stacks are not allowed."

Hmm. Actually, I think I need to revise things a bit in what I was thinking. If the server is handling the turn in correct, then all I need to do is check if enough has been turned in, the server itself will figure out what is left in the items it needs to return, right? So, a flag in configuration some place can determine if the server's hand in function accepts the stacks, or rejects them. The code in check_handin needs to be less complex than I was thinking. It still needs and adjustment though, since my tests imply that your, "This is the correct syntax.", just does not work at all for the function as its written.

Kagehi
03-13-2008, 03:14 PM
Ok. This **seems** to work, after a lot of hair pulling and confusion as to what the frack was going on. Obviously, it should be tested more rigorously than I have. lol

sub check_handin {
my $hashref = shift;
my $copy_hash = $hashref;
my %required = @_;
foreach my $req (keys %required) {
do {
if (defined $hashref->{$req}) {
if ($hashref->{$req} <= $required{$req}) {
$required{$req} = $required{$req} - $hashref->{$req};
delete $hashref->{$req};
if ($required{$req} == 0) {delete $required{$req};}
}
elsif ($hashref->{$req} > $required{$req}){
$hashref->{$req} = $hashref->{$req} - $required{$req};
delete $required{$req};
} else {
$hashref = $copy_hash;
return(0);
}
}
else {
$hashref = $copy_hash;
return(0);
}
} until !defined $required{$req};
}

Again, if the server where set up with a configuration option is turn off stacks, then this will pass, but the turn in won't work. What happens in that case... Another test might need to be added to this, to make sure that stacks are turned on, before even bothering to do any more checking. ;)

Time to go bounce around the rubber room a bit, and recover from trying to figure this code out in a language that looks, to me, like someone threw cartoon curse words at the screen. !%$%@!^%& = "open a gate to the Pegasus Galaxy", right? lol

Theeper
03-13-2008, 03:43 PM
If you run the current plugin inside the emu you'll see the it works perfectly as it is. If you tell it to check for 2 items of the same item ID, by doing 1234 => 2, it will match if you handin the two items unstacked.

I assume the embedded parser increments the value of the handin hash by key before returning it back to the script although I haven't checked.

AndMetal
03-13-2008, 06:33 PM
Well, I had a chance to dig through some of the source, and this is what I've come up with:

zone/embparser.cpp (http://eqemulator.cvs.sourceforge.net/eqemulator/EQEmuCVS/Source/zone/embparser.cpp?view=markup#l_435)

435 case EVENT_ITEM: {
436 npcmob->FaceTarget(mob);
437 //this is such a hack... why arnt these just set directly..
438 ExportVar(packagename.c_str(), "item1", GetVar("item1", npcid).c_str());
439 ExportVar(packagename.c_str(), "item2", GetVar("item2", npcid).c_str());
440 ExportVar(packagename.c_str(), "item3", GetVar("item3", npcid).c_str());
441 ExportVar(packagename.c_str(), "item4", GetVar("item4", npcid).c_str());
442 ExportVar(packagename.c_str(), "copper", GetVar("copper", npcid).c_str());
443 ExportVar(packagename.c_str(), "silver", GetVar("silver", npcid).c_str());
444 ExportVar(packagename.c_str(), "gold", GetVar("gold", npcid).c_str());
445 ExportVar(packagename.c_str(), "platinum", GetVar("platinum", npcid).c_str());
446 string hashname = packagename + std::string("::itemcount");
447 perl->eval(std::string("%").append(hashname).append(" = ();").c_str());
448 perl->eval(std::string("++$").append(hashname).append("{$").append(packagename).append("::item1};").c_str());
449 perl->eval(std::string("++$").append(hashname).append("{$").append(packagename).append("::item2};").c_str());
450 perl->eval(std::string("++$").append(hashname).append("{$").append(packagename).append("::item3};").c_str());
451 perl->eval(std::string("++$").append(hashname).append("{$").append(packagename).append("::item4};").c_str());
452 break;
453 }


Which basically translates to this:


%itemcount = ();
++$itemcount{$item1};
++$itemcount{$item2};
++$itemcount{$item3};
++$itemcount{$item4};


I tried to find the packet structure of the handin, so I could then see what is referenced, but I didn't have much luck.

Anyways, hope this helps.

Kagehi
03-13-2008, 07:19 PM
Theeper...

The problem is right here: ($hashref->{$req} != $required{$req})

I don't care what you run your script in, that says, return 0 **if** the number in the hash is not an exact match to the one in required.

There is nothing in that code, and no way it can "increment" anything. And, just to be clear, the client I have been doing the test in can't run Perl without ActivePerl being installed. So why, never mind how, Perl in it should behave differently in it than on the server, is entirely beyond me. Are you sure your not trying it with something that **isn't** using the plugin? There are a huge number of npcs that don't use it, to the detriment to anyone unfortunate enough to hand it the wrong things.

I would love to be wrong, somehow, but I just don't see any possible way I could be, not short of the parser developing artificial intelligence, the server code doesn't something entirely strange, which should be impossible, since it would involve knowing what you where trying to do in this case, or someone having changed the code in your copy of the plugin, so its not behaving the way the version under discussion does. There is no way around it. If you test the value contained in the hash item against the value contained in the requirements, such that if they are != (not equal), it fails...

Kagehi
03-13-2008, 07:33 PM
Thanks AndMetal. Unfortunately, without knowing what the structure is, its still not clear what is going on. There are only two possible answers. 1) its eating items, if stacked, or 2) its not storing them the same way as Perl does. I.e., Perl would see them like this:

$hash = (1224 => 2, 1234 => 1)
--internally: hash = table(2,2), where table(0,0) = 1224, table(0,1) = 2, etc.

If the server is doing this:

$item1 = 1224 => 2 --convert--> array(2), where array(0) = 1224, array(1) = 1224, etc.

Then.. It still shouldn't work, since your still checking the "value" of your key, which will be 1 from the server, while its 2, in your handing request. The only way it works at all is if the server is intercepting the call, converting the requests into a list that is *all* 1:1, then testing both against each other. But, this isn't a server call, its a call within Perl itself, which means the server only sees the original items you give the npc, not the requirements list.

I still don't see how Theeper can be right, and the code written as it is. It just shouldn't work with requests for more than one item, "period", no matter what context the Perl engine is running in.

Another reason I suspect he is wrong is simply because, while I have not made a comprehensive check of ever case, I haven't seen a single instance of check_handin used with a "I need more than one of these" check. I'll take a look again, and see if there is though.

Kagehi
03-13-2008, 07:46 PM
Ok... Someone please explain to me *why* it works... I did find at least one case where, yes, it does use a multi-item check, but the code, as it stands, doesn't appear to allow it at all.

For example:

cabeast's Master_Raska.pl does use it.

akanon's Sanfyrd_Featherhead.pl however uses the test for the second hand in, with single items, but uses the older method with the first one. Why? If both actually work, then why not change both of them to use the check?

At this point, can anyone confirm for certain what is bloody going on here, and why, if it is working? Not that I don't trust Threeper's word on it, but I can't figure why the same parser, even under two different clients, should produce such drastically different results, with the same code...

Theeper
03-14-2008, 02:42 AM
Because you're ignoring what the embedded parser does to the hash.

cavedude
03-14-2008, 03:37 AM
akanon's Sanfyrd_Featherhead.pl however uses the test for the second hand in, with single items, but uses the older method with the first one. Why? If both actually work, then why not change both of them to use the check?

Because many quests were written/pulled before check_handin.pl was even thought of. We try to convert them as we come across them but there are a lot of quests, and sometimes if somebody is just trying to get their work done, they ignore whatever is already in the file and just add their stuff. Either that, or they may not want to break anything, which ultimately, is a good thing.

Because you're ignoring what the embedded parser does to the hash.That's exactly right. I said it over at PEQ but check_handin.pl does nothing but returns items to the player the NPC doesn't need. Any parsing the plug-in does is simply to return items, not to check if quest objectives are met. The actual parsing of the items is done by the embedded perl parser in the EQEmu code. That's also why stacks don't work. If you try, you get a message saying that you can't trade stacks to a NPC. That isn't the plugin, but rather the Emu code.

To be short, when dealing with single items the plug-in combined with the internal parser works, even when dealing with multiple items with varying amounts. Stacks of course don't work, but that's because the NPC won't even allow you to hand them a stack.

Kagehi
03-14-2008, 06:02 AM
Seems to be a misunderstanding on my part by what you mean "internal parser". However, thinking it over, I came to the conclusion that there is one possible thing that could be happening that I didn't think about. Basically, if you dropped the code for the check_handin into one of the npcs, then called it direct, it would fail *exactly* how I described. However, I wasn't thinking in terms of the fact that you are calling it via 'plugins::'. I presume that what is actually happening, since no one seems inclined to explain what the internal parser actual does to it, that if you hand it '1234 => 4', some place **in between** the call in the npc file, and when the call is made to the function in plugins.pl, the server unstacks them. I.e., '1234 => 4' in when in the "look for this" part becomes '1234 => 1, 1234 => 1, 1234 => 1, 1234 => 1"? Meanwhile, the code for actually receiving items sees something like '1234 => 5', and just refuses to even accept them and call item_event in the script?

If this is what is going on, then I really am sorry for arguing my case as I did. I am used to environments where the Perl code is either handing variant types across boundaries without the C++ code touching its contents, or loading the code directly into the existing engine space, so that direct calls are being made, without the scripts host needing to handle it at all.

I wasn't so much ignoring what the parser did, as completely unaware of it, and AndMetal was the only one that came close to providing me with a clue as to what the heck might have actually been going on. And even he didn't know what it *actually* did to the stuff being handed in, or the stuff being checked against.

cavedude
03-14-2008, 07:23 AM
I'm trying to find code examples but have been unsuccessful so far (I did find a couple of other gems I needed solutions for, heh) I'll keep looking, though.

I am used to environments where the Perl code is either handing variant types across boundaries without the C++ code touching its contents, or loading the code directly into the existing engine space, so that direct calls are being made, without the scripts host needing to handle it at all.All of the perl "functions" we use are really just wrappers for the C++ functions. Once the C++ function is written, we then create the wrapper in zone/perlparser.cpp so the .pl scripts have access to it. In the end, it's C++ that is doing all of the work. This may not be the fastest method, but it is very effective for our needs. This situation affords us a powerful scripting language we can use to write quests, without requiring quest writers to know C++ or really, even Perl. I recommend browsing through the EQEmu source, specifically the zone/perl* files to truly understand how the system works.

Kagehi
03-14-2008, 03:59 PM
May do that, though my C++ is about 5,000 times worse than my Perl. lol Basically, my total exposure to C++ has been 4 weeks in a class called "current concepts", in which we barely touched on OOP, and that was... 15+ years ago. It was literally the year *prior* to them changing the curricula for Devry to have C++ and Windows as part of the main course work. Instead, it was all heavily based on COBOL, JCL, some vague DOS prompt emulation of *nix, which didn't actually go into any of how the OS did anything. The most advanced thing was the networking class, which I almost didn't pass because a) my lab partner bailed on me to do his stuff during lunch, without telling me, and b) it was using those old Coax systems, where if you fracking sneezed wrong it would fry the transceiver chip on the card... Guess what happened when I tried it, due to the stupid plug not being switched on on the work bench.

Now, VB, Java, Lua, which has a lot of the same neat stuff with arrays/tables as Perl (as of about... 72 hours ago), a smattering of some others, Pascal (from highschool), and of course COBOL 74, those I know, to various degrees, but C++ I never got into because a) it looked like spaghetti to me, and b) I hate trying to debug stuff without decent tools, and the only decent tools for C++ tend to all be expensive, especially if trying to code for Windows, where you also need all the libraries and macros (same dif...) for the APIs.

MS recently crowed about how, "No expert wants to see our code, they just want stable libraries and correct documentation of the APIs." Well, until now I wasn't too sympathetic to this, though mainly due to the fact that MS has *never* produced stable anything, or produced complete, never mind correct, documentation for it. ;) This case has given me some sympathy towards this position. Knowing how the data ends up looking *before* it gets handled by the Perl code would have prevented a long mess of errors, confusion and stubborn insistence that, "It just can't work!!" lol

Hmm. On a side note, I think I dropped this question in some place else, but it didn't get answered. Are globals automatically added to the DB when something sets them, or do they have to be defined *before*, loaded during start up, then get updated automatically some how? I would love to help fix some of the buggy stuff in some quests, especially the Shar Vahl area, including the citizen quest, but the fix requires one NPC, Bindarah, to be able to check in the client has done the quest successfully, in order to recreate the slate you receive from it (which needs to be handed in to other NPCs, who return it, for a lot of the faction quests). A lot of other things are messed up in there, like pathing, some mob spawn locations, the guards and npcs killing encroaching monsters, the fact that one at least in Shadeweaver seems to have a spawn glitch, so they are like 5 copies I have *seen* of him, when there should only be one (no idea how or why that is happening..). Well, its a disaster imho, and most of it I probably can't fix, but with the quest lines also kind of broken, and nothing checking to make sure you are not incorrectly handing in items you *must* have for later quests, its also close to unplayable.

That much, I can probably help to fix some of. The key quest though, will require the use of a global, to determine which part(s), of the main quest you have completed, so you can successfully fix yourself if you do something stupid, like throwing out your slate or cloak, or handing them to something that doesn't want them, and/or doesn't correctly return them (though, I thought there was a 'no-drop' that could be used to prevent the former).

AndMetal
03-14-2008, 09:07 PM
Are globals automatically added to the DB when something sets them, or do they have to be defined *before*, loaded during start up, then get updated automatically some how?


The simple answer is yes. When you set a global variable with the quest::setglobal() command, it is added into the database. Then, when the script runs, it is available with either $global_var_name or $qglobals{global_var_name}.

Kagehi
03-14-2008, 10:18 PM
There is a hard answer? lol

Thanks. Should be easy enough to correct the quest then. Was kind of a major, "Oh frack!". moment when the slate went missing and then I tried to get it back, only to find that the registrar didn't have the code to do so. Obviously, there are some issues with the others too, since they should either be a) correctly resumming items, or b) not accepting stuff they are not supposed to take. Most cases this is just annoying. Shar Vahl made it disastrous.

cavedude
03-15-2008, 01:28 AM
If the global is checked and isn't defined yet, it'll just throw up annoying errors in the logs, but it won't break the script. But yeah, no need to define them manually (in fact I believe doing so will prevent them from being read properly anyway)

I was meaning to get to the citizenship quest, but if you want to do it, by all means go ahead :)