3 Copyright (C) 2011 celeron55, Perttu Ahola <celeron55@gmail.com>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License along
16 with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 #include "irrlichttypes.h"
27 #include "inventory.h"
28 #include "inventorymanager.h" // checkItemCombination
30 CraftPointerInput::~CraftPointerInput()
32 for(u32 i=0; i<items.size(); i++)
36 CraftPointerInput createPointerInput(const CraftInput &ci, IGameDef *gamedef)
38 std::vector<InventoryItem*> items;
39 for(u32 i=0; i<ci.items.size(); i++){
40 InventoryItem *item = NULL;
41 if(ci.items[i] != ""){
42 std::istringstream iss(ci.items[i], std::ios::binary);
43 item = InventoryItem::deSerialize(iss, gamedef);
45 items.push_back(item);
47 return CraftPointerInput(ci.width, items);
50 CraftInput createInput(const CraftPointerInput &cpi)
52 std::vector<std::string> items;
53 for(u32 i=0; i<cpi.items.size(); i++){
54 if(cpi.items[i] == NULL)
57 std::ostringstream oss(std::ios::binary);
58 cpi.items[i]->serialize(oss);
59 items.push_back(oss.str());
62 return CraftInput(cpi.width, items);
65 std::string CraftInput::dump() const
67 std::ostringstream os(std::ios::binary);
68 os<<"(width="<<width<<"){";
69 for(u32 i=0; i<items.size(); i++)
70 os<<"\""<<items[i]<<"\",";
75 std::string CraftDefinition::dump() const
77 std::ostringstream os(std::ios::binary);
78 os<<"{output=\""<<output<<"\", input={";
79 for(u32 i=0; i<input.items.size(); i++)
80 os<<"\""<<input.items[i]<<"\",";
81 os<<"}, (input.width="<<input.width<<")}";
85 void CraftDefinition::serialize(std::ostream &os) const
87 writeU8(os, 0); // version
88 os<<serializeString(output);
89 writeU8(os, input.width);
90 writeU16(os, input.items.size());
91 for(u32 i=0; i<input.items.size(); i++)
92 os<<serializeString(input.items[i]);
95 void CraftDefinition::deSerialize(std::istream &is)
97 int version = readU8(is);
98 if(version != 0) throw SerializationError(
99 "unsupported CraftDefinition version");
100 output = deSerializeString(is);
101 input.width = readU8(is);
102 u32 count = readU16(is);
103 for(u32 i=0; i<count; i++)
104 input.items.push_back(deSerializeString(is));
107 class CCraftDefManager: public IWritableCraftDefManager
110 virtual ~CCraftDefManager()
114 virtual InventoryItem* getCraftResult(const CraftPointerInput &input_cpi,
115 IGameDef *gamedef) const
117 if(input_cpi.width > 3){
118 errorstream<<"getCraftResult(): ERROR: "
119 <<"input_cpi.width > 3; Failing to craft."<<std::endl;
122 InventoryItem *input_items[9];
123 for(u32 y=0; y<3; y++)
124 for(u32 x=0; x<3; x++)
127 if(x >= input_cpi.width || y >= input_cpi.height())
128 input_items[i] = NULL;
130 input_items[i] = input_cpi.items[y*input_cpi.width+x];
132 for(core::list<CraftDefinition*>::ConstIterator
133 i = m_craft_definitions.begin();
134 i != m_craft_definitions.end(); i++)
136 CraftDefinition *def = *i;
138 /*infostream<<"Checking "<<createInput(input_cpi).dump()<<std::endl
139 <<" against "<<def->input.dump()
140 <<" (output=\""<<def->output<<"\")"<<std::endl;*/
143 CraftPointerInput spec_cpi = createPointerInput(def->input, gamedef);
144 if(spec_cpi.width > 3){
145 errorstream<<"getCraftResult: ERROR: "
146 <<"spec_cpi.width > 3 in recipe "
147 <<def->dump()<<std::endl;
150 InventoryItem *spec_items[9];
151 for(u32 y=0; y<3; y++)
152 for(u32 x=0; x<3; x++)
155 if(x >= spec_cpi.width || y >= spec_cpi.height())
156 spec_items[i] = NULL;
158 spec_items[i] = spec_cpi.items[y*spec_cpi.width+x];
161 bool match = checkItemCombination(input_items, spec_items);
164 std::istringstream iss(def->output, std::ios::binary);
165 return InventoryItem::deSerialize(iss, gamedef);
168 catch(SerializationError &e)
170 errorstream<<"getCraftResult: ERROR: "
171 <<"Serialization error in recipe "
172 <<def->dump()<<std::endl;
173 // then go on with the next craft definition
178 virtual void registerCraft(const CraftDefinition &def)
180 infostream<<"registerCraft: registering craft definition: "
181 <<def.dump()<<std::endl;
182 if(def.input.width > 3 || def.input.height() > 3){
183 errorstream<<"registerCraft: input size is larger than 3x3,"
184 <<" ignoring"<<std::endl;
187 m_craft_definitions.push_back(new CraftDefinition(def));
191 for(core::list<CraftDefinition*>::Iterator
192 i = m_craft_definitions.begin();
193 i != m_craft_definitions.end(); i++){
196 m_craft_definitions.clear();
198 virtual void serialize(std::ostream &os)
200 writeU8(os, 0); // version
201 u16 count = m_craft_definitions.size();
203 for(core::list<CraftDefinition*>::Iterator
204 i = m_craft_definitions.begin();
205 i != m_craft_definitions.end(); i++){
206 CraftDefinition *def = *i;
207 // Serialize wrapped in a string
208 std::ostringstream tmp_os(std::ios::binary);
209 def->serialize(tmp_os);
210 os<<serializeString(tmp_os.str());
213 virtual void deSerialize(std::istream &is)
218 int version = readU8(is);
219 if(version != 0) throw SerializationError(
220 "unsupported CraftDefManager version");
221 u16 count = readU16(is);
222 for(u16 i=0; i<count; i++){
223 // Deserialize a string and grab a CraftDefinition from it
224 std::istringstream tmp_is(deSerializeString(is), std::ios::binary);
226 def.deSerialize(tmp_is);
232 core::list<CraftDefinition*> m_craft_definitions;
235 IWritableCraftDefManager* createCraftDefManager()
237 return new CCraftDefManager();