Dropping multiple identical items on a tile only creates one instance of the item.
Closed this issue · 6 comments
Say you have more than one of any item. If you were to drop them and try to pick them back up, only one of that item actually exists now on the game map.
Edit: I do believe I have traced the cause: items on the gamemap are stored in sets, which does not allow duplicates.
As a side note, I added the following to fighter.py under def die:
for i in self.parent.inventory.items:
self.parent.inventory.drop(i)
This also has weird behavior where it won't drop certain items (never seems to drop the second item in the list, and only dropped 3 of 5 potions, for example). I know this isn't a part of the tutorial but there seems to be some underlying issues that this bit of code is revealing.
I added those lines at the end of fighter's die method, and didn't get the issues you're having. Would you mind linking to your repository so we can see what other changes have been made, if any?
The fact that items are stored as a set shouldn't matter in this case. The set makes sure that an entity isn't added twice, but that doesn't mean two separate instances of one item can't be added to the set. The set is there to make sure the same item doesn't get dropped into the map twice, for example.
Reading what you wrote, I realized that the issue was from placing more than one of the same copy of an item into the player's inventory in setup_game. Doh!
However, the issue I'm having with the items being dropped on death is happening to me on the master branch of the tutorial, with only the for loop added to def die.
In the below pic, the player picked up a health potion then died. They dropped the dagger and potion, but not the leather armor. I know it's beyond the scope of the tutorial, but this is causing issues in my main project.
Edit: so running the for loop twice in a row makes the player drop everything, but is probably not the best solution. I'll leave some time in case you wish to respond then close this issue. Thanks for the speedy reply.
Not really the place for it, but thank you for the tutorial!
This code would cause issues:
for i in self.parent.inventory.items:
self.parent.inventory.drop(i)
If you modify a list while iterating over it you'll get unusual behavior. You'll want to iterate over a copy of this list instead:
for i in list(self.parent.inventory.items):
self.parent.inventory.drop(i)
If self.parent.inventory.items
was a set then this would have been detected earlier. Since you're not allowed to modify sets while iterating over them.
Thanks Hex, I shoulda figured this whole thing was an issue with me not knowing stuff, rather than an issue with the tutorial :)
This is a fairly common gotcha with how Python handles lists. It might be a good idea to use sets in more places.