0 votes


When trying to update the content of a dictionary, I get different results when using the copy of a dictionary instead of the original dictionary. The result obtained from the copy is the correct one. Copying it back will not solve the issue.

Line 37 of item_instance.gd produces the correct result:
var inventory = str2var(var2str(InventoryController.inventory))

Line 38 of item_instance.gd produces the incorrect result:
var inventory = InventoryController.inventory

You can download the project from BitBucket and reproduce the issue, play around and hopefully find the solution. I was unable to do so.

Note that the issue occurs only when grabbing several objects at once.

Thanks in advance.

Godot version 3.2.3 stable official
in Engine by (30 points)
edited by

1 Answer

+1 vote
Best answer

When player pickup N item, you call _on_item_grabbed N times. _on_item_grabbed adds all content of ground inventory to player inventory. So when you have M items on the floor, you will add (N * M) items to player's inventory. You should add only picking up object, not all items at once. Dirty workaround would be to empty ground_inventory after item pickup (note that it still will be called M times, but (M-1) calls will work with empty dict, i.e. do nothing).
Moreover, in your case items will be added more than (N * M) times. This is because queue_free is not executed immediately (it is executed during idle frames), and item might be picked up more than once before it is freed. Quick fix would be next check at top of the _on_item_grabbed

if is_queued_for_deletion():

To make live update of your inventory (wishlisted in bitbucket), you need to use Godot's implementation of Observer pattern (signals). And I highly recommend to read some books about game programming, in your current implementation of game components are tightly coupled and you will not be able to maintain it pretty quick. Here's one of the books you can read (you can skip III, IV and VI chapters): https://gameprogrammingpatterns.com/contents.html

by (1,314 points)
edited by

I was able to fix the issue thanks to your hint on _on_item_grabbed being called for each item instance on the ground and by deleting the nodes with is_queued_for_deletion()

The top of _on_item_grabbed looks like this:

if is_queued_for_deletion():

I'll definitely go through the book you recommended.

Thanks a lot for your insight on this.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.