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
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