Handin plugin confusion...
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 |
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:
Code:
Looking for Found Result |
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: Code:
%itemcount{$item1}++; I agree, the "better" way to do this is to do something like this: Code:
%itemcount{%item1{id}} += %itemcount{%item1{stacksize}}; 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? |
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: Code:
for every KEY in what I want do 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. |
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. Code:
# plugin::check_handin($item1 => #required_amount,...); |
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: Code:
%itemcount = (59954 => 1, 86010 => 2, 13068 => 1); 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? |
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. |
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
Quote:
Quote:
Quote:
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: |
Quote:
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. |
The proper syntax to use the plugin is like this though.
Code:
if (plugin::check_handin(\%itemcount,59954 => 1, 86010 => 2, 13068 => 1)) |
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... :( |
Quote:
$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. |
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
Code:
sub check_handin { 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 |
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. |
Well, I had a chance to dig through some of the source, and this is what I've come up with:
zone/embparser.cpp Code:
435 case EVENT_ITEM: { Code:
%itemcount = (); Anyways, hope this helps. |
All times are GMT -4. The time now is 11:29 PM. |
Powered by vBulletin®, Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.