Ah. The we’re obviously talking about different things.
Actually I’ve been considering something like this before working on “configurable object”. But in the end I haven’t found any easy way to implement something like this without breaking H3 behavior.
For example banks - they consist from 2 parts: guards and reward. But they are not separate. For example to generate correct reward message you need information about guards (“You have defeated %creature name% and claimed reward: %reward%”). Messages like this need information from multiple modules which were supposed to be black boxes. Delegating this function to object means that object would need script.
Stables have this as well - cavalry upgrade message also contains text about movement bonus. And this situation is global - right now I’m fighting with text placeholders in my configurable objects.
Another issue is rules on order in which these modules should be activated. For example Crypt should have scheme like this:
visit confirmation -> object looted? no -> guards -> guards defeated? -> morale hit & reward
yes -> morale hit
So there also should be logic code that will determine activation order, which modules are active and which should be removed and such. And this means need of scriptable objects.
I think that such modules will only work for some specific cases - like market or harbor. Using it on larger scale is not worth efforts. Especially if we may actually get scripts where most of these modules can be implemented in 1-2 calls to game state.
What may work here (relatively easy) is removing town building - map object duality. For example by implementing something like this:
class ITownBuilding // aka module
{
const CGObjectInstance * parent; // either town or map object, but town building does NOT "knows" that
//some interface, can be similar to IObjectInterface
}
class CGTownInstance : public CGObjectInstance // or whatever its parent is
{
std::map<BuildingID, ITownBuilding*> buildings; // list of town buildings, blackboxes
}
class CMapBuilding : public CGObjectInstance // for objects that have identical town building
{
ITownBuilding* building; // ONE building, with some configuration on when it gets active
}
ITownBuilding can be easily renamed to something like “object module”. In such way removing such duality should be easy but I don’t think that composing objects from modules is feasible.
And of course it won’t help with this issue:
This is what I wanted to fix with modules that have API known to objects-parents.