Przeglądaj źródła

Updated item group DB format
* Added "Algorithm" field to dehardcode the "must" subgroup associated with subgroup 0
* Added "NaturalRandom" for "Algorithm" field which will be used later
* Upgraded version and tool to upgrade the file from previous version

Atemo 5 miesięcy temu
rodzic
commit
84d2fa135e

+ 1 - 0
db/import-tmpl/item_group_db.yml

@@ -25,6 +25,7 @@
 # - Group                      Group name of the item.
 #   SubGroups:
 #     - SubGroup:              SubGroup number associated with the list of item. See doc/item_group.txt for more information.
+#       Algorithm:             Type of algorithm associated with SubGroup. (Default: Random)
 #       List:                  List of item(s) for the SubGroup.
 #        - Index               Unique number that can be used to add the same Item with different data in the list.
 #          Item                AegisName of item that will be obtained from this item group.

+ 9 - 8
db/item_group_db.yml

@@ -1,5 +1,5 @@
 # This file is a part of rAthena.
-#   Copyright(C) 2021 rAthena Development Team
+#   Copyright(C) 2024 rAthena Development Team
 #   https://rathena.org - https://github.com/rathena
 #
 # This program is free software: you can redistribute it and/or modify
@@ -25,6 +25,7 @@
 # - Group                      Group name of the item.
 #   SubGroups:
 #     - SubGroup:              SubGroup number associated with the list of item. See doc/item_group.txt for more information.
+#       Algorithm:             Type of algorithm associated with SubGroup. (Default: Random)
 #       List:                  List of item(s) for the SubGroup.
 #        - Index               Unique number that can be used to add the same Item with different data in the list.
 #          Item                AegisName of item that will be obtained from this item group.
@@ -32,7 +33,7 @@
 #          Amount              Amount of item that will be obtained. (Default: 1)
 #          Duration            Makes the item a rental item which will expire within the given amount in minutes. Not intended for use with stackable items. (Default: 0)
 #          Announced           If player obtains this item it will be broadcasted to the server. (Default: false)
-#          UniqueId            Makes the given item(s) have a Unique ID. (Default: false)
+#          UniqueId            Makes the given item(s) have a Unique ID. (Default: UniqueId from item_db)
 #          Stacked             Whether stackable items are given stacked or not. (Default: true)
 #          Named               Inscribes the item with the obtainer's name. (Default: false)
 #          Bound               Binds the obtained item. (Default: None)
@@ -45,12 +46,12 @@
 
 Header:
   Type: ITEM_GROUP_DB
-  Version: 3
+  Version: 4
 
 Footer:
   Imports:
-  - Path: db/pre-re/item_group_db.yml
-    Mode: Prerenewal
-  - Path: db/re/item_group_db.yml
-    Mode: Renewal
-  - Path: db/import/item_group_db.yml
+    - Path: db/pre-re/item_group_db.yml
+      Mode: Prerenewal
+    - Path: db/re/item_group_db.yml
+      Mode: Renewal
+    - Path: db/import/item_group_db.yml

+ 65 - 2
db/pre-re/item_group_db.yml

@@ -1,5 +1,5 @@
 # This file is a part of rAthena.
-#   Copyright(C) 2023 rAthena Development Team
+#   Copyright(C) 2024 rAthena Development Team
 #   https://rathena.org - https://github.com/rathena
 #
 # This program is free software: you can redistribute it and/or modify
@@ -25,6 +25,7 @@
 # - Group                      Group name of the item.
 #   SubGroups:
 #     - SubGroup:              SubGroup number associated with the list of item. See doc/item_group.txt for more information.
+#       Algorithm:             Type of algorithm associated with SubGroup. (Default: Random)
 #       List:                  List of item(s) for the SubGroup.
 #        - Index               Unique number that can be used to add the same Item with different data in the list.
 #          Item                AegisName of item that will be obtained from this item group.
@@ -45,12 +46,13 @@
 
 Header:
   Type: ITEM_GROUP_DB
