diff --git a/common/eq_constants.h b/common/eq_constants.h index 39ba461f0..2ab28bdca 100644 --- a/common/eq_constants.h +++ b/common/eq_constants.h @@ -1028,6 +1028,15 @@ enum ZoningMessage : int8 ZoneNoExperience = -7 }; +enum class RecipeCountType : uint8 +{ + Component, + Container, + Fail, + Salvage, + Success +}; + #define ALT_CURRENCY_ID_RADIANT 4 #define ALT_CURRENCY_ID_EBON 5 diff --git a/zone/embparser_api.cpp b/zone/embparser_api.cpp index b46a4c920..1342ddf54 100644 --- a/zone/embparser_api.cpp +++ b/zone/embparser_api.cpp @@ -3986,6 +3986,111 @@ int8 Perl__does_augment_fit_slot(EQ::ItemInstance* inst, uint32 augment_id, uint return quest_manager.DoesAugmentFit(inst, augment_id, augment_slot); } +perl::array Perl__GetRecipeComponentItemIDs(uint32 recipe_id) +{ + perl::array result; + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Component, recipe_id); + + if (!l.empty()) { + result.reserve(l.size()); + + for (int i = 0; i < l.size(); i++) { + result.push_back(l[i]); + } + } + + return result; +} + +perl::array Perl__GetRecipeContainerItemIDs(uint32 recipe_id) +{ + perl::array result; + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Container, recipe_id); + + if (!l.empty()) { + result.reserve(l.size()); + + for (int i = 0; i < l.size(); i++) { + result.push_back(l[i]); + } + } + + return result; +} + +perl::array Perl__GetRecipeFailItemIDs(uint32 recipe_id) +{ + perl::array result; + + const auto &l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Fail, recipe_id); + + if (!l.empty()) { + result.reserve(l.size()); + + for (int i = 0; i < l.size(); i++) { + result.push_back(l[i]); + } + } + + return result; +} + +perl::array Perl__GetRecipeSalvageItemIDs(uint32 recipe_id) +{ + perl::array result; + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Salvage, recipe_id); + + if (!l.empty()) { + result.reserve(l.size()); + + for (int i = 0; i < l.size(); i++) { + result.push_back(l[i]); + } + } + + return result; +} + +perl::array Perl__GetRecipeSuccessItemIDs(uint32 recipe_id) +{ + perl::array result; + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Success, recipe_id); + + if (!l.empty()) { + result.reserve(l.size()); + + for (int i = 0; i < l.size(); i++) { + result.push_back(l[i]); + } + } + + return result; +} + +int8 Perl__GetRecipeComponentCount(uint32 recipe_id, uint32 item_id) +{ + return content_db.GetRecipeComponentCount(RecipeCountType::Component, recipe_id, item_id); +} + +int8 Perl__GetRecipeFailCount(uint32 recipe_id, uint32 item_id) +{ + return content_db.GetRecipeComponentCount(RecipeCountType::Fail, recipe_id, item_id); +} + +int8 Perl__GetRecipeSalvageCount(uint32 recipe_id, uint32 item_id) +{ + return content_db.GetRecipeComponentCount(RecipeCountType::Salvage, recipe_id, item_id); +} + +int8 Perl__GetRecipeSuccessCount(uint32 recipe_id, uint32 item_id) +{ + return content_db.GetRecipeComponentCount(RecipeCountType::Success, recipe_id, item_id); +} + void perl_register_quest() { perl::interpreter perl(PERL_GET_THX); @@ -4396,6 +4501,15 @@ void perl_register_quest() package.add("getgroupidbycharid", &Perl__getgroupidbycharid); package.add("getinventoryslotname", &Perl__getinventoryslotname); package.add("getraididbycharid", &Perl__getraididbycharid); + package.add("get_recipe_component_item_ids", &Perl__GetRecipeComponentItemIDs); + package.add("get_recipe_container_item_ids", &Perl__GetRecipeContainerItemIDs); + package.add("get_recipe_fail_item_ids", &Perl__GetRecipeFailItemIDs); + package.add("get_recipe_salvage_item_ids", &Perl__GetRecipeSalvageItemIDs); + package.add("get_recipe_success_item_ids", &Perl__GetRecipeSuccessItemIDs); + package.add("get_recipe_component_count", &Perl__GetRecipeComponentCount); + package.add("get_recipe_fail_count", &Perl__GetRecipeFailCount); + package.add("get_recipe_salvage_count", &Perl__GetRecipeSalvageCount); + package.add("get_recipe_success_count", &Perl__GetRecipeSuccessCount); package.add("getracename", &Perl__getracename); package.add("getremainingtimeMS", &Perl__getremainingtimeMS); package.add("getspell", &Perl__getspell); diff --git a/zone/lua_general.cpp b/zone/lua_general.cpp index 7d0396ff2..0b4f5b035 100644 --- a/zone/lua_general.cpp +++ b/zone/lua_general.cpp @@ -3705,6 +3705,104 @@ int8 lua_does_augment_fit_slot(Lua_ItemInst inst, uint32 augment_id, uint8 augme return quest_manager.DoesAugmentFit(inst, augment_id, augment_slot); } +luabind::object lua_get_recipe_component_item_ids(lua_State* L, uint32 recipe_id) +{ + auto lua_table = luabind::newtable(L); + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Component, recipe_id); + if (!l.empty()) { + int index = 1; + for (const auto& i : l) { + lua_table[index] = i; + index++; + } + } + + return lua_table; +} + +luabind::object lua_get_recipe_container_item_ids(lua_State* L, uint32 recipe_id) +{ + auto lua_table = luabind::newtable(L); + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Container, recipe_id); + if (!l.empty()) { + int index = 1; + for (const auto& i : l) { + lua_table[index] = i; + index++; + } + } + + return lua_table; +} + +luabind::object lua_get_recipe_fail_item_ids(lua_State* L, uint32 recipe_id) +{ + auto lua_table = luabind::newtable(L); + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Fail, recipe_id); + if (!l.empty()) { + int index = 1; + for (const auto& i : l) { + lua_table[index] = i; + index++; + } + } + + return lua_table; +} + +luabind::object lua_get_recipe_salvage_item_ids(lua_State* L, uint32 recipe_id) { + auto lua_table = luabind::newtable(L); + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Salvage, recipe_id); + if (!l.empty()) { + int index = 1; + for (const auto& i : l) { + lua_table[index] = i; + index++; + } + } + + return lua_table; +} + +luabind::object lua_get_recipe_success_item_ids(lua_State* L, uint32 recipe_id) { + auto lua_table = luabind::newtable(L); + + const auto& l = content_db.GetRecipeComponentItemIDs(RecipeCountType::Success, recipe_id); + if (!l.empty()) { + int index = 1; + for (const auto& i : l) { + lua_table[index] = i; + index++; + } + } + + return lua_table; +} + +int8 lua_get_recipe_component_count(uint32 recipe_id, uint32 item_id) +{ + return content_db.GetRecipeComponentCount(RecipeCountType::Component, recipe_id, item_id); +} + +int8 lua_get_recipe_fail_count(uint32 recipe_id, uint32 item_id) +{ + return content_db.GetRecipeComponentCount(RecipeCountType::Fail, recipe_id, item_id); +} + +int8 lua_get_recipe_salvage_count(uint32 recipe_id, uint32 item_id) +{ + return content_db.GetRecipeComponentCount(RecipeCountType::Salvage, recipe_id, item_id); +} + +int8 lua_get_recipe_success_count(uint32 recipe_id, uint32 item_id) +{ + return content_db.GetRecipeComponentCount(RecipeCountType::Success, recipe_id, item_id); +} + #define LuaCreateNPCParse(name, c_type, default_value) do { \ cur = table[#name]; \ if(luabind::type(cur) != LUA_TNIL) { \ @@ -4224,6 +4322,15 @@ luabind::scope lua_register_general() { luabind::def("do_augment_slots_match", &lua_do_augment_slots_match), luabind::def("does_augment_fit", (int8(*)(Lua_ItemInst, uint32))&lua_does_augment_fit), luabind::def("does_augment_fit_slot", (int8(*)(Lua_ItemInst, uint32, uint8))&lua_does_augment_fit_slot), + luabind::def("get_recipe_component_item_ids", (luabind::object(*)(lua_State*,uint32))&lua_get_recipe_component_item_ids), + luabind::def("get_recipe_container_item_ids", (luabind::object(*)(lua_State*,uint32))&lua_get_recipe_container_item_ids), + luabind::def("get_recipe_fail_item_ids", (luabind::object(*)(lua_State*,uint32))&lua_get_recipe_fail_item_ids), + luabind::def("get_recipe_salvage_item_ids", (luabind::object(*)(lua_State*,uint32))&lua_get_recipe_salvage_item_ids), + luabind::def("get_recipe_success_item_ids", (luabind::object(*)(lua_State*,uint32))&lua_get_recipe_success_item_ids), + luabind::def("get_recipe_component_count", (int8(*)(uint32,uint32))&lua_get_recipe_component_count), + luabind::def("get_recipe_fail_count", (int8(*)(uint32,uint32))&lua_get_recipe_fail_count), + luabind::def("get_recipe_salvage_count", (int8(*)(uint32,uint32))&lua_get_recipe_salvage_count), + luabind::def("get_recipe_success_count", (int8(*)(uint32,uint32))&lua_get_recipe_success_count), /* Cross Zone */ diff --git a/zone/tradeskills.cpp b/zone/tradeskills.cpp index 69f3e5bbb..52ec95947 100644 --- a/zone/tradeskills.cpp +++ b/zone/tradeskills.cpp @@ -36,6 +36,7 @@ #include "../common/repositories/char_recipe_list_repository.h" #include "../common/zone_store.h" #include "../common/repositories/tradeskill_recipe_repository.h" +#include "../common/repositories/tradeskill_recipe_entries_repository.h" extern QueryServ* QServ; @@ -1634,6 +1635,86 @@ void Client::LearnRecipe(uint32 recipe_id) ); } +std::vector ZoneDatabase::GetRecipeComponentItemIDs(RecipeCountType count_type, uint32 recipe_id) +{ + std::vector l; + + const auto& tr = TradeskillRecipeRepository::FindOne(content_db, recipe_id); + if (!tr.id) { + return l; + } + + std::string c; + switch (count_type) { + case RecipeCountType::Success: + c = "successcount"; + break; + case RecipeCountType::Fail: + c = "failcount"; + break; + case RecipeCountType::Component: + c = "componentcount"; + break; + case RecipeCountType::Salvage: + c = "salvagecount"; + break; + case RecipeCountType::Container: + c = "iscontainer"; + break; + } + + const auto& tre = TradeskillRecipeEntriesRepository::GetWhere( + content_db, + fmt::format( + "recipe_id = {} AND {} >= 1 ORDER BY id ASC", + recipe_id, + c + ) + ); + if (tre.empty()) { + return l; + } + + for (const auto& e : tre) { + l.emplace_back(e.item_id); + } + + return l; +} + +int8 ZoneDatabase::GetRecipeComponentCount(RecipeCountType count_type, uint32 recipe_id, uint32 item_id) +{ + const auto& tr = TradeskillRecipeRepository::FindOne(content_db, recipe_id); + if (!tr.id) { + return -1; + } + + const auto& tre = TradeskillRecipeEntriesRepository::GetWhere( + content_db, + fmt::format( + "recipe_id = {} AND item_id = {} ORDER BY id ASC LIMIT 1", + recipe_id, + item_id + ) + ); + if (tre.empty()) { + return -1; + } + + switch (count_type) { + case RecipeCountType::Success: + return tre[0].successcount; + case RecipeCountType::Fail: + return tre[0].failcount; + case RecipeCountType::Component: + return tre[0].componentcount; + case RecipeCountType::Salvage: + return tre[0].salvagecount; + default: + return -1; + } +} + bool Client::CanIncreaseTradeskill(EQ::skills::SkillType tradeskill) { uint32 rawskill = GetRawSkill(tradeskill); uint16 maxskill = MaxSkill(tradeskill); diff --git a/zone/zonedb.h b/zone/zonedb.h index 56d67849c..2256ca90d 100644 --- a/zone/zonedb.h +++ b/zone/zonedb.h @@ -563,6 +563,8 @@ public: void UpdateRecipeMadecount(uint32 recipe_id, uint32 char_id, uint32 madecount); bool EnableRecipe(uint32 recipe_id); bool DisableRecipe(uint32 recipe_id); + std::vector GetRecipeComponentItemIDs(RecipeCountType count_type, uint32 recipe_id); + int8 GetRecipeComponentCount(RecipeCountType count_type, uint32 recipe_id, uint32 item_id); /* Tribute */ bool LoadTributes();