Page 1 of 1

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

Posted: Tue Jun 24, 2008 2:38 am
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.

Posted: Tue Jun 24, 2008 10:40 am
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.

Posted: Tue Jun 24, 2008 11:07 am
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.

Posted: Tue Jun 24, 2008 6:01 pm
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.

Posted: Wed Jun 25, 2008 1:51 am
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.

Posted: Thu Jun 26, 2008 2:54 pm
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.

Posted: Thu Jun 26, 2008 6:17 pm
by ncrsn
Thanks. Say if you want scripts to test it out.

Posted: Fri Jun 27, 2008 5:56 pm
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."

Posted: Sat Jun 28, 2008 2:04 am
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.

Posted: Sat Jun 28, 2008 3:45 am
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.

Posted: Sat Jun 28, 2008 4:08 am
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.)