Open Ruin0x11 opened 3 years ago
Perhaps an aspect that implements an interface like IAspectStorage
would be useful. When iterating the objects inside an aspect holder, any objects inside an aspect implementing such an interface would be joined to the main iterator. This is so you can have more than one aspect that can act like a container on the same object (each concrete aspect interface can only have at most one instance on each object).
With #147, the way
location
is calculated for map objects was changed. One unresolved question is how to add custom nested containers and have the location parenting still work.Here's what I was trying to do:
Inventory
inside itsparams
table holding the shop's contents.containing_map()
of the items in the trunk to be the containing map of the parent item.However, the trunk item has no knowledge of special things added by the
params
table or similar. Items can have aninv
, which is anInventory
provided by the engine itself for items that "look like" containers (as in, those that have the "elona.container" category). TheILocation
implementation for items delegates exclusively to thisinv
field, bypassing any containers we added even if their_parent
fields are set correctly.But what if we wanted to have our own custom containers in addition to
inv
that can hold more items, or have special behaviors like capacity/weight limits?Admittedly, just using
inv
instead of making aparams.shop_inventory
field was the right way to go in this specific example. That's what vanilla already does, and it's as simple as it gets. But this issue did remind me that wanting custom added containers could be a legitimate use case.If we decide we want to shoulder the potentially significant complexity this will add, we'd need some way of:
:iter_items()
or similar on the parent item and have the iterator "see" all the items from both its built-ininv
and the custom modded container inparams.shop_inventory
or similar.ILocation
methods cooperate with modded containers in a sane way. If there is some object inside an added container that's "registered" with a parentIItem
map object, thenILocation:has_object(item)
needs to returntrue
by peeking inside not only the item'sinv
, but inside the other modded containers also.A small anecdote: the one part of the original codebase that caused me to think that "maybe rewriting Elona from scratch is actually not a bad idea" was the special-case inventory logic for the cooler box. I wondered how it would be possible to mod in your own items like that with their own special container logic using the HSP codebase, but given the severe amount of hardcoding and global state surrounding how the cooler box worked with preventing items from rotting and having weight capacity, I had to wonder how much time it would take until such a cooler box would be possible to implement at all by writing a separate mod. When I couldn't find a good answer to that question, I (proverbially) threw my hands in the air and began to work on what would eventually become OpenNefia.