Browse Source

Adds enchantgrade chance per refine (#7608)

Fixes #7607

Co-authored-by: Aleos <aleos89@users.noreply.github.com>
Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
munkrej 2 years ago
parent
commit
22aca36d35

+ 5 - 4
db/enchantgrade.yml

@@ -1,5 +1,5 @@
 # This file is a part of rAthena.
-#   Copyright(C) 2022 rAthena Development Team
+#   Copyright(C) 2023 rAthena Development Team
 #   https://rathena.org - https://github.com/rathena
 #
 # This program is free software: you can redistribute it and/or modify
@@ -27,8 +27,9 @@
 #     - Level                           Item level.
 #       Grades:                         Enchantgrade settings per grade level.
 #         - Grade                       Enchantgrade level.
-#           Refine                      Required refine level.
-#           Chance                      Base chance of success out of 0~10000.
+#           Chances:                    Chance settings per refine level.
+#             - Refine                  Refine level.
+#               Chance                  Base chance of success out of 0~10000.
 #           Bonus                       Enchantgrade bonus. (Default: 0)
 #           AnnounceSuccess             Announce on upgrade success. (Default: true)
 #           AnnounceFail                Announce on upgrade failure. (Default: false)
@@ -51,7 +52,7 @@
 
 Header:
   Type: ENCHANTGRADE_DB
-  Version: 2
+  Version: 3
 
 Footer:
   Imports:

+ 5 - 4
db/import-tmpl/enchantgrade.yml

@@ -1,5 +1,5 @@
 # This file is a part of rAthena.
-#   Copyright(C) 2022 rAthena Development Team
+#   Copyright(C) 2023 rAthena Development Team
 #   https://rathena.org - https://github.com/rathena
 #
 # This program is free software: you can redistribute it and/or modify
@@ -27,8 +27,9 @@
 #     - Level                           Item level.
 #       Grades:                         Enchantgrade settings per grade level.
 #         - Grade                       Enchantgrade level.
-#           Refine                      Required refine level.
-#           Chance                      Base chance of success out of 0~10000.
+#           Chances:                    Chance settings per refine level.
+#             - Refine                  Refine level.
+#               Chance                  Base chance of success out of 0~10000.
 #           Bonus                       Enchantgrade bonus. (Default: 0)
 #           AnnounceSuccess             Announce on upgrade success. (Default: true)
 #           AnnounceFail                Announce on upgrade failure. (Default: false)
@@ -51,4 +52,4 @@
 
 Header:
   Type: ENCHANTGRADE_DB
-  Version: 2
+  Version: 3

+ 185 - 20
db/re/enchantgrade.yml

@@ -1,5 +1,5 @@
 # This file is a part of rAthena.
-#   Copyright(C) 2022 rAthena Development Team
+#   Copyright(C) 2023 rAthena Development Team
 #   https://rathena.org - https://github.com/rathena
 #
 # This program is free software: you can redistribute it and/or modify
@@ -27,8 +27,9 @@
 #     - Level                           Item level.
 #       Grades:                         Enchantgrade settings per grade level.
 #         - Grade                       Enchantgrade level.
-#           Refine                      Required refine level.
-#           Chance                      Base chance of success out of 0~10000.
+#           Chances:                    Chance settings per refine level.
+#             - Refine                  Refine level.
+#               Chance                  Base chance of success out of 0~10000.
 #           Bonus                       Enchantgrade bonus. (Default: 0)
 #           AnnounceSuccess             Announce on upgrade success. (Default: true)
 #           AnnounceFail                Announce on upgrade failure. (Default: false)
@@ -51,7 +52,7 @@
 
 Header:
   Type: ENCHANTGRADE_DB
-  Version: 2
+  Version: 3
 
 Body:
   - Type: Armor
@@ -59,8 +60,31 @@ Body:
       - Level: 2
         Grades:
           - Grade: None
-            Refine: 11
-            Chance: 7000
+            Chances:
+              - Refine: 9
+                Chance: 1000
+              - Refine: 10
+                Chance: 2000
+              - Refine: 11
+                Chance: 7000
+              - Refine: 12
+                Chance: 7000
+              - Refine: 13
+                Chance: 7000
+              - Refine: 14
+                Chance: 7000
+              - Refine: 15
+                Chance: 7000
+              - Refine: 16
+                Chance: 7000
+              - Refine: 17
+                Chance: 7000
+              - Refine: 18
+                Chance: 7000
+              - Refine: 19
+                Chance: 7000
+              - Refine: 20
+                Chance: 7000
             Bonus: 10
             Catalyst:
                 Item: Blessed_Etel_Dust
@@ -78,8 +102,29 @@ Body:
                 Amount: 5
                 Zeny: 875000
           - Grade: D
-            Refine: 11
-            Chance: 6000
+            Chances:
+              - Refine: 10
+                Chance: 2000
+              - Refine: 11
+                Chance: 6000
+              - Refine: 12
+                Chance: 6000
+              - Refine: 13
+                Chance: 6000
+              - Refine: 14
+                Chance: 6000
+              - Refine: 15
+                Chance: 6000
+              - Refine: 16
+                Chance: 6000
+              - Refine: 17
+                Chance: 6000
+              - Refine: 18
+                Chance: 6000
+              - Refine: 19
+                Chance: 6000
+              - Refine: 20
+                Chance: 6000
             Bonus: 30
             Catalyst:
                 Item: Blessed_Etel_Dust
@@ -97,8 +142,27 @@ Body:
                 Amount: 5
                 Zeny: 875000
           - Grade: C
-            Refine: 11
-            Chance: 5000
+            Chances:
+              - Refine: 11
+                Chance: 5000
+              - Refine: 12
+                Chance: 5000
+              - Refine: 13
+                Chance: 5000
+              - Refine: 14
+                Chance: 5000
+              - Refine: 15
+                Chance: 5000
+              - Refine: 16
+                Chance: 5000
+              - Refine: 17
+                Chance: 5000
+              - Refine: 18
+                Chance: 5000
+              - Refine: 19
+                Chance: 5000
+              - Refine: 20
+                Chance: 5000
             Bonus: 50
             AnnounceFail: true
             Catalyst:
@@ -117,8 +181,27 @@ Body:
                 Amount: 5
                 Zeny: 875000
           - Grade: B
-            Refine: 11
-            Chance: 4000
+            Chances:
+              - Refine: 11
+                Chance: 4000
+              - Refine: 12
+                Chance: 4000
+              - Refine: 13
+                Chance: 4000
+              - Refine: 14
+                Chance: 4000
+              - Refine: 15
+                Chance: 4000
+              - Refine: 16
+                Chance: 4000
+              - Refine: 17
+                Chance: 4000
+              - Refine: 18
+                Chance: 4000
+              - Refine: 19
+                Chance: 4000
+              - Refine: 20
+                Chance: 4000
             Bonus: 100
             AnnounceFail: true
             Catalyst:
@@ -141,8 +224,31 @@ Body:
       - Level: 5
         Grades:
           - Grade: None
-            Refine: 11
-            Chance: 7000
+            Chances:
+              - Refine: 9
+                Chance: 1000
+              - Refine: 10
+                Chance: 2000
+              - Refine: 11
+                Chance: 7000
+              - Refine: 12
+                Chance: 7000
+              - Refine: 13
+                Chance: 7000
+              - Refine: 14
+                Chance: 7000
+              - Refine: 15
+                Chance: 7000
+              - Refine: 16
+                Chance: 7000
+              - Refine: 17
+                Chance: 7000
+              - Refine: 18
+                Chance: 7000
+              - Refine: 19
+                Chance: 7000
+              - Refine: 20
+                Chance: 7000
             Bonus: 10
             Catalyst:
                 Item: Blessed_Etel_Dust
@@ -160,8 +266,29 @@ Body:
                 Amount: 5
                 Zeny: 875000
           - Grade: D
-            Refine: 11
-            Chance: 6000
+            Chances:
+              - Refine: 10
+                Chance: 2000
+              - Refine: 11
+                Chance: 6000
+              - Refine: 12
+                Chance: 6000
+              - Refine: 13
+                Chance: 6000
+              - Refine: 14
+                Chance: 6000
+              - Refine: 15
+                Chance: 6000
+              - Refine: 16
+                Chance: 6000
+              - Refine: 17
+                Chance: 6000
+              - Refine: 18
+                Chance: 6000
+              - Refine: 19
+                Chance: 6000
+              - Refine: 20
+                Chance: 6000
             Bonus: 30
             Catalyst:
                 Item: Blessed_Etel_Dust
@@ -179,8 +306,27 @@ Body:
                 Amount: 5
                 Zeny: 875000
           - Grade: C
-            Refine: 11
-            Chance: 5000
+            Chances:
+              - Refine: 11
+                Chance: 5000
+              - Refine: 12
+                Chance: 5000
+              - Refine: 13
+                Chance: 5000
+              - Refine: 14
+                Chance: 5000
+              - Refine: 15
+                Chance: 5000
+              - Refine: 16
+                Chance: 5000
+              - Refine: 17
+                Chance: 5000
+              - Refine: 18
+                Chance: 5000
+              - Refine: 19
+                Chance: 5000
+              - Refine: 20
+                Chance: 5000
             Bonus: 50
             AnnounceFail: true
             Catalyst:
@@ -199,8 +345,27 @@ Body:
                 Amount: 5
                 Zeny: 875000
           - Grade: B
-            Refine: 11
-            Chance: 4000
+            Chances:
+              - Refine: 11
+                Chance: 4000
+              - Refine: 12
+                Chance: 4000
+              - Refine: 13
+                Chance: 4000
+              - Refine: 14
+                Chance: 4000
+              - Refine: 15
+                Chance: 4000
+              - Refine: 16
+                Chance: 4000
+              - Refine: 17
+                Chance: 4000
+              - Refine: 18
+                Chance: 4000
+              - Refine: 19
+                Chance: 4000
+              - Refine: 20
+                Chance: 4000
             Bonus: 100
             AnnounceFail: true
             Catalyst:

+ 34 - 0
doc/yaml/db/enchantgrade.yml

@@ -0,0 +1,34 @@
+###########################################################################
+# Enchantgrade Database
+###########################################################################
+#
+# Enchantgrade Settings
+#
+###########################################################################
+# - Type                                Item type.
+#   Levels:                             Enchantgrade settings per item level.
+#     - Level                           Item level.
+#       Grades:                         Enchantgrade settings per grade level.
+#         - Grade                       Enchantgrade level.
+#           Chances:                    Chance settings per refine level.
+#             - Refine                  Refine level.
+#               Chance                  Base chance of success out of 0~10000.
+#           Bonus                       Enchantgrade bonus. (Default: 0)
+#           AnnounceSuccess             Announce on upgrade success. (Default: true)
+#           AnnounceFail                Announce on upgrade failure. (Default: false)
+#           Announce                    Announce on upgrade success and failure.
+#           Catalyst:                   Catalyst item to increase chance of success.
+#             Item                      The item that can be used.
+#             AmountPerStep             Amount of Item needed.
+#                                       Set to 0 to disable the catalyst.
+#             MaximumSteps              Maximum amount of times Item can be used.
+#             ChanceIncrease            Amount at which the chance increases for each Item used.
+#           Options:                    Success chance based on cost type.
+#             - Option                  Index of the client option.
+#               Item                    Required item.
+#               Amount                  Amount of required item. (Default: 1)
+#                                       Set to 0 to remove an option.
+#               Price                   Amount of zeny required. (Default: 0)
+#               BreakingRate            Chance of item breaking out of 0~10000. (Default: 0)
+#               DowngradeAmount         Number of refine levels reduced on failure. (Default: 0)
+###########################################################################

+ 1 - 1
doc/yaml/db/license.yml

@@ -1,5 +1,5 @@
 # This file is a part of rAthena.
-#   Copyright(C) 2021 rAthena Development Team
+#   Copyright(C) 2023 rAthena Development Team
 #   https://rathena.org - https://github.com/rathena
 #
 # This program is free software: you can redistribute it and/or modify

+ 5 - 8
src/map/clif.cpp

@@ -23570,11 +23570,7 @@ void clif_enchantgrade_add( map_session_data& sd, uint16 index = UINT16_MAX, std
 
 	if( index < UINT16_MAX ){
 		p->index = client_index( index );
-		if( sd.inventory.u.items_inventory[index].refine >= gradeLevel->refine ){
-			p->success_chance = gradeLevel->chance / 100;
-		}else{
-			p->success_chance = 0;
-		}
+		p->success_chance = gradeLevel->chances[sd.inventory.u.items_inventory[index].refine] / 100;
 		p->blessing_info.id = client_nameid( gradeLevel->catalyst.item );
 		p->blessing_info.amount = gradeLevel->catalyst.amountPerStep;
 		p->blessing_info.max_blessing = gradeLevel->catalyst.maximumSteps;
@@ -23750,8 +23746,10 @@ void clif_parse_enchantgrade_start( int fd, map_session_data* sd ){
 		return;
 	}
 
-	// Not refined enough
-	if( sd->inventory.u.items_inventory[index].refine < enchantgradelevel->refine ){
+	uint16 totalChance = enchantgradelevel->chances[sd->inventory.u.items_inventory[index].refine];
+
+	// No chance to increase the enchantgrade
+	if( totalChance == 0 ){
 		return;
 	}
 
@@ -23767,7 +23765,6 @@ void clif_parse_enchantgrade_start( int fd, map_session_data* sd ){
 		return;
 	}
 
-	uint16 totalChance = enchantgradelevel->chance;
 	uint16 steps = min( p->blessing_amount, enchantgradelevel->catalyst.maximumSteps );
 	std::unordered_map<uint16, uint16> requiredItems;
 

+ 21 - 20
src/map/status.cpp

@@ -653,37 +653,38 @@ uint64 EnchantgradeDatabase::parseBodyNode( const ryml::NodeRef& node ){
 			bool gradeExists = grade != nullptr;
 
 			if( !gradeExists ){
+				if( !this->nodesExist( gradeNode, { "Chances", "Options" } ) ){
+					return 0;
+				}
+
 				grade = std::make_shared<s_enchantgradelevel>();
 				grade->grade = gradeLevel;
-
-				if( !this->nodesExist( gradeNode, { "Refine", "Chance", "Options" } ) ){
-					return 0;
+				for( int i = 0; i < ARRAYLENGTH( grade->chances ); i++ ){
+					grade->chances[i] = 0;
 				}
 			}
 
-			if( this->nodeExists( gradeNode, "Refine" ) ){
-				uint16 refine;
+			if( this->nodeExists( gradeNode, "Chances" ) ){
+				for( const ryml::NodeRef& chanceNode : gradeNode["Chances"] ){
+					uint16 refine;
 
-				if( !this->asUInt16( gradeNode, "Refine", refine ) ){
-					return 0;
-				}
+					if( !this->asUInt16( chanceNode, "Refine", refine ) ){
+						return 0;
+					}
 
-				if( refine > MAX_REFINE ){
-					this->invalidWarning( gradeNode["Refine"], "Refine %hu is too high, capping to %hu...\n", refine, MAX_REFINE );
-					refine = MAX_REFINE;
-				}
+					if( refine > MAX_REFINE ){
+						this->invalidWarning( chanceNode["Refine"], "Refine %hu is too high. Maximum: %hu.\n", refine, MAX_REFINE );
+						return 0;
+					}
 
-				grade->refine = refine;
-			}
+					uint16 chance;
 
-			if( this->nodeExists( gradeNode, "Chance" ) ){
-				uint16 chance;
+					if( !this->asUInt16Rate( chanceNode, "Chance", chance ) ){
+						return 0;
+					}
 
-				if( !this->asUInt16Rate( gradeNode, "Chance", chance ) ){
-					return 0;
+					grade->chances[refine] = chance;
 				}
-
-				grade->chance = chance;
 			}
 
 			if( this->nodeExists( gradeNode, "Bonus" ) ){

+ 2 - 3
src/map/status.hpp

@@ -165,8 +165,7 @@ struct s_enchantgradeoption{
 
 struct s_enchantgradelevel{
 	e_enchantgrade grade;
-	uint16 refine;
-	uint16 chance;
+	uint16 chances[MAX_REFINE + 1];
 	uint16 bonus;
 	bool announceSuccess;
 	bool announceFail;
@@ -186,7 +185,7 @@ struct s_enchantgrade{
 
 class EnchantgradeDatabase : public TypesafeYamlDatabase<uint16, s_enchantgrade>{
 public:
-	EnchantgradeDatabase() : TypesafeYamlDatabase( "ENCHANTGRADE_DB", 2, 1 ){
+	EnchantgradeDatabase() : TypesafeYamlDatabase( "ENCHANTGRADE_DB", 3 ){
 
 	}
 

+ 62 - 1
src/tool/yamlupgrade.cpp

@@ -10,6 +10,7 @@ static bool upgrade_item_db(std::string file, const uint32 source_version);
 static bool upgrade_job_stats(std::string file, const uint32 source_version);
 static bool upgrade_status_db(std::string file, const uint32 source_version);
 static bool upgrade_map_drops_db(std::string file, const uint32 source_version);
+static bool upgrade_enchantgrade_db( std::string file, const uint32 source_version );
 
 template<typename Func>
 bool process(const std::string &type, uint32 version, const std::vector<std::string> &paths, const std::string &name, Func lambda) {
@@ -129,7 +130,7 @@ bool YamlUpgradeTool::initialize( int argc, char* argv[] ){
 	if (!process("STATUS_DB", 3, root_paths, "status", [](const std::string& path, const std::string& name_ext, uint32 source_version) -> bool {
 		return upgrade_status_db(path + name_ext, source_version);
 		})) {
-		return 0;
+		return false;
 	}
 	
 	if (!process("MAP_DROP_DB", 2, root_paths, "map_drops", [](const std::string& path, const std::string& name_ext, uint32 source_version) -> bool {
@@ -138,6 +139,12 @@ bool YamlUpgradeTool::initialize( int argc, char* argv[] ){
 		return 0;
 	}
 
+	if( !process( "ENCHANTGRADE_DB", 3, root_paths, "enchantgrade", []( const std::string& path, const std::string& name_ext, uint32 source_version ) -> bool {
+		return upgrade_enchantgrade_db( path + name_ext, source_version );
+		} ) ){
+		return false;
+	}
+
 	return true;
 }
 
@@ -366,6 +373,60 @@ static bool upgrade_map_drops_db(std::string file, const uint32 source_version)
 	return true;
 }
 
+static bool upgrade_enchantgrade_db( std::string file, const uint32 source_version ){
+	size_t entries = 0;
+
+	for( auto input : inNode["Body"] ){
+		// If under version 3
+		if( source_version < 3 ){
+			if( input["Levels"].IsDefined() ){
+				for( auto levelNode : input["Levels"] ){
+					if( levelNode["Grades"].IsDefined() ){
+						for( auto gradeNode : levelNode["Grades"] ){
+							// Convert Refine + Chance to a Chances array
+							if( gradeNode["Refine"].IsDefined() && !gradeNode["Chance"].IsDefined() ){
+								ShowError( "Cannot upgrade automatically, because Refine is specified, but Chance is missing" );
+								return false;
+							}
+
+							if( gradeNode["Chance"].IsDefined() && !gradeNode["Refine"].IsDefined() ){
+								ShowError( "Cannot upgrade automatically, because Chance is specified, but Refine is missing" );
+								return false;
+							}
+
+							uint16 refine = gradeNode["Refine"].as<uint16>();
+							uint16 chance = gradeNode["Chance"].as<uint16>();
+
+							auto chancesNode = gradeNode["Chances"];
+
+							for( int i = refine, j = 0; i <= MAX_REFINE; i++, j++ ){
+								auto chanceNode = chancesNode[j];
+
+								chanceNode["Refine"] = i;
+								chanceNode["Chance"] = chance;
+							}
+
+							// Remove the existing Refine entry
+							gradeNode.remove( "Refine" );
+
+							// Remove the existing Chance entry
+							gradeNode.remove( "Chance" );
+						}
+					}
+				}
+			}
+		}
+
+		body << input;
+		entries++;
+	}
+
+	ShowStatus( "Done converting/upgrading '" CL_WHITE "%zu" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", entries, file.c_str() );
+
+	return true;
+}
+
+
 int main( int argc, char *argv[] ){
 	return main_core<YamlUpgradeTool>( argc, argv );
 }