PDA

View Full Version : #nukeitem Tweak:


So_1337
08-02-2008, 12:31 PM
Hey guys.

Perhaps this is really just a bug preventing the command from working properly, but I thought I'd post here. Without being able to see and understand the code myself (which I sure can't and sure don't!), I have to bug you for the answer. If it's a bug, it needs to be moved. If it's just functionality that isn't there for some reason, it'd be nice to have it added.

I've had the problem a few times where I will receive the error "Bogus item detected!" while play-testing a quest with a perfectly legitimate and non-bogus item, and I never receive the item that I can see. However, trying to do the hand-in again reports that I have a duplicate item.

The item always shows as being in the Cursor slot (slot 30), even though I can't see it. The only way I know it's there is with #peekinv and going through the listing.

When it does happen, the only way I can find to stop it is to log out and in until it pops on my cursor. Makes it immensely irritating. Even #nukeitem doesn't clear it, surprisingly. Is there some reason that #nukeitem isn't able to clear it? I know I've deleted items off of a person's cursor before, but it never seems to work in this instance. Is it not checking every possible slot?

AndMetal
08-03-2008, 12:13 AM
Here's the code for the NukeItem command:

zone/command.cpp (http://eqemulator.cvs.sourceforge.net/eqemulator/EQEmuCVS/Source/zone/command.cpp?revision=1.51&view=markup#l_2754)

void command_nukeitem(Client *c, const Seperator *sep)
{
int numitems, itemid;

if (c->GetTarget() && c->GetTarget()->IsClient() && (sep->IsNumber(1) || sep->IsHexNumber(1))) {
itemid=sep->IsNumber(1)?atoi(sep->arg[1]):hextoi(sep->arg[1]);
numitems = c->GetTarget()->CastToClient()->NukeItem(itemid);
c->Message(0, " %u items deleted", numitems);
}
else
c->Message(0, "Usage: (targted) #nukeitem itemnum - removes the item from the player's inventory");
}


zone/inventory.cpp (http://eqemulator.cvs.sourceforge.net/eqemulator/EQEmuCVS/Source/zone/inventory.cpp?revision=1.27&view=markup#l_47)

// @merth: this needs to be touched up
uint32 Client::NukeItem(uint32 itemnum) {
if (itemnum == 0)
return 0;
uint32 x = 0;

int i;
for (i=0; i<=29; i++) { // Equipped and personal inventory
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
DeleteItemInInventory(i, 0, true);
x++;
}
}
for (i=251; i<=339; i++) { // Main inventory's and cursor's containers
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
DeleteItemInInventory(i, 0, true);
x++;
}
}
for (i=2000; i<=2015; i++) { // Bank slots
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
DeleteItemInInventory(i, 0, true);
x++;
}
}
for (i=2030; i<=2109; i++) { // Bank's containers
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
DeleteItemInInventory(i, 0, true);
x++;
}
}
for (i=2500; i<=2501; i++) { // Shared bank
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
DeleteItemInInventory(i, 0, true);
x++;
}
}
for (i=2531; i<=2550; i++) { // Shared bank's containers
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
DeleteItemInInventory(i, 0, true);
x++;
}
}

return x;
}


Referencing the Wiki (http://www.eqemulator.net/wiki/wikka.php?wakka=DevInventorySlots), the cursor itself is slot # 30 and its bag slots are 331 through 340. So, basically, slot 30 (an item just on the cursor) isn't being nuked by NukeItem. If you change the following:

for (i=0; i<=30; i++) { // Equipped and personal inventory & single item on cursor
if (GetItemIDAt(i) == itemnum || (itemnum == 0xFFFE && GetItemIDAt(i) != INVALID_ID)) {
DeleteItemInInventory(i, 0, true);
x++;
}
}

That will fix it.

Logistically speaking, there might be a better way to do this, seeing as how each and every one of those for statements is exactly the same (which is what I'm sure the comment "this needs to be touched up" at the top means), although I'm not sure of the best, simplest way to do so. I was thinking an array with all of the slots to check defined in it, but I have a feeling that might be slower than just using for.

In any case, hope this helps.

trevius
08-03-2008, 03:41 AM
Ya, I noticed that when I was trying to use the #nukeitem on a player after I accidentally used #gi on the wrong player, it wasn't able to nuke it, because it was on the cursor. I think it gave me an error about not finding the item, even though I could #peekinv and see it was still on the cursor.

If this fix resolves that, that would be nice. If there is a better way to do it that someone can clean up a bit, that would be even better :)

So_1337
08-03-2008, 10:28 AM
Thanks a bunch, AndMetal. I'm pretty much useless on real coding, so you did all the legwork for this one. Now I understand why it's not working properly. This would be a big boon for GMs trying to fix errors in this way. Thanks to anyone who takes it further =)