CleverRaven/Cataclysm-DDA — pull request #4904 by RabbitB (2013-12-06 02:02:59+00:00)
Title: [FIXED] Expanded Qualities System & Smart Crafting Distances

This is a resubmission of PR: https://github.com/CleverRaven/Cataclysm-DDA/pull/4835

A major bug was discovered with it so it was necessary to unmerge it. This PR is a submission of all the original functionality, with the necessary bug-fixes. There should no longer be issues related to crafting with resources outside of the default crafting distance, and working on vehicles (installing parts, etc.) should now properly take into account the crafting distances awarded by storing items on furniture. Tools have also been properly fixed so they take the distances into account.

-----

The basis of the qualities system was already in-place, but it wasn't finished. The existing functions weren't capable of reading quality values and essentially just treated qualities as flags. The interface also wasn't fleshed out to the same scale of flags.

The expanded qualities system now accomplishes its original task and allows for retrieving quality values. It has also been expanded to encompass furniture and terrain in addition to the original item only support. To make the system easier to access, the interface for qualities has been expanded to give it parity with the flags interface.

`class item`, `struct furn_t`, `struct ter_t`
```C++
bool has_quality(std::string quality_id) const // Checks if a quality exists.
bool has_quality(std::string quality_id, int quality_value) const //Checks if a quality with the specific value exists.
int level_of_quality(std::string quality_id) const // Get the value of a quality.
```

`class map`
```C++
bool has_quality(std::string quality_id, const int x, const int y)
bool has_quality(std::string quality_id, const int quality_value, const int x, const int y)
bool has_quality_ter(std::string quality_id, const int x, const int y)
bool has_quality_ter(std::string quality_id, const int quality_value, const int x, const int y)
bool has_quality_furn(std::string quality_id, const int x, const int y)
bool has_quality_furn(std::string quality_id, const int quality_value, const int x, const int y)
bool has_quality_ter_or_furn(std::string quality_id, const int x, const int y)
bool has_quality_ter_or_furn(std::string quality_id, const int quality_value, const int x, const int y)
bool has_quality_ter_and_furn(std::string quality_id, const int x, const int y)
bool has_quality_ter_and_furn(std::string quality_id, const int quality_value, const int x, const int y)
```

Expanding the qualities system was part of implementing a smart crafting distance system. Under this system, furniture and terrain can define the quality `CRAFT_DISTANCE`, the value of which determines from how far away the items stored on the tile can be used for the purposes of crafting.

This system was implemented to help address a number of issues:
- Players want a reason to develop a permanent base, but bases in their current form are grossly inferior to large vehicles.
- If a player does establish a base, they are punished for developing a realistic layout. Organizing items, creating stock rooms and work areas are all markedly inferior to just throwing everything the player finds into one large pile and then standing over it to craft.
- Furniture is largely useless and the player has no reason to build or use it beyond sleeping purposes.

Many changes are needed to fully address those issues, but this system attempts to help alleviate some of the issue by giving the player an incentive to build furniture and design a smart and efficient layout for their base, by effectively expanding their crafting radius for doing so.

The rational for implementing the system as it is, is that it not only improves gameplay, but it increases realism. In real life, items organized on a shelf, counter, locker or other furniture meant for storing or organizing items are easier to find (in contrast to items just thrown on the floor, or in piles), either because you can see them more easily or more easily remember where they are.

It is important to remember that yes, realism (although not necessarily gameplay or player fun) can be increased further by giving a penalty for creating large piles of items, or for storing many different types of items in the same space, but this system does not address that specifically, for several reasons.
- As written, the system is simple and doesn't degrade performance or introduce a lot of changes to existing code.
- Accounting for penalties for piled up or scattered items is not simple; in fact, although related conceptually, programmatically it requires even further additions and code changes. Even though this system would stand as a basis for those additions, this PR does not attempt to implement those additions itself.

We must remember that at the heart of all this, Cataclysm still has a number of overarching issues (end-game content, base-building, etc.) that cannot be solved by a singular fix. The best we can and should do is take small bites out of the issues until we have whittled them away. This PR is just an attempt to take a small bite out of one of those issues.