[WIP] Overhaul of code involving requirements, recipes and skills.

From commit notes:

Includes:
 * A massive amount of const-correctness fixes, particularly to code involving the Skill class.
 * Removing differentiation between primary and secondary skill requirements
 * Moving skill requirements to src/requirements.cpp, paving way to using them for vehicles and construction
 * Modified recipe success formulas, they're reasonably similar to the previous ones, save for the 100% broken chance-to-learn recipe
 * Changing skill requirements internally to a more easily extensible format
 * [WIP] Ability to load said requirements from a different JSON structure, that can be more easily included in different entity types in the future. So far this is heavily WIP
 * Adding to above two points: Backwards-compatibility is kept, no data file changes included
 * [WIP] Crafting UI changes. WIP part includes showing a confidence/difficulty rating instead of a raw %
 * Minor fix for two typos in recipe_food.json

Also, changes I forgot to mention there:
 * Unlearnable recipes in books are shown in red
 * Recipe learning threshold from books now uses recipe skill requirements, due to there no longer being a primary skill/difficulty pair. This is probably the biggest non-structural change of them all, but I'm not sure anything can be done about it. Perhaps a flat bonus/penalty to skill levels required.
 * Skill requirements now include few more factors that can be overwritten in the new(wip) requirement JSON format, this includes base success chance, and splitting minimum required skill off from difficulty, meaning it will be possible to enable crafting higher-level recipes at a significant failure probability penalty, if that turns out to be a desirable thing, or to make recipes harder than their base requirement.
 * Some formatting changes - I upgraded bits of code to C++11, primarily just the for-in syntax, renamed some cryptic variable names, and added few intermediate variables in some places to make code more readable.

Forgive me for submitting a single huge monolithic commit, but the code was essentially spaghetti. From gameplay point of view, the changes are not significant, outside of the modified recipe success probabilities(they're reasonably close to before, though) necessitated by the fact that the old dice-based algorithms were impossible or at least very hard to extend to support multiple skills, and as such I have replaced it with a simple algorithm that can be modified by a single difficulty modifier parameter.

This is not yet finished, as it contains few issues that I ended up not fixing due to having to leave my development machine, notably probability of critical failure is way too high, and difficulty penalties for learning recipes need adjustments - currently, disassembly, learning by crafting, reading from books all use the same success chance as crafting.

And yet again, forgive me for how monolithic this is, trust me that the code was intertwined enough that the difficulty of changing it independent-bit-by-bit was somewhere between "impossible" and "I'm not good enough of a coder".
I don't know about the rest of the code, but in what I worked on, `p` and `_player` were both used, and I simply picked the more readable of the two to use as a common convention. Unfortunately, `player` is a class name and therefore not an option.

Davek <notifications@github.com> wrote:

>> @@ -72,6 +72,27 @@ struct item_comp : public component {
>>      std::string get_color(bool has_one, const inventory &crafting_inv, int batch = 1) const;
>>  };
>>  
>> +struct skill_requirement {
>> +    const Skill* skill = nullptr; // This should NEVER be null if it's loaded properly
>> +    int minimum = 0; // Minimum skill required to use this recipe
>> +    int difficulty = 0; // Difficulty of this recipe
>> +    float base_success = 0.5f;
>> +    float stat_factor = 0.125f; // How much of a bonus/penalty to skill deviating from 8 is
>> +
>> +    skill_requirement() { }
>> +    skill_requirement(const Skill* _skill, int _minimum, int _difficulty,
>> +                      float _base_success = 0.5f)
>> +        : skill(_skill), minimum(_minimum), difficulty(_difficulty),
>> +          base_success(_base_success) { }
>> +
>> +    void load(JsonObject &json_obj);
>> +    bool meets_minimum(const player& _player) const;
>
>personal opinion (and since the rest of the code uses this), var name being `p` would suffice, no? I can't stand leading underscores, sans being a reserved name syntax or C opaque struct var.
>
>---
>Reply to this email directly or view it on GitHub:
>https://github.com/CleverRaven/Cataclysm-DDA/pull/10567/files#r22144855