-  Version: 3
+  Version: 4
 
 Body:
   - Group: ACCESORY
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Ring
@@ -181,6 +183,7 @@ Body:
   - Group: BLEUBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Milk
@@ -218,6 +221,7 @@ Body:
   - Group: BLUEBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -3288,6 +3292,7 @@ Body:
   - Group: BOMB
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Apple_Bomb
@@ -3316,6 +3321,7 @@ Body:
   - Group: BOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Old_Blue_Box
@@ -3329,6 +3335,7 @@ Body:
   - Group: CANDY
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Candy
@@ -3339,6 +3346,7 @@ Body:
   - Group: CARDALBUM
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Poring_Card
@@ -4429,6 +4437,7 @@ Body:
   - Group: CASH_FOOD
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Str_Dish10_
@@ -4451,6 +4460,7 @@ Body:
   - Group: CHERISH_BOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Dog_Cap_
@@ -4464,6 +4474,7 @@ Body:
   - Group: CHERISH_BOX_ORI
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Ragnarok_Limited_Ed
@@ -4483,6 +4494,7 @@ Body:
   - Group: COOKIEBAG
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Candy
@@ -4535,6 +4547,7 @@ Body:
   - Group: EASTER_SCROLL
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: No_Recipient
@@ -4581,6 +4594,7 @@ Body:
   - Group: EGGBOY
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Grape
@@ -4606,6 +4620,7 @@ Body:
   - Group: EGGGIRL
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Grape
@@ -4631,6 +4646,7 @@ Body:
   - Group: ELEMENT
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Scarlet_Pts
@@ -4647,6 +4663,7 @@ Body:
   - Group: FIRSTAID
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -4705,6 +4722,7 @@ Body:
   - Group: FISH
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Fish_Slice
@@ -4715,6 +4733,7 @@ Body:
   - Group: FOOD
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Royal_Jelly
@@ -4785,6 +4804,7 @@ Body:
   - Group: FOODBAG
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Apple
@@ -4921,6 +4941,7 @@ Body:
   - Group: FRUIT
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Apple
@@ -4940,6 +4961,7 @@ Body:
   - Group: GEMSTONE
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Yellow_Gemstone
@@ -4953,6 +4975,7 @@ Body:
   - Group: GIFTBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -5167,6 +5190,7 @@ Body:
   - Group: GIFTBOXCHINA
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -5963,6 +5987,7 @@ Body:
   - Group: GIFTBOX_1
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -6177,6 +6202,7 @@ Body:
   - Group: GIFTBOX_2
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -6391,6 +6417,7 @@ Body:
   - Group: GIFTBOX_3
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -6605,6 +6632,7 @@ Body:
   - Group: GIFTBOX_4
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -6819,6 +6847,7 @@ Body:
   - Group: GREENBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Chocolate_Drink
@@ -6856,6 +6885,7 @@ Body:
   - Group: HERB
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Herb
@@ -6869,6 +6899,7 @@ Body:
   - Group: HOMETOWNGIFT
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Korea_Rice_Cake
@@ -6897,6 +6928,7 @@ Body:
   - Group: JEWEL
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Yellow_Gemstone
@@ -6961,6 +6993,7 @@ Body:
   - Group: JUICE
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Apple_Juice
@@ -6974,6 +7007,7 @@ Body:
   - Group: LOTTOBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Lotto31
@@ -7008,6 +7042,7 @@ Body:
   - Group: LOUISE_COSTUME_BOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Bag
@@ -7018,6 +7053,7 @@ Body:
   - Group: MAGICCARDALBUM
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Ghostring_Card
@@ -7115,6 +7151,7 @@ Body:
   - Group: MASK
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Mr_Smile
@@ -7158,6 +7195,7 @@ Body:
   - Group: MASQUERADE
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Drooping_Nine_Tail_
@@ -7174,6 +7212,7 @@ Body:
   - Group: MASQUERADE_2
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Dress_Hat
@@ -7190,6 +7229,7 @@ Body:
   - Group: MEAT
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Meat
@@ -7200,6 +7240,7 @@ Body:
   - Group: MERCENARY
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Bow_Mercenary_Scroll1
@@ -7294,6 +7335,7 @@ Body:
   - Group: MINERAL
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Emperium
@@ -7358,6 +7400,7 @@ Body:
   - Group: OLDGIFTBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Fallen_Leaves_
