Пример #1
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
				it = input.items.begin();
				it != input.items.end(); it++) {
			if (!it->empty()) {
				all_empty = false;
				break;
			}
		}
		if (all_empty)
			return false;

		std::vector<std::string> input_names;
		input_names = craftGetItemNames(input.items, gamedef);
		std::sort(input_names.begin(), input_names.end());

		// Try hash types with increasing collision rate, and return if found.
		for (int type = 0; type <= craft_hash_type_max; type++) {
			u64 hash = getHashForGrid((CraftHashType) type, input_names);

			/*errorstream << "Checking type " << type << " with hash " << hash << std::endl;*/

			// We'd like to do "const [...] hash_collisions = m_craft_defs[type][hash];"
			// but that doesn't compile for some reason. This does.
			std::map<u64, std::vector<CraftDefinition*> >::const_iterator
				col_iter = (m_craft_defs[type]).find(hash);

			if (col_iter == (m_craft_defs[type]).end())
				continue;

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

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

				if (def->check(input, gamedef)) {
					// Get output, then decrement input (if requested)
					output = def->getOutput(input, gamedef);
					if (decrementInput)
						def->decrementInput(input, gamedef);
					/*errorstream << "Check RETURNS TRUE" << std::endl;*/
					return true;
				}
			}
		}
		return false;
	}
Пример #2
0
u64 CraftDefinitionShapeless::getHash(CraftHashType type) const
{
	assert(hash_inited); // Pre-condition
	assert(type == CRAFT_HASH_TYPE_ITEM_NAMES
		|| type == CRAFT_HASH_TYPE_COUNT); // Pre-condition
	return getHashForGrid(type, recipe_names);
}
Пример #3
0
u64 CraftDefinitionShaped::getHash(CraftHashType type) const
{
	assert(hash_inited); // Pre-condition
	assert((type == CRAFT_HASH_TYPE_ITEM_NAMES)
		|| (type == CRAFT_HASH_TYPE_COUNT)); // Pre-condition

	std::vector<std::string> rec_names = recipe_names;
	std::sort(rec_names.begin(), rec_names.end());
	return getHashForGrid(type, rec_names);
}
Пример #4
0
u64 CraftDefinitionShapeless::getHash(CraftHashType type) const
{
	assert(hash_inited); //pre-condition
	if (type == CRAFT_HASH_TYPE_ITEM_NAMES || type == CRAFT_HASH_TYPE_COUNT) {
		return getHashForGrid(type, recipe_names);
	} else {
		//illegal hash type for this CraftDefinition (pre-condition)
		assert(false);
		return 0;
	}
}
Пример #5
0
u64 CraftDefinitionShaped::getHash(CraftHashType type) const
{
	assert(hash_inited); //pre-condition
	if ((type == CRAFT_HASH_TYPE_ITEM_NAMES) || (type == CRAFT_HASH_TYPE_COUNT)) {
		std::vector<std::string> rec_names = recipe_names;
		std::sort(rec_names.begin(), rec_names.end());
		return getHashForGrid(type, rec_names);
	} else {
		//illegal hash type for this CraftDefinition (pre-condition)
		assert(false);
		return 0;
	}
}
Пример #6
0
	virtual bool getCraftResult(CraftInput &input, CraftOutput &output,
			std::vector<ItemStack> &output_replacement, bool decrementInput,
			IGameDef *gamedef) const
	{
		output.item = "";
		output.time = 0;

		// If all input items are empty, abort.
		bool all_empty = true;
		for (const auto &item : input.items) {
			if (!item.empty()) {
				all_empty = false;
				break;
			}
		}
		if (all_empty)
			return false;

		std::vector<std::string> input_names;
		input_names = craftGetItemNames(input.items, gamedef);
		std::sort(input_names.begin(), input_names.end());

		// Try hash types with increasing collision rate, and return if found.
		for (int type = 0; type <= craft_hash_type_max; type++) {
			u64 hash = getHashForGrid((CraftHashType) type, input_names);

			/*errorstream << "Checking type " << type << " with hash " << hash << std::endl;*/

			// We'd like to do "const [...] hash_collisions = m_craft_defs[type][hash];"
			// but that doesn't compile for some reason. This does.
			auto col_iter = (m_craft_defs[type]).find(hash);

			if (col_iter == (m_craft_defs[type]).end())
				continue;

			const std::vector<CraftDefinition*> &hash_collisions = col_iter->second;
			// Walk crafting definitions from back to front, so that later
			// definitions can override earlier ones.
			for (std::vector<CraftDefinition*>::size_type
					i = hash_collisions.size(); i > 0; i--) {
				CraftDefinition *def = hash_collisions[i - 1];

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

				if (def->check(input, gamedef)) {
					// Check if the crafted node/item exists
					CraftOutput out = def->getOutput(input, gamedef);
					ItemStack is;
					is.deSerialize(out.item, gamedef->idef());
					if (!is.isKnown(gamedef->idef())) {
						infostream << "trying to craft non-existent "
							<< out.item << ", ignoring recipe" << std::endl;
						continue;
					}

					// Get output, then decrement input (if requested)
					output = out;
                    
					if (decrementInput)
						def->decrementInput(input, output_replacement, gamedef);
					/*errorstream << "Check RETURNS TRUE" << std::endl;*/
					return true;
				}
			}
		}
		return false;
	}