CleverRaven/Cataclysm-DDA — pull request #8397 by BevapDin (2014-07-31 18:48:57+00:00)
Title: Saving monster on submaps [CR]

This is a draft.

- Added a monster list to submaps, `game::force_save_monster` adds the monster to that list. The list is stored in the maps file as part of the submap. It stores the whole monster object (everything that would normally be stored in the main save as active monsters), the monster of that list are spawned on the map as part of `map::spawn_monsters`, the same place were spawn points create the monsters. Monsters stored that way do not move outside of the reality bubble, they remain where they are just like spawn points, only with more data.
- Made a central `game::despawn_monster` function that decides what to do with the monster.

A monster can despawn either into a monster group on the overmap (losing all monster data and reverting to a simply increasing of the population), or into the monster list of a submap (being saved exactly). The function will create a new monster group if applicable.

The monster is stored exactly (by adding it to the submap) when `monster::spawned_from_spawn_point` is true (monster was spawned from `map::spawn_monsters`), or `monster::in_default_state` returns false.

`monster::in_default_state` decides whether the monster can be recreated by spawning a new monster, only based on its monster type (that implies the monster has the default speed/hp, no inventory, no effects, etc.).

It could be extended:
- Adding a monster-flag (maybe even reuse the IMMOBILE flag) that makes turrets and the like also be stored on the submap (mostly to preserve their ammo).
- Adding some reference to a monster that is spawned from a horde or similar monster group so it can despawn back into that group.
- Adding a monster-list to the monster group of a overmap. When new monsters from that group spawn, randomly choose one of those instead of generating a new monster. This would allow real monsters to move across the overmap (as part of the horde).
- What makes the default state of a monster - currently things like anger, plans, special attacks timeout, etc. are not considered. But if too many things are considered, the monster will nearly never be in the default state and always saved onto the submap.

Removing monsters that are in their default state should be find. The monster will be recreated during the normal spawn. This happens for example to wildlife critter, a squirrel is a squirrel, if the player goes away and comes back, it is expected to not find the squirrel there. As the removed monster is equal to a newly spawned monster, the player won't see any difference.

Note: spawnmapx, spawnmapy, spawnposx, spawnposy (part of the monster class) have been replaced with a simple bool `monster::spawned_from_spawn_point`. The values were mostly ignore, or simply recalculated based on the monster position, or only checked for being != -1.

Works fine with the new "pacified" effect.

Btw. can someone explain why items are in the monster inventory are not simply stored with `json.member("inv", inv);`? Instead the code iterates through the vector and save each item separately. Why does the item-save function even have the `bool save_contents` parameter? It should *always* save the content, shouldn't it?