@@ -7371,6 +7414,7 @@ Body:
   - Group: ORE
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Iron_Ore
@@ -7435,6 +7479,7 @@ Body:
   - Group: PIERRE_TREASUREBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Old_Blue_Box
@@ -7523,6 +7568,7 @@ Body:
   - Group: POISON
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Poison_Paralysis
@@ -7551,6 +7597,7 @@ Body:
   - Group: POTION
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -7567,6 +7614,7 @@ Body:
   - Group: QUIVER
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Arrow_Container
@@ -7610,6 +7658,7 @@ Body:
   - Group: RECOVERY
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Fruit_Of_Mastela
@@ -7656,6 +7705,7 @@ Body:
   - Group: REDBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Cat_Hat
@@ -7702,6 +7752,7 @@ Body:
   - Group: REDBOX_2
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Alice_Doll
@@ -7718,6 +7769,7 @@ Body:
   - Group: RESIST
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Resist_Fire
@@ -7734,6 +7786,7 @@ Body:
   - Group: SCROLL
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Earth_Scroll_1_3
@@ -7792,6 +7845,7 @@ Body:
   - Group: TAMING
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Unripe_Apple
@@ -7946,6 +8000,7 @@ Body:
   - Group: THROWABLE
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Mysterious_Powder
@@ -8019,6 +8074,7 @@ Body:
   - Group: TOKEN_OF_SIEGFRIED
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: F_Token_Of_Siegfried
@@ -8032,6 +8088,7 @@ Body:
   - Group: TRESURE_BOX_WOE
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Old_Blue_Box
@@ -8096,6 +8153,7 @@ Body:
   - Group: VIOLETBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Red_Potion
@@ -10869,6 +10927,7 @@ Body:
   - Group: XMAS_GIFT
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: HandMade_Chocolate
@@ -10930,6 +10989,7 @@ Body:
   - Group: YELLOWBOX
     SubGroups:
       - SubGroup: 6
+        Algorithm: NaturalRandom
         List:
           - Index: 0
             Item: Elephant_Hat_
@@ -10946,6 +11006,7 @@ Body:
   - Group: MF_NOTELEPORT
     SubGroups:
       - SubGroup: 0
+        Algorithm: Must
         List:
           - Index: 0
             Item: Wing_Of_Fly
@@ -10960,6 +11021,7 @@ Body:
   - Group: MF_NORETURN
     SubGroups:
       - SubGroup: 0
+        Algorithm: Must
         List:
           - Index: 0
             Item: Wing_Of_Butterfly
@@ -11008,6 +11070,7 @@ Body:
   - Group: GIANT_FLY_WING
     SubGroups:
       - SubGroup: 0
+        Algorithm: Must
         List:
           - Index: 0
             Item: Giant_Fly_Wing

Plik diff jest za duży
+ 126 - 2
db/re/item_group_db.yml


+ 13 - 2
doc/item_group.txt

@@ -75,19 +75,29 @@ Amount: Amount of item that will be obtained.
 
 ---------------------------------------
 
-SubGroup: Setting this to '0' makes the item always obtainable ("must" item).
-		  SubGroup value will allocate where the item will be stored at random group.
+SubGroup: Unique number to create a list of item.
 
+---------------------------------------
+
+Algorithm: Type of algorithm associated with SubGroup.
+
+Random             - Random item.
+Must               - Makes the item(s) always obtainable ("must" item).
+NaturalRandom      - Random item. (same result as "Random" for now)
+
+Example:
 	Item Group:
       - Group: MyItemGroup
         SubGroups:
           - SubGroup: 0
+            Algorithm: Must
             List:
               - Index: 0
                 Item: Knife       # "must" item(s)
               - Index: 1
                 Item: Dagger      # "must" item(s)
           - SubGroup: 1
+            Algorithm: Random
             List:
               - Index: 0
                 Item: Stiletto    # random at SubGroup 1
