summaryrefslogtreecommitdiff
path: root/src/craftdef.cpp
Commit message (Collapse)AuthorAge
* Overall improvements to log messages (#9598)sfan52020-04-08
| | | | Hide some unnecessarily verbose ones behind --trace or disable them entirely. Remove duplicate ones. Improve their contents in some places.
* Fix some issues with minetest.clear_craft (#8712)Paul Ouellette2019-08-10
| | | | | | | | | | | * Fix some issues with minetest.clear_craft - Fix memory leak - Fix crafts with an output count not being cleared when clearing by input. - Fix recipe list being reversed when clearing by input. * Add CraftInput::empty()
* Prefix RecipePriority elements with PRIORITY_Paul Ouellette2019-07-27
|
* Initialize priority in CraftDefinition constructorsPaul Ouellette2019-07-27
| | | | | The priority is used by getCraftResult, which may be used before initHash is called.
* Prioritise craft recipesHybridDog2019-05-20
| | | | | | When multiple recipes are applicable, the recipes are prioritised in this order: toolrepair < shapeless with groups < shapeless < shaped with groups < shaped For cooking and fuel, items are prioritised over item groups
* Test crafting hash type only once for a recipeHybridDog2019-05-20
|
* Use unordered_map instead of map for craft definitions (#8432)HybridDog2019-03-31
|
* Speed up the craft definition handling (#8097)Jozef Behran2019-01-13
| | | | | | | | | | | The craft definition handling code that collects the names of the craftable nodes suffers from vector reallocation performance hits, slowing down instances with lots of crafting recipes (VanessaE's DreamBuilder and most public server some to my mind when thinking about this). As in each instance the size of the resulting vector is already known, add a reserve() call before the offending loops to allocate the needed chunk of memory within the result vector in one go, getting rid of the overhead.
* Add disable_repair group to prevent tool repair (#7381)Wuzzy2018-10-16
|
* Don't try to craft a non-existent itemEsteban I. RM2017-10-16
|
* Modernize code: very last fixes (#6290)Loïc Blot2017-08-20
| | | Last modernization fixes
* Modernize src/c* src/d* and src/e* files (#6263)Loïc Blot2017-08-17
| | | | | | | | | | | | | | | | | * Modernize src/c* src/d* and src/e* files * default operator * redundant init * delete default constructors on CraftDefinition childs (never used) * fix some missing init values * const ref fix reported by clang-tidy * ranged-based for loops * simple conditions & returns * empty stl function instead of size * emplace_back stl function instead of push_back + construct temp obj * auto for some iterators * code style fixes * c++ stl headers instead of C stl headers (stdio.h -> cstdio)
* Add ItemStack key-value meta storagerubenwardy2017-02-04
|
* Adding minetest.clear_craftFoghrye42016-07-05
| | | | | Modifications by est31: grammar fixes in doc + error messages and a little style fix, no functional change.
* Clean up StrfndShadowNinja2016-03-19
| | | | | | | | | | | Changes: * Fix indentation. * Pass strings by const reference. * Merge Strfnd and WStrfnd into one class instead of copying them. * Remove trailing spaces. * Fix variable names. * Move to util. * Other miscellaneous style fixes.
* Allow craft replacements to use groupsTeTpaAka2015-11-15
|
* Change i++ to ++iDavid Jones2015-08-25
|
* Fix endless loop since grandparent commitest312015-07-04
|
* Craftdef: Use numbers instead of iteratorsest312015-07-04
| | | | Use numbers instead of iterators to traverse various vectors.
* Fix missing check for 0 in craft replacementsTeTpaAka2015-07-04
|
* Fix bug when craft input isn't replacedTeTpaAka2015-06-22
|
* Fix release build warningest312015-05-08
|
* Remove craftdef serialisationest312015-04-26
| | | | | It isn't needed anymore, sending ICraftDefManager over the network has been obsoleted by protocol version 7.
* Craftdef refactorest312015-04-26
| | | | | Fix style, refactor assert, use '"' instead of "\"", replace code duplicating craftGetItemName, rename iterators.
* craftdef.cpp: Return 0 after assert to make Clang happyLoic Blot2015-04-05
|
* Crafting speedupest312015-04-05
| | | | | | | | | | | | | | | This greatly increases crafting performance, especially in worlds with many mods. Approved by @kwolekr. Introduces a hash-type-layered fall-through mechanism, where every layer specifies one hash algorithm, and the "deeper the fall", the more collisions to expect for the algorithm. One Craft definition only resides at one layer, which improves speed for lower layers (and a complete fail), due to most craft definitions residing at high layers. Due to the fall-through design, the undocumented behaviour that later craft recipes override older ones had to be weaked up a bit, but craft recipes with the same hash and layer will still override.
* Optimize minetest.get_(all)_craft_recipe(s)gregorycu2015-03-20
| | | | Signed off by: ShadowNinja, kwolekr
* Craftdef.cpp: Improve loop and mathematics for CraftDefinitionShaped::checkLoic Blot2015-02-10
|
* Fix getCraftRecipe returing wrong reciep due to way to unspecific output ↵sapier2015-02-02
| | | | matching
* Fix aliases not working in shapeless crafting recipesKahrl2013-08-25
|
* Omnicleanup: header cleanup, add ModApiUtil shared between game and mainmenuKahrl2013-08-14
|
* Added method to get all registered recipes for item(node)RealBadAngel2013-03-05
|
* Update Copyright YearsSfan52013-02-24
|
* Change Minetest-c55 to MinetestPilzAdam2013-02-24
|
* Working group-shapeless and multigroup recipesPerttu Ahola2012-07-26
|
* Add minetest.get_craft_recipe()darkrose2012-07-21
|
* Properly and efficiently use split utility headersPerttu Ahola2012-06-17
|
* Allow groups in crafting recipesPerttu Ahola2012-06-06
|
* Allow replacements in cooking and fuel recipesKahrl2012-06-06
|
* Switch the license to be LGPLv2/later, with small parts still remaining as ↵Perttu Ahola2012-06-05
| | | | GPLv2/later, by agreement of major contributors
* Clean up log messages everywherePerttu Ahola2012-03-11
|
* The huge item definition and item namespace unification patch (itemdef), see ↵Kahrl2012-01-12
| | | | http://c55.me/minetest/wiki/doku.php?id=changes:itemdef
* Add InvRef and InvStack (currently untested and unusable)Perttu Ahola2012-01-02
|
* Catch SerializationError in CCraftDefManager::getCraftResult()Perttu Ahola2011-11-29
|
* Crafting definition in scriptsPerttu Ahola2011-11-29
span class="hl opt">; if (conf.exists("author")) game_author = conf.get("author"); int game_release = 0; if (conf.exists("release")) game_release = conf.getS32("release"); std::string menuicon_path; #ifndef SERVER menuicon_path = getImagePath( game_path + DIR_DELIM + "menu" + DIR_DELIM + "icon.png"); #endif return SubgameSpec(id, game_path, gamemod_path, mods_paths, game_name, menuicon_path, game_author, game_release); } SubgameSpec findWorldSubgame(const std::string &world_path) { std::string world_gameid = getWorldGameId(world_path, true); // See if world contains an embedded game; if so, use it. std::string world_gamepath = world_path + DIR_DELIM + "game"; if (fs::PathExists(world_gamepath)) { SubgameSpec gamespec; gamespec.id = world_gameid; gamespec.path = world_gamepath; gamespec.gamemods_path = world_gamepath + DIR_DELIM + "mods"; Settings conf; std::string conf_path = world_gamepath + DIR_DELIM + "game.conf"; conf.readConfigFile(conf_path.c_str()); if (conf.exists("name")) gamespec.name = conf.get("name"); else gamespec.name = world_gameid; return gamespec; } return findSubgame(world_gameid); } std::set<std::string> getAvailableGameIds() { std::set<std::string> gameids; std::set<std::string> gamespaths; gamespaths.insert(porting::path_share + DIR_DELIM + "games"); gamespaths.insert(porting::path_user + DIR_DELIM + "games"); Strfnd search_paths(getSubgamePathEnv()); while (!search_paths.at_end()) gamespaths.insert(search_paths.next(PATH_DELIM)); for (const std::string &gamespath : gamespaths) { std::vector<fs::DirListNode> dirlist = fs::GetDirListing(gamespath); for (const fs::DirListNode &dln : dirlist) { if (!dln.dir) continue; // If configuration file is not found or broken, ignore game Settings conf; std::string conf_path = gamespath + DIR_DELIM + dln.name + DIR_DELIM + "game.conf"; if (!conf.readConfigFile(conf_path.c_str())) continue; // Add it to result const char *ends[] = {"_game", NULL}; std::string shorter = removeStringEnd(dln.name, ends); if (!shorter.empty()) gameids.insert(shorter); else gameids.insert(dln.name); } } return gameids; } std::vector<SubgameSpec> getAvailableGames() { std::vector<SubgameSpec> specs; std::set<std::string> gameids = getAvailableGameIds(); specs.reserve(gameids.size()); for (const auto &gameid : gameids) specs.push_back(findSubgame(gameid)); return specs; } #define LEGACY_GAMEID "minetest" bool getWorldExists(const std::string &world_path) { return (fs::PathExists(world_path + DIR_DELIM + "map_meta.txt") || fs::PathExists(world_path + DIR_DELIM + "world.mt")); } //! Try to get the displayed name of a world std::string getWorldName(const std::string &world_path, const std::string &default_name) { std::string conf_path = world_path + DIR_DELIM + "world.mt"; Settings conf; bool succeeded = conf.readConfigFile(conf_path.c_str()); if (!succeeded) { return default_name; } if (!conf.exists("world_name")) return default_name; return conf.get("world_name"); } std::string getWorldGameId(const std::string &world_path, bool can_be_legacy) { std::string conf_path = world_path + DIR_DELIM + "world.mt"; Settings conf; bool succeeded = conf.readConfigFile(conf_path.c_str()); if (!succeeded) { if (can_be_legacy) { // If map_meta.txt exists, it is probably an old minetest world if (fs::PathExists(world_path + DIR_DELIM + "map_meta.txt")) return LEGACY_GAMEID; } return ""; } if (!conf.exists("gameid")) return ""; // The "mesetint" gameid has been discarded if (conf.get("gameid") == "mesetint") return "minetest"; return conf.get("gameid"); } std::string getWorldPathEnv() { char *world_path = getenv("MINETEST_WORLD_PATH"); return world_path ? std::string(world_path) : ""; } std::vector<WorldSpec> getAvailableWorlds() { std::vector<WorldSpec> worlds; std::set<std::string> worldspaths; Strfnd search_paths(getWorldPathEnv()); while (!search_paths.at_end()) worldspaths.insert(search_paths.next(PATH_DELIM)); worldspaths.insert(porting::path_user + DIR_DELIM + "worlds"); infostream << "Searching worlds..." << std::endl; for (const std::string &worldspath : worldspaths) { infostream << " In " << worldspath << ": "; std::vector<fs::DirListNode> dirvector = fs::GetDirListing(worldspath); for (const fs::DirListNode &dln : dirvector) { if (!dln.dir) continue; std::string fullpath = worldspath + DIR_DELIM + dln.name; std::string name = getWorldName(fullpath, dln.name); // Just allow filling in the gameid always for now bool can_be_legacy = true; std::string gameid = getWorldGameId(fullpath, can_be_legacy); WorldSpec spec(fullpath, name, gameid); if (!spec.isValid()) { infostream << "(invalid: " << name << ") "; } else { infostream << name << " "; worlds.push_back(spec); } } infostream << std::endl; } // Check old world location do { std::string fullpath = porting::path_user + DIR_DELIM + "world"; if (!fs::PathExists(fullpath)) break; std::string name = "Old World"; std::string gameid = getWorldGameId(fullpath, true); WorldSpec spec(fullpath, name, gameid); infostream << "Old world found." << std::endl; worlds.push_back(spec); } while (false); infostream << worlds.size() << " found." << std::endl; return worlds; } void loadGameConfAndInitWorld(const std::string &path, const std::string &name, const SubgameSpec &gamespec, bool create_world) { std::string final_path = path; // If we're creating a new world, ensure that the path isn't already taken if (create_world) { int counter = 1; while (fs::PathExists(final_path) && counter < MAX_WORLD_NAMES) { final_path = path + "_" + std::to_string(counter); counter++; } if (fs::PathExists(final_path)) { throw BaseException("Too many similar filenames"); } } Settings *game_settings = Settings::getLayer(SL_GAME); const bool new_game_settings = (game_settings == nullptr); if (new_game_settings) { // Called by main-menu without a Server instance running // -> create and free manually game_settings = Settings::createLayer(SL_GAME); } getGameMinetestConfig(gamespec.path, *game_settings); game_settings->removeSecureSettings(); infostream << "Initializing world at " << final_path << std::endl; fs::CreateAllDirs(final_path); // Create world.mt if does not already exist std::string worldmt_path = final_path + DIR_DELIM "world.mt"; if (!fs::PathExists(worldmt_path)) { Settings conf; conf.set("world_name", name); conf.set("gameid", gamespec.id); conf.set("backend", "sqlite3"); conf.set("player_backend", "sqlite3"); conf.set("auth_backend", "sqlite3"); conf.setBool("creative_mode", g_settings->getBool("creative_mode")); conf.setBool("enable_damage", g_settings->getBool("enable_damage")); if (!conf.updateConfigFile(worldmt_path.c_str())) { throw BaseException("Failed to update the config file"); } } // Create map_meta.txt if does not already exist std::string map_meta_path = final_path + DIR_DELIM + "map_meta.txt"; if (!fs::PathExists(map_meta_path)) { verbosestream << "Creating map_meta.txt (" << map_meta_path << ")" << std::endl; std::ostringstream oss(std::ios_base::binary); Settings conf; MapgenParams params; params.readParams(g_settings); params.writeParams(&conf); conf.writeLines(oss); oss << "[end_of_params]\n"; fs::safeWriteToFile(map_meta_path, oss.str()); } // The Settings object is no longer needed for created worlds if (new_game_settings) delete game_settings; }