CleverRaven/Cataclysm-DDA — pull request #5405 by BevapDin (2014-01-04 16:46:43+00:00)
Title: mood manager WIP/CR

So, this mod manager seems to be the next big thing, that everyone wants.
I looked into the GalenEvils branch and after merging it with the current mainline (it's quite a bit out of date), it seems quite good (non-functional, but the ui is there - and the ui is the stuff I generally never touch).

I expanded it and made it working - at least as far as I have tested, but I'm very bad at testing.

There have been some changes to the main menu:
Professions use items and more that might depend on a mod (even the professions can be modded) and the skills, too. The player has to choose a world (and the mods they want to use in that world) before character generation. If one chooses "New Game" and than an further command, the world has to be selected there. It uses `worldfactory::pick_world` which either uses the only world that exist, prints the menu to create a new one or prints a menu to select an existing world.

Character templates have been disabled for now, as the would store the profession and that means they would require loading a world with the needed mod or so.

ALL the UI parts of the mod manager are from GalenEvil.

*****

The mods work like this:
A mod must have an entry in a modinfo.json file, located in the data folder. (There may be several mods defined in one file, and there can be several of these files. They are all loaded anyway.)

A mod requires an ident and a mod-type (CORE or SUPPLEMENTAL), each world can only have one CORE mod, but many SUPPLEMENTAL mods. Each mod has a data path. The game considers all files with the json ending in that path (recursive) as part of the mod (this is also part of GalenEvils work).
A simple example mod definition looks like this:
```
{
"type": "MOD_INFO",
"mod-type": "SUPPLEMENTAL",
"ident": "self-contained-mod",
"name": "self-contained mod",
"description": "text...",
"dependencies": ["other-mod-ident"],
"path": "modinfo.json"
}
```

The path of a mod is defined like this:
If the mod info contains a path member, this is used and prefixed with the path of the modinfo.json that it is taken from (if read from a "data/mods/modinfo.json" and path is "my-mod-data, the path becomes "data/mods/my-mod-data/").
If the mod info does not contain a path member, the path becomes "/data" (if read from a "data/mods/my-mod/modinfo.json", it will be "data/mods/my-mod/data/").

Path can refer to a folder or to the modinfo file itself (like in the above example). This allows self-contained mods, that consists of only one file.

GalenEvils mod manager copies all mod specific json files into a folder in the world (save/my-world/mods) and loads them from there.
Changes to the original mods (in data/mods) will therefor *not* appear in any existing world. This might be good, or bad, I'm not sure.

Upon starting a game, the currently active world is set and the mods of that world are loaded. Than the user might create a new character or start playing an existing one, like normal, no changes here.

*****

Json can be checked with `./cataclysm --check-mods`

There might still be problems, I didn't played much with it.
Biggest problem might be unloading and reloading C++ object from json. They are partially interconnected. I tried to add unload-functions (called `reset_*`) for each `load_*(JsonObject &jo)` function that is added to `type_function_map` but I might have missed something.

Moving stuff from C++ to json goes now like this:
- create load_*(JsonObject &jo) function (or member function of a class)
- create reset_* function, which deletes all the loaded stuff
- Optional: create finalize function (called after loading all mods)
- Register these function in init.cpp

I also fixed the delayed loading from json files, but this seems to be very slow as each files content is parsed several times. Although it allows recipes and vehicles (depend on vehicle parts) to be specified anywhere, ones does have to make sure that vehicles get leaded after the vehicle parts are loaded.

*****

Questions:

What about mod naming clashes? This applies to items/... but basically what if the mod manager encounters a mod with an ident that it already knows of?
Should the manager add a number to the ident and make it unique that way or should it discard the mod?

Coping the mods into the world folder makes them static (won't change when the mod changes). Is this desired?

GalenEvils work seems to assume that at most one CORE mod gets selected and that this mod provides the core data for the game. That means only data from the mods (of the selected world) gets loaded. So once you created a world, the data/json folder would be unused as everything gets loaded from the world folder (except maybe names, colors). That would work perfectly well, but might be a bit inconvenient?
This requires a check (so I think) to make sure the user actually selected a CORE mod, as otherwise the game would be pretty much unplayable.

Some code maybe should check if the monster/overmap terrain/furniture/terrain/item/... exists before spawing/using it to allow mods to not include that thing.

Should mods be able remove already loaded data (like removing items from item groups, in case those items should spawn somewhere else)?

Adding to mods / removing mods from an existing world?
Adding wouldn't be a problem (as long as the mod does not remove things), but removing stuff is generally dangerous/impossible.

Default set of mods to be set when creating a new world?

*****

Another thing (that might even go in without the mod manager): the vehicle parts with variable size are now loaded from json, as are the CBM items. This is necessarily because the CBMs depended on the load bionics.

And changed the item_group loading slightly:
item types that already exist will be overridden (this I think was already the case, I added proper deletion of the previous item). This allows mods to re-define existing items.
item_groups are appended to existing item_groups, so mods can append their items so they spawn.
This should also work with professions, materials and skills.

*****

This branch is actually not merge-ready, there are some mods that are currently only used for testing. Some add things, some contain things moved from the core data.

How much of it can be used and how much do I have to rewrite?