From 893bfabe91e65e53aeb1fdd6c2d0285d9d086337 Mon Sep 17 00:00:00 2001 From: Aleos Date: Fri, 10 Sep 2021 14:24:23 -0400 Subject: [PATCH] Adds support for Level field in ItemCost (#5268) * Fixes #5266. * Adds the ability to supply the ItemCost level to easily override a specific level or only define some levels that have item requirements. * When the Level label is provided for ItemCost it becomes dependent to that level only. * Removes some remaining hardcoded skills that have skill level dependent checks. * Added support to CSV2YAML to properly convert those level dependent skills. * Adds documentation to header and upped version. Thanks to @Pringle012 and @Lemongrass3110! --- db/import-tmpl/skill_db.yml | 3 +- db/pre-re/skill_db.yml | 57 ++++++++++++++++++++++++++++++++++++- db/re/skill_db.yml | 57 ++++++++++++++++++++++++++++++++++++- db/skill_db.yml | 3 +- doc/skill_db.txt | 25 +++++++++++++++- doc/yaml/db/skill_db.yml | 1 + src/map/skill.cpp | 44 ++++++++++++++-------------- src/map/skill.hpp | 3 +- src/tool/csv2yaml.cpp | 26 +++++++++++++++-- 9 files changed, 190 insertions(+), 29 deletions(-) diff --git a/db/import-tmpl/skill_db.yml b/db/import-tmpl/skill_db.yml index 7522ebd614..c748487805 100644 --- a/db/import-tmpl/skill_db.yml +++ b/db/import-tmpl/skill_db.yml @@ -112,6 +112,7 @@ # ItemCost: Item required to cast. (Default: 0) # - Item Item name. # Amount Item amount. +# Level Skill level. Makes the skill item check become level dependent if supplied. (Default: applies to all levels) # Equipment: Equipped item required to cast. (Default: nullptr) # Unit: Skill unit values. (Optional) # Id Skill unit ID. @@ -129,4 +130,4 @@ Header: Type: SKILL_DB - Version: 1 + Version: 2 diff --git a/db/pre-re/skill_db.yml b/db/pre-re/skill_db.yml index 15cd441b70..be2867c99d 100644 --- a/db/pre-re/skill_db.yml +++ b/db/pre-re/skill_db.yml @@ -112,6 +112,7 @@ # ItemCost: Item required to cast. (Default: 0) # - Item Item name. # Amount Item amount. +# Level Skill level. Makes the skill item check become level dependent if supplied. (Default: applies to all levels) # Equipment: Equipped item required to cast. (Default: nullptr) # Unit: Skill unit values. (Optional) # Id Skill unit ID. @@ -129,7 +130,7 @@ Header: Type: SKILL_DB - Version: 1 + Version: 2 Body: - Id: 1 @@ -2933,6 +2934,22 @@ Body: Time: 2400 Requires: SpCost: 75 + ItemCost: + - Item: Blue_Gemstone + Amount: 1 + Level: 6 + - Item: Blue_Gemstone + Amount: 1 + Level: 7 + - Item: Blue_Gemstone + Amount: 1 + Level: 8 + - Item: Blue_Gemstone + Amount: 1 + Level: 9 + - Item: Blue_Gemstone + Amount: 1 + Level: 10 Unit: Id: Firepillar_Waiting AlternateId: Firepillar_Active @@ -20862,12 +20879,16 @@ Body: ItemCost: - Item: Scarlet_Pts Amount: 3 + Level: 1 - Item: Lime_Green_Pts Amount: 3 + Level: 2 - Item: Yellow_Wish_Pts Amount: 3 + Level: 3 - Item: Indigo_Pts Amount: 3 + Level: 4 - Item: Magic_Gear_Fuel Amount: 2 Equipment: @@ -26359,10 +26380,13 @@ Body: ItemCost: - Item: Boody_Red Amount: 3 + Level: 1 - Item: Boody_Red Amount: 6 + Level: 2 - Item: Flame_Heart Amount: 1 + Level: 3 - Id: 2458 Name: SO_SUMMON_AQUA Description: Summon Water Spirit Aqua @@ -26400,10 +26424,13 @@ Body: ItemCost: - Item: Crystal_Blue Amount: 3 + Level: 1 - Item: Crystal_Blue Amount: 6 + Level: 2 - Item: Mistic_Frozen Amount: 1 + Level: 3 - Id: 2459 Name: SO_SUMMON_VENTUS Description: Summon Wind Spirit Ventus @@ -26441,10 +26468,13 @@ Body: ItemCost: - Item: Wind_Of_Verdure Amount: 3 + Level: 1 - Item: Wind_Of_Verdure Amount: 6 + Level: 2 - Item: Rough_Wind Amount: 1 + Level: 3 - Id: 2460 Name: SO_SUMMON_TERA Description: Summon Earth Spirit Tera @@ -26482,10 +26512,13 @@ Body: ItemCost: - Item: Yellow_Live Amount: 3 + Level: 1 - Item: Yellow_Live Amount: 6 + Level: 2 - Item: Great_Nature Amount: 1 + Level: 3 - Id: 2461 Name: SO_EL_ACTION Description: Elemental Action @@ -26567,10 +26600,13 @@ Body: ItemCost: - Item: Scarlet_Pts Amount: 1 + Level: 1 - Item: Scarlet_Pts Amount: 2 + Level: 2 - Item: Scarlet_Pts Amount: 3 + Level: 3 Unit: Id: Fire_Insignia Layout: 1 @@ -26606,10 +26642,13 @@ Body: ItemCost: - Item: Indigo_Pts Amount: 1 + Level: 1 - Item: Indigo_Pts Amount: 2 + Level: 2 - Item: Indigo_Pts Amount: 3 + Level: 3 Unit: Id: Water_Insignia Layout: 1 @@ -26645,10 +26684,13 @@ Body: ItemCost: - Item: Yellow_Wish_Pts Amount: 1 + Level: 1 - Item: Yellow_Wish_Pts Amount: 2 + Level: 2 - Item: Yellow_Wish_Pts Amount: 3 + Level: 3 Unit: Id: Wind_Insignia Layout: 1 @@ -26684,10 +26726,13 @@ Body: ItemCost: - Item: Lime_Green_Pts Amount: 1 + Level: 1 - Item: Lime_Green_Pts Amount: 2 + Level: 2 - Item: Lime_Green_Pts Amount: 3 + Level: 3 Unit: Id: Earth_Insignia Layout: 1 @@ -27226,14 +27271,19 @@ Body: ItemCost: - Item: Oil_Bottle Amount: 1 + Level: 1 - Item: Explosive_Powder Amount: 1 + Level: 2 - Item: Smoke_Powder Amount: 1 + Level: 3 - Item: Tear_Gas Amount: 1 + Level: 4 - Item: Acid_Bottle Amount: 1 + Level: 5 - Id: 2487 Name: GN_FIRE_EXPANSION_SMOKE_POWDER Description: Fire Expansion Smoke Powder @@ -28938,14 +28988,19 @@ Body: ItemCost: - Item: Makibishi Amount: 3 + Level: 1 - Item: Makibishi Amount: 4 + Level: 2 - Item: Makibishi Amount: 5 + Level: 3 - Item: Makibishi Amount: 6 + Level: 4 - Item: Makibishi Amount: 7 + Level: 5 Unit: Id: Makibishi Range: 1 diff --git a/db/re/skill_db.yml b/db/re/skill_db.yml index 7cd6796aa5..3ac8c28381 100644 --- a/db/re/skill_db.yml +++ b/db/re/skill_db.yml @@ -112,6 +112,7 @@ # ItemCost: Item required to cast. (Default: 0) # - Item Item name. # Amount Item amount. +# Level Skill level. Makes the skill item check become level dependent if supplied. (Default: applies to all levels) # Equipment: Equipped item required to cast. (Default: nullptr) # Unit: Skill unit values. (Optional) # Id Skill unit ID. @@ -129,7 +130,7 @@ Header: Type: SKILL_DB - Version: 1 + Version: 2 Body: - Id: 1 @@ -2995,6 +2996,22 @@ Body: Time: 48 Requires: SpCost: 75 + ItemCost: + - Item: Blue_Gemstone + Amount: 1 + Level: 6 + - Item: Blue_Gemstone + Amount: 1 + Level: 7 + - Item: Blue_Gemstone + Amount: 1 + Level: 8 + - Item: Blue_Gemstone + Amount: 1 + Level: 9 + - Item: Blue_Gemstone + Amount: 1 + Level: 10 Unit: Id: Firepillar_Waiting AlternateId: Firepillar_Active @@ -21557,12 +21574,16 @@ Body: ItemCost: - Item: Scarlet_Pts Amount: 3 + Level: 1 - Item: Lime_Green_Pts Amount: 3 + Level: 2 - Item: Yellow_Wish_Pts Amount: 3 + Level: 3 - Item: Indigo_Pts Amount: 3 + Level: 4 - Item: Magic_Gear_Fuel Amount: 2 Equipment: @@ -26971,10 +26992,13 @@ Body: ItemCost: - Item: Boody_Red Amount: 3 + Level: 1 - Item: Boody_Red Amount: 6 + Level: 2 - Item: Flame_Heart Amount: 1 + Level: 3 - Id: 2458 Name: SO_SUMMON_AQUA Description: Summon Water Spirit Aqua @@ -27013,10 +27037,13 @@ Body: ItemCost: - Item: Crystal_Blue Amount: 3 + Level: 1 - Item: Crystal_Blue Amount: 6 + Level: 2 - Item: Mistic_Frozen Amount: 1 + Level: 3 - Id: 2459 Name: SO_SUMMON_VENTUS Description: Summon Wind Spirit Ventus @@ -27055,10 +27082,13 @@ Body: ItemCost: - Item: Wind_Of_Verdure Amount: 3 + Level: 1 - Item: Wind_Of_Verdure Amount: 6 + Level: 2 - Item: Rough_Wind Amount: 1 + Level: 3 - Id: 2460 Name: SO_SUMMON_TERA Description: Summon Earth Spirit Tera @@ -27097,10 +27127,13 @@ Body: ItemCost: - Item: Yellow_Live Amount: 3 + Level: 1 - Item: Yellow_Live Amount: 6 + Level: 2 - Item: Great_Nature Amount: 1 + Level: 3 - Id: 2461 Name: SO_EL_ACTION Description: Elemental Action @@ -27184,10 +27217,13 @@ Body: ItemCost: - Item: Scarlet_Pts Amount: 1 + Level: 1 - Item: Scarlet_Pts Amount: 2 + Level: 2 - Item: Scarlet_Pts Amount: 3 + Level: 3 Unit: Id: Fire_Insignia Layout: 1 @@ -27224,10 +27260,13 @@ Body: ItemCost: - Item: Indigo_Pts Amount: 1 + Level: 1 - Item: Indigo_Pts Amount: 2 + Level: 2 - Item: Indigo_Pts Amount: 3 + Level: 3 Unit: Id: Water_Insignia Layout: 1 @@ -27264,10 +27303,13 @@ Body: ItemCost: - Item: Yellow_Wish_Pts Amount: 1 + Level: 1 - Item: Yellow_Wish_Pts Amount: 2 + Level: 2 - Item: Yellow_Wish_Pts Amount: 3 + Level: 3 Unit: Id: Wind_Insignia Layout: 1 @@ -27304,10 +27346,13 @@ Body: ItemCost: - Item: Lime_Green_Pts Amount: 1 + Level: 1 - Item: Lime_Green_Pts Amount: 2 + Level: 2 - Item: Lime_Green_Pts Amount: 3 + Level: 3 Unit: Id: Earth_Insignia Layout: 1 @@ -27871,14 +27916,19 @@ Body: ItemCost: - Item: Oil_Bottle Amount: 1 + Level: 1 - Item: Explosive_Powder Amount: 1 + Level: 2 - Item: Smoke_Powder Amount: 1 + Level: 3 - Item: Tear_Gas Amount: 1 + Level: 4 - Item: Acid_Bottle Amount: 1 + Level: 5 - Id: 2487 Name: GN_FIRE_EXPANSION_SMOKE_POWDER Description: Fire Expansion Smoke Powder @@ -30741,14 +30791,19 @@ Body: ItemCost: - Item: Makibishi Amount: 3 + Level: 1 - Item: Makibishi Amount: 4 + Level: 2 - Item: Makibishi Amount: 5 + Level: 3 - Item: Makibishi Amount: 6 + Level: 4 - Item: Makibishi Amount: 7 + Level: 5 Unit: Id: Makibishi Interval: 5000 diff --git a/db/skill_db.yml b/db/skill_db.yml index f1f29e6e47..d5cb78d6fc 100644 --- a/db/skill_db.yml +++ b/db/skill_db.yml @@ -112,6 +112,7 @@ # ItemCost: Item required to cast. (Default: 0) # - Item Item name. # Amount Item amount. +# Level Skill level. Makes the skill item check become level dependent if supplied. (Default: applies to all levels) # Equipment: Equipped item required to cast. (Default: nullptr) # Unit: Skill unit values. (Optional) # Id Skill unit ID. @@ -129,7 +130,7 @@ Header: Type: SKILL_DB - Version: 1 + Version: 2 Footer: Imports: diff --git a/doc/skill_db.txt b/doc/skill_db.txt index 12c6336a6d..aca6fb30a5 100644 --- a/doc/skill_db.txt +++ b/doc/skill_db.txt @@ -727,7 +727,30 @@ Sequence Map Form ------------------ -ItemCost: Item required to cast. +ItemCost: Item required to cast. If the Level is supplied, then the ItemCost becomes skill level dependent. + +Levels 1 - 5 have no item cost but levels 6 - 10 require a Blue Gemstone. + ItemCost: + - Item: Blue_Gemstone + Amount: 1 + Level: 6 + - Item: Blue_Gemstone + Amount: 1 + Level: 7 + - Item: Blue_Gemstone + Amount: 1 + Level: 8 + - Item: Blue_Gemstone + Amount: 1 + Level: 9 + - Item: Blue_Gemstone + Amount: 1 + Level: 10 + +# All levels require a Blue Gemstone. + ItemCost: + - Item: Blue_Gemstone + Amount: 1 ------------------ diff --git a/doc/yaml/db/skill_db.yml b/doc/yaml/db/skill_db.yml index 982b221c4f..45e46115f9 100644 --- a/doc/yaml/db/skill_db.yml +++ b/doc/yaml/db/skill_db.yml @@ -95,6 +95,7 @@ # ItemCost: Item required to cast. (Default: 0) # - Item Item name. # Amount Item amount. +# Level Skill level. Makes the skill item check become level dependent if supplied. (Default: applies to all levels) # Equipment: Equipped item required to cast. (Default: nullptr) # Unit: Skill unit values. (Optional) # Id Skill unit ID. diff --git a/src/map/skill.cpp b/src/map/skill.cpp index 03e36396a4..b58a023162 100755 --- a/src/map/skill.cpp +++ b/src/map/skill.cpp @@ -16703,7 +16703,6 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint struct status_data *status; struct status_change *sc; int i,hp_rate,sp_rate, sp_skill_rate_bonus = 100; - bool level_dependent = false; memset(&req,0,sizeof(req)); @@ -16810,26 +16809,16 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint req.status = skill->require.status; req.eqItem = skill->require.eqItem; + // Level dependence flag is determined based on the ItemCost Level label + bool level_dependent = skill->require.itemid_level_dependent; + switch( skill_id ) { /* Skill level-dependent checks */ case NC_SHAPESHIFT: // NOTE: Magic_Gear_Fuel must be last in the ItemCost list depending on the skill's max level case NC_REPAIR: // NOTE: Repair_Kit must be last in the ItemCost list depending on the skill's max level req.itemid[1] = skill->require.itemid[skill->max]; req.amount[1] = skill->require.amount[skill->max]; - case KO_MAKIBISHI: - case GN_FIRE_EXPANSION: - case SO_SUMMON_AGNI: - case SO_SUMMON_AQUA: - case SO_SUMMON_VENTUS: - case SO_SUMMON_TERA: - case SO_WATER_INSIGNIA: - case SO_FIRE_INSIGNIA: - case SO_WIND_INSIGNIA: - case SO_EARTH_INSIGNIA: - case WZ_FIREPILLAR: // no gems required at level 1-5 [celest] - req.itemid[0] = skill->require.itemid[min(skill_lv-1,MAX_SKILL_ITEM_REQUIRE-1)]; - req.amount[0] = skill->require.amount[min(skill_lv-1,MAX_SKILL_ITEM_REQUIRE-1)]; - level_dependent = true; + // Fall through /* Normal skill requirements and gemstone checks */ default: @@ -16905,12 +16894,8 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint } } // Check requirement for Magic Gear Fuel - if (req.itemid[i] == ITEMID_MAGIC_GEAR_FUEL) { - if (sd->special_state.no_mado_fuel) - { - req.itemid[i] = req.amount[i] = 0; - } - } + if (req.itemid[i] == ITEMID_MAGIC_GEAR_FUEL && sd->special_state.no_mado_fuel) + req.itemid[i] = req.amount[i] = 0; } break; } @@ -22370,6 +22355,23 @@ uint64 SkillDatabase::parseBodyNode(const YAML::Node &node) { if (!this->asInt32(it, "Amount", amount)) continue; + if (this->nodeExists(it, "Level")) { + uint16 cost_level; + + if (!this->asUInt16(it, "Level", cost_level)) + continue; + + if (cost_level < 1 || cost_level > skill->max) { + this->invalidWarning(it["Level"], "Requires ItemCost Level %d is not within %s's level range of 1~%d.\n", cost_level, skill->name, skill->max); + return 0; + } + + count = cost_level - 1; + + if (!skill->require.itemid_level_dependent) + skill->require.itemid_level_dependent = true; + } + skill->require.itemid[count] = item->nameid; skill->require.amount[count] = amount; count++; diff --git a/src/map/skill.hpp b/src/map/skill.hpp index 1211f006be..8abcdd1378 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -228,6 +228,7 @@ struct s_skill_require { int32 amount[MAX_SKILL_ITEM_REQUIRE]; /// Amount of item std::vector eqItem; /// List of equipped item std::vector status; /// List of Status required (SC) + bool itemid_level_dependent; /// If the ItemCost is skill level dependent or not. }; /// Skill Copyable structure. @@ -300,7 +301,7 @@ struct s_skill_db { class SkillDatabase : public TypesafeCachedYamlDatabase { public: - SkillDatabase() : TypesafeCachedYamlDatabase("SKILL_DB", 1) { + SkillDatabase() : TypesafeCachedYamlDatabase("SKILL_DB", 2, 1) { } diff --git a/src/tool/csv2yaml.cpp b/src/tool/csv2yaml.cpp index a277567c5d..c55cfa48e9 100644 --- a/src/tool/csv2yaml.cpp +++ b/src/tool/csv2yaml.cpp @@ -244,14 +244,14 @@ int do_init( int argc, char** argv ){ } skill_txt_data( path_db_mode, path_db ); - if (!process("SKILL_DB", 1, { path_db_mode }, "skill_db", [](const std::string& path, const std::string& name_ext) -> bool { + if (!process("SKILL_DB", 2, { path_db_mode }, "skill_db", [](const std::string& path, const std::string& name_ext) -> bool { return sv_readdb(path.c_str(), name_ext.c_str(), ',', 18, 18, -1, &skill_parse_row_skilldb, false); })){ return 0; } skill_txt_data( path_db_import, path_db_import ); - if (!process("SKILL_DB", 1, { path_db_import }, "skill_db", [](const std::string& path, const std::string& name_ext) -> bool { + if (!process("SKILL_DB", 2, { path_db_import }, "skill_db", [](const std::string& path, const std::string& name_ext) -> bool { return sv_readdb(path.c_str(), name_ext.c_str(), ',', 18, 18, -1, &skill_parse_row_skilldb, false); })){ return 0; @@ -2010,6 +2010,28 @@ static bool skill_parse_row_skilldb(char* split[], int columns, int current) { body << YAML::Key << "Item" << YAML::Value << *item_name; body << YAML::Key << "Amount" << YAML::Value << it_req->second.amount[i]; + + switch (skill_id) { // List of level dependent item costs + case WZ_FIREPILLAR: + if (i < 6) + break; // Levels 1-5 have no cost + case NC_SHAPESHIFT: + case NC_REPAIR: + if (skill_id == NC_SHAPESHIFT || skill_id == NC_REPAIR && i >= 5) + break; // Don't add level 5 label as it exceeds the max level of these skills + case GN_FIRE_EXPANSION: + case SO_SUMMON_AGNI: + case SO_SUMMON_AQUA: + case SO_SUMMON_VENTUS: + case SO_SUMMON_TERA: + case SO_WATER_INSIGNIA: + case SO_FIRE_INSIGNIA: + case SO_WIND_INSIGNIA: + case SO_EARTH_INSIGNIA: + case KO_MAKIBISHI: + body << YAML::Key << "Level" << YAML::Value << i; + } + body << YAML::EndMap; } }