1 /*
2 craftdef.h
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 */
5 
6 /*
7 This file is part of Freeminer.
8 
9 Freeminer is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13 
14 Freeminer  is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17 GNU General Public License for more details.
18 
19 You should have received a copy of the GNU General Public License
20 along with Freeminer.  If not, see <http://www.gnu.org/licenses/>.
21 */
22 
23 #ifndef CRAFTDEF_HEADER
24 #define CRAFTDEF_HEADER
25 
26 #include <string>
27 #include <iostream>
28 #include <vector>
29 #include <utility>
30 #include "gamedef.h"
31 #include "inventory.h"
32 
33 /*
34 	Crafting methods.
35 
36 	The crafting method depends on the inventory list
37 	that the crafting input comes from.
38 */
39 enum CraftMethod
40 {
41 	// Crafting grid
42 	CRAFT_METHOD_NORMAL,
43 	// Cooking something in a furnace
44 	CRAFT_METHOD_COOKING,
45 	// Using something as fuel for a furnace
46 	CRAFT_METHOD_FUEL,
47 };
48 
49 /*
50 	Input: The contents of the crafting slots, arranged in matrix form
51 */
52 struct CraftInput
53 {
54 	CraftMethod method;
55 	unsigned int width;
56 	std::vector<ItemStack> items;
57 
CraftInputCraftInput58 	CraftInput():
59 		method(CRAFT_METHOD_NORMAL), width(0), items()
60 	{}
CraftInputCraftInput61 	CraftInput(CraftMethod method_, unsigned int width_,
62 			const std::vector<ItemStack> &items_):
63 		method(method_), width(width_), items(items_)
64 	{}
65 	std::string dump() const;
66 };
67 
68 /*
69 	Output: Result of crafting operation
70 */
71 struct CraftOutput
72 {
73 	// Used for normal crafting and cooking, itemstring
74 	std::string item;
75 	// Used for cooking (cook time) and fuel (burn time), seconds
76 	float time;
77 
CraftOutputCraftOutput78 	CraftOutput():
79 		item(""), time(0)
80 	{}
CraftOutputCraftOutput81 	CraftOutput(std::string item_, float time_):
82 		item(item_), time(time_)
83 	{}
84 	std::string dump() const;
85 };
86 
87 /*
88 	A list of replacements. A replacement indicates that a specific
89 	input item should not be deleted (when crafting) but replaced with
90 	a different item. Each replacements is a pair (itemstring to remove,
91 	itemstring to replace with)
92 
93 	Example: If ("bucket:bucket_water", "bucket:bucket_empty") is a
94 	replacement pair, the crafting input slot that contained a water
95 	bucket will contain an empty bucket after crafting.
96 
97 	Note: replacements only work correctly when stack_max of the item
98 	to be replaced is 1. It is up to the mod writer to ensure this.
99 */
100 struct CraftReplacements
101 {
102 	// List of replacements
103 	std::vector<std::pair<std::string, std::string> > pairs;
104 
CraftReplacementsCraftReplacements105 	CraftReplacements():
106 		pairs()
107 	{}
CraftReplacementsCraftReplacements108 	CraftReplacements(std::vector<std::pair<std::string, std::string> > pairs_):
109 		pairs(pairs_)
110 	{}
111 	std::string dump() const;
112 	void serialize(std::ostream &os) const;
113 	void deSerialize(std::istream &is);
114 };
115 
116 /*
117 	Crafting definition base class
118 */
119 class CraftDefinition
120 {
121 public:
CraftDefinition()122 	CraftDefinition(){}
~CraftDefinition()123 	virtual ~CraftDefinition(){}
124 
125 	void serialize(std::ostream &os) const;
126 	static CraftDefinition* deSerialize(std::istream &is);
127 
128 	// Returns type of crafting definition
129 	virtual std::string getName() const=0;
130 
131 	// Checks whether the recipe is applicable
132 	virtual bool check(const CraftInput &input, IGameDef *gamedef) const=0;
133 	// Returns the output structure, meaning depends on crafting method
134 	// The implementation can assume that check(input) returns true
135 	virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const=0;
136 	// the inverse of the above
137 	virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const=0;
138 	// Decreases count of every input item
139 	virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const=0;
140 
141 	virtual std::string dump() const=0;
142 
143 protected:
144 	virtual void serializeBody(std::ostream &os) const=0;
145 	virtual void deSerializeBody(std::istream &is, int version)=0;
146 };
147 
148 /*
149 	A plain-jane (shaped) crafting definition
150 
151 	Supported crafting method: CRAFT_METHOD_NORMAL.
152 	Requires the input items to be arranged exactly like in the recipe.
153 */
154 class CraftDefinitionShaped: public CraftDefinition
155 {
156 public:
CraftDefinitionShaped()157 	CraftDefinitionShaped():
158 		output(""), width(1), recipe(), replacements()
159 	{}
CraftDefinitionShaped(const std::string & output_,unsigned int width_,const std::vector<std::string> & recipe_,const CraftReplacements & replacements_)160 	CraftDefinitionShaped(
161 			const std::string &output_,
162 			unsigned int width_,
163 			const std::vector<std::string> &recipe_,
164 			const CraftReplacements &replacements_):
165 		output(output_), width(width_), recipe(recipe_), replacements(replacements_)
166 	{}
~CraftDefinitionShaped()167 	virtual ~CraftDefinitionShaped(){}
168 
169 	virtual std::string getName() const;
170 	virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
171 	virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
172 	virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
173 	virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
174 
175 	virtual std::string dump() const;
176 
177 protected:
178 	virtual void serializeBody(std::ostream &os) const;
179 	virtual void deSerializeBody(std::istream &is, int version);
180 
181 private:
182 	// Output itemstring
183 	std::string output;
184 	// Width of recipe
185 	unsigned int width;
186 	// Recipe matrix (itemstrings)
187 	std::vector<std::string> recipe;
188 	// Replacement items for decrementInput()
189 	CraftReplacements replacements;
190 };
191 
192 /*
193 	A shapeless crafting definition
194 	Supported crafting method: CRAFT_METHOD_NORMAL.
195 	Input items can arranged in any way.
196 */
197 class CraftDefinitionShapeless: public CraftDefinition
198 {
199 public:
CraftDefinitionShapeless()200 	CraftDefinitionShapeless():
201 		output(""), recipe(), replacements()
202 	{}
CraftDefinitionShapeless(const std::string & output_,const std::vector<std::string> & recipe_,const CraftReplacements & replacements_)203 	CraftDefinitionShapeless(
204 			const std::string &output_,
205 			const std::vector<std::string> &recipe_,
206 			const CraftReplacements &replacements_):
207 		output(output_), recipe(recipe_), replacements(replacements_)
208 	{}
~CraftDefinitionShapeless()209 	virtual ~CraftDefinitionShapeless(){}
210 
211 	virtual std::string getName() const;
212 	virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
213 	virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
214 	virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
215 	virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
216 
217 	virtual std::string dump() const;
218 
219 protected:
220 	virtual void serializeBody(std::ostream &os) const;
221 	virtual void deSerializeBody(std::istream &is, int version);
222 
223 private:
224 	// Output itemstring
225 	std::string output;
226 	// Recipe list (itemstrings)
227 	std::vector<std::string> recipe;
228 	// Replacement items for decrementInput()
229 	CraftReplacements replacements;
230 };
231 
232 /*
233 	Tool repair crafting definition
234 	Supported crafting method: CRAFT_METHOD_NORMAL.
235 	Put two damaged tools into the crafting grid, get one tool back.
236 	There should only be one crafting definition of this type.
237 */
238 class CraftDefinitionToolRepair: public CraftDefinition
239 {
240 public:
CraftDefinitionToolRepair()241 	CraftDefinitionToolRepair():
242 		additional_wear(0)
243 	{}
CraftDefinitionToolRepair(float additional_wear_)244 	CraftDefinitionToolRepair(float additional_wear_):
245 		additional_wear(additional_wear_)
246 	{}
~CraftDefinitionToolRepair()247 	virtual ~CraftDefinitionToolRepair(){}
248 
249 	virtual std::string getName() const;
250 	virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
251 	virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
252 	virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
253 	virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
254 
255 	virtual std::string dump() const;
256 
257 protected:
258 	virtual void serializeBody(std::ostream &os) const;
259 	virtual void deSerializeBody(std::istream &is, int version);
260 
261 private:
262 	// This is a constant that is added to the wear of the result.
263 	// May be positive or negative, allowed range [-1,1].
264 	// 1 = new tool is completely broken
265 	// 0 = simply add remaining uses of both input tools
266 	// -1 = new tool is completely pristine
267 	float additional_wear;
268 };
269 
270 /*
271 	A cooking (in furnace) definition
272 	Supported crafting method: CRAFT_METHOD_COOKING.
273 */
274 class CraftDefinitionCooking: public CraftDefinition
275 {
276 public:
CraftDefinitionCooking()277 	CraftDefinitionCooking():
278 		output(""), recipe(""), cooktime()
279 	{}
CraftDefinitionCooking(const std::string & output_,const std::string & recipe_,float cooktime_,const CraftReplacements & replacements_)280 	CraftDefinitionCooking(
281 			const std::string &output_,
282 			const std::string &recipe_,
283 			float cooktime_,
284 			const CraftReplacements &replacements_):
285 		output(output_), recipe(recipe_), cooktime(cooktime_), replacements(replacements_)
286 	{}
~CraftDefinitionCooking()287 	virtual ~CraftDefinitionCooking(){}
288 
289 	virtual std::string getName() const;
290 	virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
291 	virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
292 	virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
293 	virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
294 
295 	virtual std::string dump() const;
296 
297 protected:
298 	virtual void serializeBody(std::ostream &os) const;
299 	virtual void deSerializeBody(std::istream &is, int version);
300 
301 private:
302 	// Output itemstring
303 	std::string output;
304 	// Recipe itemstring
305 	std::string recipe;
306 	// Time in seconds
307 	float cooktime;
308 	// Replacement items for decrementInput()
309 	CraftReplacements replacements;
310 };
311 
312 /*
313 	A fuel (for furnace) definition
314 	Supported crafting method: CRAFT_METHOD_FUEL.
315 */
316 class CraftDefinitionFuel: public CraftDefinition
317 {
318 public:
CraftDefinitionFuel()319 	CraftDefinitionFuel():
320 		recipe(""), burntime()
321 	{}
CraftDefinitionFuel(std::string recipe_,float burntime_,const CraftReplacements & replacements_)322 	CraftDefinitionFuel(std::string recipe_,
323 			float burntime_,
324 			const CraftReplacements &replacements_):
325 		recipe(recipe_), burntime(burntime_), replacements(replacements_)
326 	{}
~CraftDefinitionFuel()327 	virtual ~CraftDefinitionFuel(){}
328 
329 	virtual std::string getName() const;
330 	virtual bool check(const CraftInput &input, IGameDef *gamedef) const;
331 	virtual CraftOutput getOutput(const CraftInput &input, IGameDef *gamedef) const;
332 	virtual CraftInput getInput(const CraftOutput &output, IGameDef *gamedef) const;
333 	virtual void decrementInput(CraftInput &input, IGameDef *gamedef) const;
334 
335 	virtual std::string dump() const;
336 
337 protected:
338 	virtual void serializeBody(std::ostream &os) const;
339 	virtual void deSerializeBody(std::istream &is, int version);
340 
341 private:
342 	// Recipe itemstring
343 	std::string recipe;
344 	// Time in seconds
345 	float burntime;
346 	// Replacement items for decrementInput()
347 	CraftReplacements replacements;
348 };
349 
350 /*
351 	Crafting definition manager
352 */
353 class ICraftDefManager
354 {
355 public:
ICraftDefManager()356 	ICraftDefManager(){}
~ICraftDefManager()357 	virtual ~ICraftDefManager(){}
358 
359 	// The main crafting function
360 	virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
361 			bool decrementInput, IGameDef *gamedef) const=0;
362 	virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
363 			IGameDef *gamedef) const=0;
364 	virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
365 			IGameDef *gamedef) const=0;
366 
367 	// Print crafting recipes for debugging
368 	virtual std::string dump() const=0;
369 
370 	virtual void serialize(std::ostream &os) const=0;
371 };
372 
373 class IWritableCraftDefManager : public ICraftDefManager
374 {
375 public:
IWritableCraftDefManager()376 	IWritableCraftDefManager(){}
~IWritableCraftDefManager()377 	virtual ~IWritableCraftDefManager(){}
378 
379 	// The main crafting function
380 	virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
381 			bool decrementInput, IGameDef *gamedef) const=0;
382 	virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
383 			IGameDef *gamedef) const=0;
384 	virtual std::vector<CraftDefinition*> getCraftRecipes(CraftOutput &output,
385 			IGameDef *gamedef) const=0;
386 
387 	// Print crafting recipes for debugging
388 	virtual std::string dump() const=0;
389 
390 	// Add a crafting definition.
391 	// After calling this, the pointer belongs to the manager.
392 	virtual void registerCraft(CraftDefinition *def)=0;
393 	// Delete all crafting definitions
394 	virtual void clear()=0;
395 
396 	virtual void serialize(std::ostream &os) const=0;
397 	virtual void deSerialize(std::istream &is)=0;
398 };
399 
400 IWritableCraftDefManager* createCraftDefManager();
401 
402 #endif
403 
404