DestroyItem() fails: "That item is 'gotten'."

Report core bugs regarding the Ultima Online Emulator Core release (version 097). You can attach your Core Dump. One bug per post.

Moderator: POL Developer

Locked
User avatar
ncrsn
Grandmaster Poster
Posts: 255
Joined: Fri Feb 10, 2006 12:15 am

DestroyItem() fails: "That item is 'gotten'."

Post by ncrsn »

I couldn't find the errortext documented anywhere.

Here's the scenario:
- a container with caninsert-, oninsert- and methodscript
- an item which is dragged into the container
- during the process, the item is supposed to be destroyed

CanInsertScript checks for objtype and returns 1 (valid).
OnInsertScript contains container.MethodCall(item), which looks like this:

Code: Select all

exported function MethodCall( container, inserted_item )
    // Make sure no-one else is using this.
    var result := ReserveItem(inserted_item);
    
    if (result)
        // Destroy it.
        result := DestroyItem(inserted_item);
    endif
    
    return result;
endfunction
MethodCall's return value is then evaluated in the OnInsertScript. And what happens? It returns a cryptical "That item is 'gotten'." error.

I did few tests and it seems that ReserveItem is the cause of the error. Should the methodscript not to reserve the item before trying to destroy it, item is destroyed properly.

Yet I have not tried if same applies in some other settings, too, but I hope the error message itself reveals something to the ones who have access to the source code (and few minutes time to check it out).

I don't think that in this case the item's destruction should fail.
Luth
Former Developer
Posts: 200
Joined: Mon Jan 30, 2006 8:10 am

Post by Luth »

I think if you successfully Reserve the item, then, as you suggested, you first want to Release the item and then Destroy it.
User avatar
ncrsn
Grandmaster Poster
Posts: 255
Joined: Fri Feb 10, 2006 12:15 am

Post by ncrsn »

That old feature was fixed a few releases ago:
core-changes.txt wrote:-- POL096.5 --
10-20 Austin
Fixed : DestroyItem() and SubtractAmount() will work on items reserved in the same script.
So I hope it's supposed to work even these days? As the normal behaviour...

Code: Select all

program stupid_script( item )
    ReserveItem(item);
    DestroyItem(item);
endprogram
Works like a charm.

--

Oh and I'm using the latest core, the-nearly-final-oo-la-laa-097.
Luth
Former Developer
Posts: 200
Joined: Mon Jan 30, 2006 8:10 am

Post by Luth »

Ah. I overlooked something. :) Because the item is currently being moved by the client, the object has been "gotten" until the move is complete.

Because the item is InUse, Reserve will fail (generating an "That item is already being used." error), and Destroy will fail (generating the "That item is 'gotten'." error). I believe you'll have to destroy the item outside of that script.
User avatar
ncrsn
Grandmaster Poster
Posts: 255
Joined: Fri Feb 10, 2006 12:15 am

Post by ncrsn »

So in this case, the non-documentated error is because the dragged item is reserved, but not Reserved, by core, so that the ReserveItem() function still allows reserving the item to other processes, but it really won't hold?

I summarized that because you wrote "Reserve will fail", which is not the case. Which is the odd thing - I can take I cannot destroy an unreservable item, but when the item is reserved to My Process and I still cannot get rid of it, I get confused and tend to post bug reports.
Luth
Former Developer
Posts: 200
Joined: Mon Jan 30, 2006 8:10 am

Post by Luth »

I looked at the code when I was writing this, and I believe that if you attempt to reserve an item that is "gotten" it should fail with the error message I presented you. Maybe I didn't read it as closely as I should have. :x I'll try to look over it again when I have a free moment.
User avatar
ncrsn
Grandmaster Poster
Posts: 255
Joined: Fri Feb 10, 2006 12:15 am

Post by ncrsn »

Thanks. Say if you want scripts to test it out.
Luth
Former Developer
Posts: 200
Joined: Mon Jan 30, 2006 8:10 am

Post by Luth »

When moving an item, the following segment gets run:

Code: Select all

client->chr->gotten_item = item;
item->inuse(true);
item->is_gotten(true);
When calling ReserveItem, the following segment gets run:

Code: Select all

if (item->inuse())
{
  if (is_reserved_to_me( item ))
    return new BLong( 1 );
  else
    return new BError( "That item is already being used." );
}
It seems to me that in your script ReserveItem will fail with the above error message unless the item was Reserved to that character prior to this script being called. In that case, ReserveItem will succeed (as its already reserved) and DestroyItem will fail as the item is still "gotten."
User avatar
ncrsn
Grandmaster Poster
Posts: 255
Joined: Fri Feb 10, 2006 12:15 am

Post by ncrsn »

Correct me if I got this wrong: the item has two different reserving options: 1. reserved ("gotten") by character 2. reserved by process. Script-wise we can directly control only the latter one, while core handles the former when necessary? If so, even if item could be reserved to process using ReserveItem() (or released using ReleaseItem()), IF item is also reserved by the character the uses of item reservation would be slight (-> One cannot destroy an item "gotten" by character)?

I'd like to get this right for sure before suggesting anything.
User avatar
MontuZ
Forum Regular
Posts: 338
Joined: Fri Feb 10, 2006 8:08 am
Location: Myrtle Beach, South Carolina

Post by MontuZ »

getgottenitem() - returns an ItemRef to the item held on the player's cursor, if any.

cleargottenitem() - Returns 'dragged' item to original location.

From;
http://docs.polserver.com/pol097/objref.php#Character

Didn't fully read all the posts, sorry of this doesn't help.
User avatar
ncrsn
Grandmaster Poster
Posts: 255
Joined: Fri Feb 10, 2006 12:15 am

Post by ncrsn »

Thanks anyway, going to try if that solves it.

edit:
And I did.

From OnInsertScript

Code: Select all

program oninsertscript( who, container, movetype, inserttype, item )
    print("Gotten item: " + who.GetGottenItem() + ".");
    print("Clearing returned... " + who.ClearGottenItem() + ".");
    
    return 1;
endprogram
Printed "Gotten item: <uninitialized object>." and "Clearing returned... " + error{ errortext = "No Gotten Item" }".

So, I think it didn't help after all. I think it's because the item is already "dropped" from cursor when -insertscripts are launched.

--
(By the way, it would be useful to be able to tell if item is dragged by someone - nowadays one cannot tell whether it is or is not, without enumerating all players online and comparing the gotten item they might have to it. Might do a feature request about this one day.)
Locked