@@ -96,6 +106,7 @@ SubGroup: Setting this to '0' makes the item always obtainable ("must" item).
                 Item: Stiletto_   # random at SubGroup 1
                 Rate: 2
           - SubGroup: 2
+            Algorithm: Random
             List:
               - Index: 0
                 Item: Stiletto    # random at SubGroup 2

+ 1 - 0
doc/yaml/db/item_group_db.yml

@@ -8,6 +8,7 @@
 # - Group                      Group name of the item.
 #   SubGroups:
 #     - SubGroup:              SubGroup number associated with the list of item. See doc/item_group.txt for more information.
+#       Algorithm:             Type of algorithm associated with SubGroup. (Default: Random)
 #       List:                  List of item(s) for the SubGroup.
 #        - Index               Unique number that can be used to add the same Item with different data in the list.
 #          Item                AegisName of item that will be obtained from this item group.

+ 30 - 20
src/map/itemdb.cpp

@@ -3029,21 +3029,13 @@ uint8 ItemGroupDatabase::pc_get_itemgroup( uint16 group_id, bool identify, map_s
 	if (group->random.empty())
 		return 0;
 
-	// Get all the 'must' item(s) (subgroup 0)
-	std::shared_ptr<s_item_group_random> must = util::umap_find(group->random, static_cast<uint16>(0));
-	if( must != nullptr ){
-		for (const auto &it : must->data)
-			this->pc_get_itemgroup_sub( sd, identify, it.second );
-	}
-
-	// Get 1 'random' item from each subgroup
 	for (const auto &random : group->random) {
-		// Skip the 'must' group
-		if( random.first == 0 ){
-			continue;
+		if( random.second->algorithm != SUBGROUP_ALGO_MUST )
+			this->pc_get_itemgroup_sub( sd, identify, this->get_random_itemsubgroup( random.second ) );
+		else {
+			for (const auto &it : random.second->data)
+				this->pc_get_itemgroup_sub( sd, identify, it.second );
 		}
-
-		this->pc_get_itemgroup_sub( sd, identify, this->get_random_itemsubgroup( random.second ) );
 	}
 
 	return 0;
@@ -3315,20 +3307,38 @@ uint64 ItemGroupDatabase::parseBodyNode(const ryml::NodeRef& node) {
 
 			uint16 subgroup;
 
-			if (this->nodeExists(subit, "SubGroup")) {
-				if (!this->asUInt16(subit, "SubGroup", subgroup))
-					continue;
-			} else {
-				subgroup = 1;
-			}
+			if (!this->asUInt16(subit, "SubGroup", subgroup))
+				continue;
 
 			std::shared_ptr<s_item_group_random> random = util::umap_find(group->random, subgroup);
+			bool random_exists = random != nullptr;
 
-			if (random == nullptr) {
+			if (!random_exists) {
 				random = std::make_shared<s_item_group_random>();
 				group->random[subgroup] = random;
 			}
 
+			if (this->nodeExists(subit, "Algorithm")) {
+				std::string sub_algo;
+
+				if (!this->asString(subit, "Algorithm", sub_algo))
+					return 0;
+
+				std::string sub_algo_constant = "SUBGROUP_ALGO_" + sub_algo;
+				int64 constant_algo;
+
+				if (!script_get_constant(sub_algo_constant.c_str(), &constant_algo)) {
+					this->invalidWarning(subit["Algorithm"], "Invalid Algorithm %s.\n", sub_algo.c_str());
+					continue;
+				}
+
+				random->algorithm = static_cast<uint16>(constant_algo);
+			} else {
+				if (!random_exists) {
+					random->algorithm = SUBGROUP_ALGO_RANDOM;
+				}
+			}
+
 			const auto& listNode = subit["List"];
 
 			for (const auto& listit : listNode) {

+ 8 - 1
src/map/itemdb.hpp

@@ -2961,6 +2961,12 @@ enum e_random_item_group {
 	IG_MAX,
 };
 
+enum e_item_subgroup_algorithm : uint16 {
+	SUBGROUP_ALGO_RANDOM,
+	SUBGROUP_ALGO_NATURALRANDOM,
+	SUBGROUP_ALGO_MUST,
+};
+
 /// Enum for bound/sell restricted selling
 enum e_itemshop_restrictions {
 	ISR_NONE = 0x0,
@@ -3139,6 +3145,7 @@ struct s_item_group_entry
 struct s_item_group_random
 {
 	uint32 total_rate;
+	uint16 algorithm;
 	std::unordered_map<uint32, std::shared_ptr<s_item_group_entry>> data; /// index, s_item_group_entry
 };
 
@@ -3296,7 +3303,7 @@ extern ItemDatabase item_db;
 
 class ItemGroupDatabase : public TypesafeCachedYamlDatabase<uint16, s_item_group_db> {
 public:
-	ItemGroupDatabase() : TypesafeCachedYamlDatabase("ITEM_GROUP_DB", 3, 1) {
+	ItemGroupDatabase() : TypesafeCachedYamlDatabase("ITEM_GROUP_DB", 4, 1) {
 
 	}
 

+ 4 - 0
src/map/script_constants.hpp

@@ -16,6 +16,10 @@
 	export_constant(INT_MIN);
 	export_constant(INT_MAX);
 
+	export_constant(SUBGROUP_ALGO_RANDOM);
+	export_constant(SUBGROUP_ALGO_NATURALRANDOM);
+	export_constant(SUBGROUP_ALGO_MUST);
+
 	/* server defines */
 	export_constant(PACKETVER);
 	export_constant(MAX_LEVEL);

+ 6 - 2
src/tool/csv2yaml.cpp

@@ -440,14 +440,14 @@ bool Csv2YamlTool::initialize( int32 argc, char* argv[] ){
 	}
 
 	item_group_txt_data(path_db_mode, path_db);
-	if (!process("ITEM_GROUP_DB", 2, { path_db_mode }, "item_group_db", [](const std::string &path, const std::string &name_ext) -> bool {
+	if (!process("ITEM_GROUP_DB", 4, { path_db_mode }, "item_group_db", [](const std::string &path, const std::string &name_ext) -> bool {
 		return itemdb_read_group_yaml();
 	})) {
 		return false;
 	}
 
 	item_group_txt_data(path_db_import, path_db_import);
-	if (!process("ITEM_GROUP_DB", 2, { path_db_import }, "item_group_db", [](const std::string &path, const std::string &name_ext) -> bool {
+	if (!process("ITEM_GROUP_DB", 4, { path_db_import }, "item_group_db", [](const std::string &path, const std::string &name_ext) -> bool {
 		return itemdb_read_group_yaml();
 	})) {
 		return false;
@@ -4084,6 +4084,10 @@ static bool itemdb_read_group_yaml(void) {
 		for (const auto &item : it.second.item) {	// subgroup
 			body << YAML::BeginMap;
 			body << YAML::Key << "SubGroup" << YAML::Value << item.first;
+			if (item.first == 0)
+				body << YAML::Key << "Algorithm" << YAML::Value << "Must";
+			else if (item.first == 6)
+				body << YAML::Key << "Algorithm" << YAML::Value << "NaturalRandom";
 			body << YAML::Key << "List";
 			body << YAML::BeginSeq;
 			for (const auto &listit : item.second) {

+ 81 - 1
src/tool/yamlupgrade.cpp

@@ -145,7 +145,7 @@ bool YamlUpgradeTool::initialize( int32 argc, char* argv[] ){
 		} ) ){
 		return false;
 	}
-	if( !process( "ITEM_GROUP_DB", 3, root_paths, "item_group_db", []( const std::string& path, const std::string& name_ext, uint32 source_version ) -> bool {
+	if( !process( "ITEM_GROUP_DB", 4, root_paths, "item_group_db", []( const std::string& path, const std::string& name_ext, uint32 source_version ) -> bool {
 		return upgrade_item_group_db( path + name_ext, source_version );
 		} ) ){
 		return false;
@@ -508,6 +508,86 @@ static bool upgrade_item_group_db( std::string file, const uint32 source_version
 			body << YAML::EndMap;
 		}
 
+		if( source_version == 3 ){
+			body << YAML::BeginMap;
+			body << YAML::Key << "Group" << YAML::Value << input["Group"];
+
+			if( input["SubGroups"].IsDefined() ){
+				body << YAML::Key << "SubGroups";
+				body << YAML::BeginSeq;
+
+				for (const auto &it : input["SubGroups"]) {
+					body << YAML::BeginMap;
+					if( !it["SubGroup"].IsDefined() ){
+						ShowError( "Cannot upgrade automatically, SubGroup is missing." );
+						return false;
+					}
+					body << YAML::Key << "SubGroup" << YAML::Value << it["SubGroup"];
+
+					if (it["SubGroup"].as<uint16>() == 0)
+						body << YAML::Key << "Algorithm" << YAML::Value << "Must";
+					else if (it["SubGroup"].as<uint16>() == 6)
+						body << YAML::Key << "Algorithm" << YAML::Value << "NaturalRandom";
+					// else
+						// body << YAML::Key << "Algorithm" << YAML::Value << "Random";
+
+					if( it["List"].IsDefined() )
+						body << YAML::Key << "List";{
+						body << YAML::BeginSeq;
+
+						uint32 index = 0;
+
+						for( auto ListNode : it["List"] ){
+							if( !ListNode["Item"].IsDefined() ){
+								ShowError( "Cannot upgrade automatically, Item is missing" );
+								return false;
+							}
+							body << YAML::BeginMap;
+
+							body << YAML::Key << "Index" << YAML::Value << index;
+							body << YAML::Key << "Item" << YAML::Value << ListNode["Item"];
+
+							if( ListNode["Rate"].IsDefined() )
+								body << YAML::Key << "Rate" << YAML::Value << ListNode["Rate"];
+							if( ListNode["Amount"].IsDefined() )
+								body << YAML::Key << "Amount" << YAML::Value << ListNode["Amount"];
+							if( ListNode["Duration"].IsDefined() )
+								body << YAML::Key << "Duration" << YAML::Value << ListNode["Duration"];
+							if( ListNode["Announced"].IsDefined() )
+								body << YAML::Key << "Announced" << YAML::Value << ListNode["Announced"];
+							if( ListNode["UniqueId"].IsDefined() )
+								body << YAML::Key << "UniqueId" << YAML::Value << ListNode["UniqueId"];
+							if( ListNode["Stacked"].IsDefined() )
+								body << YAML::Key << "Stacked" << YAML::Value << ListNode["Stacked"];
+							if( ListNode["Named"].IsDefined() )
+								body << YAML::Key << "Named" << YAML::Value << ListNode["Named"];
+							if( ListNode["Bound"].IsDefined() )
+								body << YAML::Key << "Bound" << YAML::Value << ListNode["Bound"];
+							if( ListNode["RandomOptionGroup"].IsDefined() )
+								body << YAML::Key << "RandomOptionGroup" << YAML::Value << ListNode["RandomOptionGroup"];
+							if( ListNode["RefineMinimum"].IsDefined() )
+								body << YAML::Key << "RefineMinimum" << YAML::Value << ListNode["RefineMinimum"];
+							if( ListNode["RefineMaximum"].IsDefined() )
+								body << YAML::Key << "RefineMaximum" << YAML::Value << ListNode["RefineMaximum"];
+							if( ListNode["Clear"].IsDefined() )
+								body << YAML::Key << "Clear" << YAML::Value << ListNode["Clear"];
+
+							index++;
+							body << YAML::EndMap;
+						}
+
+						body << YAML::EndSeq;
+					}
+					if( it["Clear"].IsDefined() )
+						body << YAML::Key << "Clear" << YAML::Value << it["Clear"];
+
+					body << YAML::EndMap;
+				}
+				body << YAML::EndSeq;
+			}
+			body << YAML::EndMap;
+		}
+
 		entries++;
 	}
 

Niektóre pliki nie zostały wyświetlone z powodu dużej ilości zmienionych plików