forked from CleverRaven/Cataclysm-DDA
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrecipe.h
348 lines (272 loc) · 12.5 KB
/
recipe.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
#pragma once
#ifndef CATA_SRC_RECIPE_H
#define CATA_SRC_RECIPE_H
#include <cstddef>
#include <cstdint>
#include <functional>
#include <iosfwd>
#include <map>
#include <new>
#include <set>
#include <string>
#include <utility>
#include <vector>
#include "build_reqs.h"
#include "calendar.h"
#include "optional.h"
#include "requirements.h"
#include "translations.h"
#include "type_id.h"
#include "value_ptr.h"
class Character;
class JsonObject;
class item;
template <typename E> struct enum_traits;
enum class recipe_filter_flags : int {
none = 0,
no_rotten = 1,
no_favorite = 2,
};
enum class recipe_time_flag : int {
none = 0,
ignore_proficiencies = 1,
};
template<>
struct enum_traits<recipe_time_flag> {
static constexpr bool is_flag_enum = true;
};
template<>
struct enum_traits<recipe_filter_flags> {
static constexpr bool is_flag_enum = true;
};
struct recipe_proficiency {
proficiency_id id;
bool required = false;
float time_multiplier = 0.0f;
float fail_multiplier = 0.0f;
float learning_time_mult = 1.0f;
cata::optional<time_duration> max_experience = cata::nullopt;
void load( const JsonObject &jo );
void deserialize( const JsonObject &jo );
};
struct book_recipe_data {
int skill_req = -1;
cata::optional<translation> alt_name = cata::nullopt;
bool hidden = false;
void load( const JsonObject &jo );
void deserialize( const JsonObject &jo );
};
struct practice_recipe_data {
// recipe difficulty will be set dynamically between min and max
// based on current skill level; max is optional and defaults to
// MAX_SKILL - 1
int min_difficulty;
int max_difficulty;
// character cannot raise the primary skill above this limit regardless
// of recipe difficulty; defaults to MAX_SKILL
int skill_limit;
void load( const JsonObject &jo );
void deserialize( const JsonObject &jo );
};
class recipe
{
friend class recipe_dictionary;
private:
itype_id result_ = itype_id::NULL_ID();
int64_t time = 0; // in movement points (100 per turn)
float exertion = 0.0f;
public:
recipe();
bool is_null() const {
return ident_.is_null();
}
explicit operator bool() const {
return !is_null();
}
const itype_id &result() const {
return result_;
}
const itype_id &container_id() const {
return container;
}
bool was_loaded = false;
bool obsolete = false;
std::string category;
std::string subcategory;
translation description;
// overrides the result name; used by practice recipes
translation name_;
int difficulty = 0;
// Returns the recipe difficulty. For practice recipes, this is adjusted
// for the crafter's current skill level.
int get_difficulty( const Character &crafter ) const;
// Returns the maximum skill level at which crafting this recipe would still
// give xp (matching the definition of cap from Character::practice).
int get_skill_cap() const;
/** Fetch combined requirement data (inline and via "using" syntax).
*
* Use simple_requirements() for player display or when you just want to
* know the requirements as listed in the json files. Use
* deduped_requirements() to calculate actual craftability of a recipe. */
const requirement_data &simple_requirements() const {
return requirements_;
}
const deduped_requirement_data &deduped_requirements() const {
return deduped_requirements_;
}
const recipe_id &ident() const {
return ident_;
}
bool is_blacklisted() const {
return requirements_.is_blacklisted();
}
// Slower equivalent of is_blacklisted that needs to be used before
// recipe finalization happens
bool will_be_blacklisted() const;
std::function<bool( const item & )> get_component_filter(
recipe_filter_flags = recipe_filter_flags::none ) const;
/** Prevent this recipe from ever being added to the player's learned recipes ( used for special NPC crafting ) */
bool never_learn = false;
/** If recipe can be used for disassembly fetch the combined requirements */
requirement_data disassembly_requirements() const {
if( reversible ) {
return simple_requirements().disassembly_requirements();
} else {
return {};
}
}
/// @returns The name (@ref item::nname) of the resulting item (@ref result).
/// @param decorated whether the result includes decoration (favorite mark, etc).
std::string result_name( bool decorated = false ) const;
std::map<itype_id, int> byproducts;
skill_id skill_used;
std::map<skill_id, int> required_skills;
std::vector<recipe_proficiency> proficiencies;
std::map<skill_id, int> autolearn_requirements; // Skill levels required to autolearn
std::map<skill_id, int> learn_by_disassembly; // Skill levels required to learn by disassembly
// Books containing this recipe, and the skill level required
std::map<itype_id, book_recipe_data> booksets;
// Parameters for practice recipes
cata::optional<practice_recipe_data> practice_data;
std::set<flag_id> flags_to_delete; // Flags to delete from the resultant item.
// Create a string list to describe the skill requirements for this recipe
// Format: skill_name(level/amount), skill_name(level/amount)
// Character object (if provided) used to color levels
// These are primarily used by the crafting menu.
// Format the primary skill string.
std::string primary_skill_string( const Character &c ) const;
// Format the other skills string.
std::string required_skills_string( const Character &c ) const;
// Format the proficiencies string.
std::string required_proficiencies_string( const Character *c ) const;
std::string used_proficiencies_string( const Character *c ) const;
std::string missing_proficiencies_string( const Character *c ) const;
// Proficiencies for search
std::string recipe_proficiencies_string() const;
// Required proficiencies, mandatory to craft
std::vector<proficiency_id> required_proficiencies() const;
// True if character and helpers have all required proficiencies
bool character_has_required_proficiencies( const Character &c ) const;
// Used proficiencies, will impede crafting if missing
std::vector<proficiency_id> used_proficiencies() const;
// The time malus due to proficiencies lacking
float proficiency_time_maluses( const Character &crafter ) const;
// The failure malus due to proficiencies lacking
float proficiency_failure_maluses( const Character &crafter ) const;
// How active of exercise this recipe is
float exertion_level() const;
// This is used by the basecamp bulletin board.
std::string required_all_skills_string() const;
// Create a string to describe the time savings of batch-crafting, if any.
// Format: "N% at >M units" or "none"
std::string batch_savings_string() const;
// Create an item instance as if the recipe was just finished,
// Contain charges multiplier
item create_result() const;
std::vector<item> create_results( int batch = 1 ) const;
// Create byproduct instances as if the recipe was just finished
std::vector<item> create_byproducts( int batch = 1 ) const;
bool has_byproducts() const;
int64_t batch_time( const Character &guy, int batch, float multiplier, size_t assistants ) const;
time_duration batch_duration( const Character &guy, int batch = 1, float multiplier = 1.0,
size_t assistants = 0 ) const;
time_duration time_to_craft( const Character &guy,
recipe_time_flag flags = recipe_time_flag::none ) const;
int64_t time_to_craft_moves( const Character &guy,
recipe_time_flag flags = recipe_time_flag::none ) const;
bool has_flag( const std::string &flag_name ) const;
bool is_reversible() const {
return reversible;
}
void load( const JsonObject &jo, const std::string &src );
void finalize();
/** Returns a non-empty string describing an inconsistency (if any) in the recipe. */
std::string get_consistency_error() const;
bool is_practice() const;
bool is_blueprint() const;
const update_mapgen_id &get_blueprint() const;
const translation &blueprint_name() const;
const std::vector<itype_id> &blueprint_resources() const;
const std::vector<std::pair<std::string, int>> &blueprint_provides() const;
const std::vector<std::pair<std::string, int>> &blueprint_requires() const;
const std::vector<std::pair<std::string, int>> &blueprint_excludes() const;
/**
* Calculate blueprint requirements according to changed terrain and furniture
* tiles, then check the calculated requirements against blueprint requirements
* specified in JSON. If there's any inconsistency, it issues a debug message.
* This is only used in unit tests so as to speed up data loading in gameplay.
*/
void check_blueprint_requirements();
bool hot_result() const;
bool removes_raw() const;
// Returns the amount or charges recipe will produce.
int makes_amount() const;
private:
void incorporate_build_reqs();
void add_requirements( const std::vector<std::pair<requirement_id, int>> &reqs );
private:
recipe_id ident_ = recipe_id::NULL_ID();
/** Abstract recipes can be inherited from but are themselves disposed of at finalization */
bool abstract = false;
/** set learning requirements equal to required skills at finalization? */
bool autolearn = false;
/** Does the item spawn contained in container? */
bool contained = false;
/** Does the container spawn sealed? */
bool sealed = true;
/** Can recipe be used for disassembly of @ref result via @ref disassembly_requirements */
bool reversible = false;
/** Time (in moves) to disassemble if different to assembly. Requires `reversible = true` */
int64_t uncraft_time = 0;
/** What does the item spawn contained in? Unset ("null") means default container. */
itype_id container = itype_id::NULL_ID();
/** External requirements (via "using" syntax) where second field is multiplier */
std::vector<std::pair<requirement_id, int>> reqs_external;
/** Requires specified inline with the recipe (and replaced upon inheritance) */
std::vector<std::pair<requirement_id, int>> reqs_internal;
/** Combined requirements cached when recipe finalized */
requirement_data requirements_;
/** Deduped version constructed from the above requirements_ */
deduped_requirement_data deduped_requirements_;
std::set<std::string> flags;
/** If set (zero or positive) set charges of output result for items counted by charges */
cata::optional<int> charges;
// maximum achievable time reduction, as percentage of the original time.
// if zero then the recipe has no batch crafting time reduction.
double batch_rscale = 0.0;
int batch_rsize = 0; // minimum batch size to needed to reach batch_rscale
int result_mult = 1; // used by certain batch recipes that create more than one stack of the result
update_mapgen_id blueprint;
translation bp_name;
std::vector<itype_id> bp_resources;
std::vector<std::pair<std::string, int>> bp_provides;
std::vector<std::pair<std::string, int>> bp_requires;
std::vector<std::pair<std::string, int>> bp_excludes;
/** Blueprint requirements either autocalculcated or explicitly
* specified. These members relate to resolving those blueprint
* requirements into the standard recipe requirements. */
bool bp_autocalc = false;
bool check_blueprint_needs = false;
cata::value_ptr<build_reqs> blueprint_reqs;
};
#endif // CATA_SRC_RECIPE_H