Преглед изворни кода

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!
Aleos пре 3 година
родитељ
комит
893bfabe91
9 измењених фајлова са 190 додато и 29 уклоњено
  1. 2 1
      db/import-tmpl/skill_db.yml
  2. 56 1
      db/pre-re/skill_db.yml
  3. 56 1
      db/re/skill_db.yml
  4. 2 1
      db/skill_db.yml
  5. 24 1
      doc/skill_db.txt
  6. 1 0
      doc/yaml/db/skill_db.yml
  7. 23 21
      src/map/skill.cpp
  8. 2 1
      src/map/skill.hpp
  9. 24 2
      src/tool/csv2yaml.cpp

+ 2 - 1
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

+ 56 - 1
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

+ 56 - 1
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

+ 2 - 1
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:

+ 24 - 1
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
 
 ------------------
 

+ 1 - 0
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.

+ 23 - 21
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++;

+ 2 - 1
src/map/skill.hpp

@@ -228,6 +228,7 @@ struct s_skill_require {
 	int32 amount[MAX_SKILL_ITEM_REQUIRE];	/// Amount of item
 	std::vector<t_itemid> eqItem;				/// List of equipped item
 	std::vector<sc_type> 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 <uint16, s_skill_db> {
 public:
-	SkillDatabase() : TypesafeCachedYamlDatabase("SKILL_DB", 1) {
+	SkillDatabase() : TypesafeCachedYamlDatabase("SKILL_DB", 2, 1) {
 
 	}
 

+ 24 - 2
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;
 				}
 			}