Exemplo n.º 1
0
	virtual void registerCraft(const CraftDefinition &def)
	{
		infostream<<"registerCraft: registering craft definition: "
				<<def.dump()<<std::endl;
		if(def.input.width > 3 || def.input.height() > 3){
			errorstream<<"registerCraft: input size is larger than 3x3,"
					<<" ignoring"<<std::endl;
			return;
		}
		m_craft_definitions.push_back(new CraftDefinition(def));
	}
Exemplo n.º 2
0
	virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
			bool decrementInput, IGameDef *gamedef) const
	{
		output.item = "";
		output.time = 0;

		// If all input items are empty, abort.
		bool all_empty = true;
		for(std::vector<ItemStack>::const_iterator
				i = input.items.begin();
				i != input.items.end(); i++)
		{
			if(!i->empty())
			{
				all_empty = false;
				break;
			}
		}
		if(all_empty)
			return false;

		// Walk crafting definitions from back to front, so that later
		// definitions can override earlier ones.
		for(std::vector<CraftDefinition*>::const_reverse_iterator
				i = m_craft_definitions.rbegin();
				i != m_craft_definitions.rend(); i++)
		{
			CraftDefinition *def = *i;

			/*infostream<<"Checking "<<input.dump()<<std::endl
					<<" against "<<def->dump()<<std::endl;*/

			try {
				if(def->check(input, gamedef))
				{
					// Get output, then decrement input (if requested)
					output = def->getOutput(input, gamedef);
					if(decrementInput)
						def->decrementInput(input, gamedef);
					return true;
				}
			}
			catch(SerializationError &e)
			{
				errorstream<<"getCraftResult: ERROR: "
						<<"Serialization error in recipe "
						<<def->dump()<<std::endl;
				// then go on with the next craft definition
			}
		}
		return false;
	}
Exemplo n.º 3
0
	virtual bool getCraftRecipe(CraftInput &input, CraftOutput &output,
			IGameDef *gamedef) const
	{
		CraftOutput tmpout;
		tmpout.item = "";
		tmpout.time = 0;

		// If output item is empty, abort.
		if(output.item.empty())
			return false;

		// Walk crafting definitions from back to front, so that later
		// definitions can override earlier ones.
		for(std::vector<CraftDefinition*>::const_reverse_iterator
				i = m_craft_definitions.rbegin();
				i != m_craft_definitions.rend(); i++)
		{
			CraftDefinition *def = *i;

			/*infostream<<"Checking "<<input.dump()<<std::endl
					<<" against "<<def->dump()<<std::endl;*/

			try {
				tmpout = def->getOutput(input, gamedef);
				if(tmpout.item.substr(0,output.item.length()) == output.item)
				{
					// Get output, then decrement input (if requested)
					input = def->getInput(output, gamedef);
					return true;
				}
			}
			catch(SerializationError &e)
			{
				errorstream<<"getCraftResult: ERROR: "
						<<"Serialization error in recipe "
						<<def->dump()<<std::endl;
				// then go on with the next craft definition
			}
		}
		return false;
	}
Exemplo n.º 4
0
	virtual InventoryItem* getCraftResult(const CraftPointerInput &input_cpi,
			IGameDef *gamedef) const
	{
		if(input_cpi.width > 3){
			errorstream<<"getCraftResult(): ERROR: "
					<<"input_cpi.width > 3; Failing to craft."<<std::endl;
			return NULL;
		}
		InventoryItem *input_items[9];
		for(u32 y=0; y<3; y++)
		for(u32 x=0; x<3; x++)
		{
			u32 i=y*3+x;
			if(x >= input_cpi.width || y >= input_cpi.height())
				input_items[i] = NULL;
			else
				input_items[i] = input_cpi.items[y*input_cpi.width+x];
		}
		for(core::list<CraftDefinition*>::ConstIterator
				i = m_craft_definitions.begin();
				i != m_craft_definitions.end(); i++)
		{
			CraftDefinition *def = *i;

			/*infostream<<"Checking "<<createInput(input_cpi).dump()<<std::endl
					<<" against "<<def->input.dump()
					<<" (output=\""<<def->output<<"\")"<<std::endl;*/

			try {
				CraftPointerInput spec_cpi = createPointerInput(def->input, gamedef);
				if(spec_cpi.width > 3){
					errorstream<<"getCraftResult: ERROR: "
							<<"spec_cpi.width > 3 in recipe "
							<<def->dump()<<std::endl;
					continue;
				}
				InventoryItem *spec_items[9];
				for(u32 y=0; y<3; y++)
				for(u32 x=0; x<3; x++)
				{
					u32 i=y*3+x;
					if(x >= spec_cpi.width || y >= spec_cpi.height())
						spec_items[i] = NULL;
					else
						spec_items[i] = spec_cpi.items[y*spec_cpi.width+x];
				}

				bool match = checkItemCombination(input_items, spec_items);

				if(match){
					std::istringstream iss(def->output, std::ios::binary);
					return InventoryItem::deSerialize(iss, gamedef);
				}
			}
			catch(SerializationError &e)
			{
				errorstream<<"getCraftResult: ERROR: "
						<<"Serialization error in recipe "
						<<def->dump()<<std::endl;
				// then go on with the next craft definition
			}
		}
		return NULL;
	}