Jelajahi Sumber

Changed field and constant names
* Algorithm -> Draws
* SUBGROUP_ALGO_NATURALRANDOM -> GROUP_DRAWS_NOREPLACEMENT (draws without replacement)
* SUBGROUP_ALGO_RANDOM -> GROUP_DRAWS_REPLACEMENT (draws with replacement)
* SUBGROUP_ALGO_MUST -> GROUP_DRAWS_MUST

Atemo 5 bulan lalu
induk
melakukan
7cd8ab8116

+ 2 - 2
db/import-tmpl/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,7 +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)
+#       Draws:                 Type of draws associated with SubGroup. (Default: Replacement)
 #       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.

+ 1 - 1
db/item_group_db.yml

@@ -25,7 +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)
+#       Draws:                 Type of draws associated with SubGroup. (Default: Replacement)
 #       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.

+ 63 - 63
db/pre-re/item_group_db.yml

@@ -25,7 +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)
+#       Draws:                 Type of draws associated with SubGroup. (Default: Replacement)
 #       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.
@@ -52,7 +52,7 @@ Body:
   - Group: ACCESORY
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Ring
@@ -183,7 +183,7 @@ Body:
   - Group: BLEUBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Milk
@@ -221,7 +221,7 @@ Body:
   - Group: BLUEBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -3292,7 +3292,7 @@ Body:
   - Group: BOMB
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Apple_Bomb
@@ -3321,7 +3321,7 @@ Body:
   - Group: BOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Old_Blue_Box
@@ -3335,7 +3335,7 @@ Body:
   - Group: CANDY
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Candy
@@ -3346,7 +3346,7 @@ Body:
   - Group: CARDALBUM
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Poring_Card
@@ -4437,7 +4437,7 @@ Body:
   - Group: CASH_FOOD
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Str_Dish10_
@@ -4460,7 +4460,7 @@ Body:
   - Group: CHERISH_BOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Dog_Cap_
@@ -4474,7 +4474,7 @@ Body:
   - Group: CHERISH_BOX_ORI
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Ragnarok_Limited_Ed
@@ -4494,7 +4494,7 @@ Body:
   - Group: COOKIEBAG
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Candy
@@ -4547,7 +4547,7 @@ Body:
   - Group: EASTER_SCROLL
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: No_Recipient
@@ -4594,7 +4594,7 @@ Body:
   - Group: EGGBOY
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Grape
@@ -4620,7 +4620,7 @@ Body:
   - Group: EGGGIRL
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Grape
@@ -4646,7 +4646,7 @@ Body:
   - Group: ELEMENT
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Scarlet_Pts
@@ -4663,7 +4663,7 @@ Body:
   - Group: FIRSTAID
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -4722,7 +4722,7 @@ Body:
   - Group: FISH
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Fish_Slice
@@ -4733,7 +4733,7 @@ Body:
   - Group: FOOD
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Royal_Jelly
@@ -4804,7 +4804,7 @@ Body:
   - Group: FOODBAG
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Apple
@@ -4941,7 +4941,7 @@ Body:
   - Group: FRUIT
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Apple
@@ -4961,7 +4961,7 @@ Body:
   - Group: GEMSTONE
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Yellow_Gemstone
@@ -4975,7 +4975,7 @@ Body:
   - Group: GIFTBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -5190,7 +5190,7 @@ Body:
   - Group: GIFTBOXCHINA
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -5987,7 +5987,7 @@ Body:
   - Group: GIFTBOX_1
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -6202,7 +6202,7 @@ Body:
   - Group: GIFTBOX_2
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -6417,7 +6417,7 @@ Body:
   - Group: GIFTBOX_3
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -6632,7 +6632,7 @@ Body:
   - Group: GIFTBOX_4
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -6847,7 +6847,7 @@ Body:
   - Group: GREENBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Chocolate_Drink
@@ -6885,7 +6885,7 @@ Body:
   - Group: HERB
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Herb
@@ -6899,7 +6899,7 @@ Body:
   - Group: HOMETOWNGIFT
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Korea_Rice_Cake
@@ -6928,7 +6928,7 @@ Body:
   - Group: JEWEL
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Yellow_Gemstone
@@ -6993,7 +6993,7 @@ Body:
   - Group: JUICE
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Apple_Juice
@@ -7007,7 +7007,7 @@ Body:
   - Group: LOTTOBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Lotto31
@@ -7042,7 +7042,7 @@ Body:
   - Group: LOUISE_COSTUME_BOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Bag
@@ -7053,7 +7053,7 @@ Body:
   - Group: MAGICCARDALBUM
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Ghostring_Card
@@ -7151,7 +7151,7 @@ Body:
   - Group: MASK
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Mr_Smile
@@ -7195,7 +7195,7 @@ Body:
   - Group: MASQUERADE
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Drooping_Nine_Tail_
@@ -7212,7 +7212,7 @@ Body:
   - Group: MASQUERADE_2
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Dress_Hat
@@ -7229,7 +7229,7 @@ Body:
   - Group: MEAT
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Meat
@@ -7240,7 +7240,7 @@ Body:
   - Group: MERCENARY
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Bow_Mercenary_Scroll1
@@ -7335,7 +7335,7 @@ Body:
   - Group: MINERAL
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Emperium
@@ -7400,7 +7400,7 @@ Body:
   - Group: OLDGIFTBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Fallen_Leaves_
@@ -7414,7 +7414,7 @@ Body:
   - Group: ORE
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Iron_Ore
@@ -7479,7 +7479,7 @@ Body:
   - Group: PIERRE_TREASUREBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Old_Blue_Box
@@ -7568,7 +7568,7 @@ Body:
   - Group: POISON
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Poison_Paralysis
@@ -7597,7 +7597,7 @@ Body:
   - Group: POTION
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -7614,7 +7614,7 @@ Body:
   - Group: QUIVER
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Arrow_Container
@@ -7658,7 +7658,7 @@ Body:
   - Group: RECOVERY
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Fruit_Of_Mastela
@@ -7705,7 +7705,7 @@ Body:
   - Group: REDBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Cat_Hat
@@ -7752,7 +7752,7 @@ Body:
   - Group: REDBOX_2
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Alice_Doll
@@ -7769,7 +7769,7 @@ Body:
   - Group: RESIST
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Resist_Fire
@@ -7786,7 +7786,7 @@ Body:
   - Group: SCROLL
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Earth_Scroll_1_3
@@ -7845,7 +7845,7 @@ Body:
   - Group: TAMING
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Unripe_Apple
@@ -8000,7 +8000,7 @@ Body:
   - Group: THROWABLE
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Mysterious_Powder
@@ -8074,7 +8074,7 @@ Body:
   - Group: TOKEN_OF_SIEGFRIED
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: F_Token_Of_Siegfried
@@ -8088,7 +8088,7 @@ Body:
   - Group: TRESURE_BOX_WOE
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Old_Blue_Box
@@ -8153,7 +8153,7 @@ Body:
   - Group: VIOLETBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Red_Potion
@@ -10927,7 +10927,7 @@ Body:
   - Group: XMAS_GIFT
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: HandMade_Chocolate
@@ -10989,7 +10989,7 @@ Body:
   - Group: YELLOWBOX
     SubGroups:
       - SubGroup: 6
-        Algorithm: NaturalRandom
+        Draws: NoReplacement
         List:
           - Index: 0
             Item: Elephant_Hat_
@@ -11006,7 +11006,7 @@ Body:
   - Group: MF_NOTELEPORT
     SubGroups:
       - SubGroup: 0
-        Algorithm: Must
+        Draws: Must
         List:
           - Index: 0
             Item: Wing_Of_Fly
@@ -11021,7 +11021,7 @@ Body:
   - Group: MF_NORETURN
     SubGroups:
       - SubGroup: 0
-        Algorithm: Must
+        Draws: Must
         List:
           - Index: 0
             Item: Wing_Of_Butterfly
@@ -11070,7 +11070,7 @@ Body:
   - Group: GIANT_FLY_WING
     SubGroups:
       - SubGroup: 0
-        Algorithm: Must
+        Draws: Must
         List:
           - Index: 0
             Item: Giant_Fly_Wing

File diff ditekan karena terlalu besar
+ 112 - 112
db/re/item_group_db.yml


+ 6 - 6
doc/item_group.txt

@@ -79,25 +79,25 @@ SubGroup: Unique number to create a list of item.
 
 ---------------------------------------
 
-Algorithm: Type of algorithm associated with SubGroup.
+Draws: Type of draws associated with SubGroup.
 
-Random             - Random item.
+Replacement        - Draws with replacement. An item selected in the draw can still be selected in the next draws.
 Must               - Makes the item(s) always obtainable ("must" item).
-NaturalRandom      - Random item. (same result as "Random" for now)
+NoReplacement      - Draws without replacement. An item selected in the draw can't be selected in the next draws. Only when the group is completely empty or the server restarts, the group refills.
 
 Example:
 	Item Group:
       - Group: MyItemGroup
         SubGroups:
           - SubGroup: 0
-            Algorithm: Must
+            Draws: Must
             List:
               - Index: 0
                 Item: Knife       # "must" item(s)
               - Index: 1
                 Item: Dagger      # "must" item(s)
           - SubGroup: 1
-            Algorithm: Random
+            Draws: Replacement
             List:
               - Index: 0
                 Item: Stiletto    # random at SubGroup 1
@@ -106,7 +106,7 @@ Example:
                 Item: Stiletto_   # random at SubGroup 1
                 Rate: 2
           - SubGroup: 2
-            Algorithm: Random
+            Draws: Replacement
             List:
               - Index: 0
                 Item: Stiletto    # random at SubGroup 2

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

@@ -8,7 +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)
+#       Draws:                 Type of draws associated with SubGroup. (Default: Replacement)
 #       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.

+ 84 - 43
src/map/itemdb.cpp

@@ -2888,33 +2888,38 @@ uint16 itemdb_searchname_array(std::map<t_itemid, std::shared_ptr<item_data>> &d
 	return static_cast<uint16>(data.size());
 }
 
-std::shared_ptr<s_item_group_entry> ItemGroupDatabase::get_random_itemsubgroup(std::shared_ptr<s_item_group_random> random, e_group_search_type search_type) {
+std::shared_ptr<s_item_group_entry> ItemGroupDatabase::get_random_itemsubgroup(std::shared_ptr<s_item_group_random> random, e_group_draws_type search_type) {
 	if (random == nullptr)
 		return nullptr;
 
-	if (search_type == GROUP_SEARCH_DROP) {
-		// We pick a random item from the group and then do a drop check based on the rate
-		std::shared_ptr<s_item_group_entry> entry = util::umap_random(random->data);
-		if (rnd_chance_official<uint16>(entry->rate, 10000))
-			return entry;
-	}
-	else {
-		// Each item has x positions whereas x is the rate defined for the item in the umap
-		// We pick a random position and find the item that is at this position
-		uint32 pos = rnd_value<uint32>(1, random->total_rate);
-		uint32 current_pos = 1;
-		// Iterate through each item in the umap
-		for (const auto& [index, entry] : random->data) {
-			if (entry == nullptr)
-				return nullptr;
-			// If rate is 0 it means that this is SubGroup 0 which should just return any random item
-			if (entry->rate == 0)
-				return util::umap_random(random->data);
-			// We move "rate" positions
-			current_pos += entry->rate;
-			// If we passed the target position, entry is the item we are looking for
-			if (current_pos > pos)
+	switch( search_type ) {
+		case GROUP_DRAWS_DROP: {
+			// We pick a random item from the group and then do a drop check based on the rate. On fail, do not return any item
+			std::shared_ptr<s_item_group_entry> entry = util::umap_random(random->data);
+			if (rnd_chance_official<uint16>(entry->rate, 10000))
 				return entry;
+			break;
+		}
+		case GROUP_DRAWS_NOREPLACEMENT:	// placeholder
+		case GROUP_DRAWS_REPLACEMENT: {
+			// Each item has x positions whereas x is the rate defined for the item in the umap
+			// We pick a random position and find the item that is at this position
+			uint32 pos = rnd_value<uint32>(1, random->total_rate);
+			uint32 current_pos = 1;
+			// Iterate through each item in the umap
+			for (const auto& [index, entry] : random->data) {
+				if (entry == nullptr)
+					return nullptr;
+				// Return any random item if rate is 0
+				if (entry->rate == 0)
+					return util::umap_random(random->data);
+				// We move "rate" positions
+				current_pos += entry->rate;
+				// If we passed the target position, entry is the item we are looking for
+				if (current_pos > pos)
+					return entry;
+			}
+			break;
 		}
 	}
 	// Return nullptr on fail
@@ -2925,10 +2930,10 @@ std::shared_ptr<s_item_group_entry> ItemGroupDatabase::get_random_itemsubgroup(s
 * Return a random group entry from Item Group
 * @param group_id
 * @param sub_group
-* @param search_type: see e_group_search_type
+* @param search_type: see e_group_draws_type
 * @return Item group entry or nullptr on fail
 */
-std::shared_ptr<s_item_group_entry> ItemGroupDatabase::get_random_entry(uint16 group_id, uint8 sub_group, e_group_search_type search_type) {
+std::shared_ptr<s_item_group_entry> ItemGroupDatabase::get_random_entry(uint16 group_id, uint8 sub_group, e_group_draws_type search_type) {
 	std::shared_ptr<s_item_group_db> group = this->find(group_id);
 
 	if (group == nullptr) {
@@ -2943,6 +2948,36 @@ std::shared_ptr<s_item_group_entry> ItemGroupDatabase::get_random_entry(uint16 g
 		ShowError("get_random_entry: No item entries for group id %hu and sub group %hu.\n", group_id, sub_group);
 		return nullptr;
 	}
+	if (search_type > GROUP_DRAWS_MUST) {
+		ShowError("get_random_entry: Invalid search_type %hu for group id %hu, sub group %hu.\n", search_type, group_id, sub_group);
+		return nullptr;
+	}
+
+	return this->get_random_itemsubgroup(group->random[sub_group], search_type);
+}
+
+std::shared_ptr<s_item_group_entry> ItemGroupDatabase::get_random_entry(uint16 group_id, uint8 sub_group) {
+	std::shared_ptr<s_item_group_db> group = this->find(group_id);
+
+	if (group == nullptr) {
+		ShowError("get_random_entry: Invalid group id %hu.\n", group_id);
+		return nullptr;
+	}
+	if (group->random.empty()) {
+		ShowError("get_random_entry: No item entries for group id %hu.\n", group_id);
+		return nullptr;
+	}
+	if (group->random.count(sub_group) == 0) {
+		ShowError("get_random_entry: No item entries for group id %hu and sub group %hu.\n", group_id, sub_group);
+		return nullptr;
+	}
+
+	e_group_draws_type search_type = group->random[sub_group]->draws;
+
+	if (search_type > GROUP_DRAWS_MUST) {
+		ShowError("get_random_entry: Invalid search_type %hu for group id %hu, sub group %hu.\n", search_type, group_id, sub_group);
+		return nullptr;
+	}
 
 	return this->get_random_itemsubgroup(group->random[sub_group], search_type);
 }
@@ -3030,11 +3065,17 @@ uint8 ItemGroupDatabase::pc_get_itemgroup( uint16 group_id, bool identify, map_s
 		return 0;
 
 	for (const auto &random : group->random) {
-		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 );
+		switch( random.second->draws ) {
+			case GROUP_DRAWS_REPLACEMENT:
+				this->pc_get_itemgroup_sub( sd, identify, this->get_random_itemsubgroup( random.second, GROUP_DRAWS_REPLACEMENT ) );
+				break;
+			case GROUP_DRAWS_NOREPLACEMENT:
+				this->pc_get_itemgroup_sub( sd, identify, this->get_random_itemsubgroup( random.second, GROUP_DRAWS_NOREPLACEMENT ) );
+				break;
+			case GROUP_DRAWS_MUST:
+				for (const auto &it : random.second->data)
+					this->pc_get_itemgroup_sub( sd, identify, it.second );
+				break;
 		}
 	}
 
@@ -3318,24 +3359,24 @@ uint64 ItemGroupDatabase::parseBodyNode(const ryml::NodeRef& node) {
 				group->random[subgroup] = random;
 			}
 
-			if (this->nodeExists(subit, "Algorithm")) {
-				std::string sub_algo;
+			if (this->nodeExists(subit, "Draws")) {
+				std::string sub_str;
 
-				if (!this->asString(subit, "Algorithm", sub_algo))
+				if (!this->asString(subit, "Draws", sub_str))
 					return 0;
 
-				std::string sub_algo_constant = "SUBGROUP_ALGO_" + sub_algo;
-				int64 constant_algo;
+				std::string sub_constant_str = "GROUP_DRAWS_" + sub_str;
+				int64 constant_str;
 
-				if (!script_get_constant(sub_algo_constant.c_str(), &constant_algo)) {
-					this->invalidWarning(subit["Algorithm"], "Invalid Algorithm %s.\n", sub_algo.c_str());
+				if (!script_get_constant(sub_constant_str.c_str(), &constant_str)) {
+					this->invalidWarning(subit["Draws"], "Invalid Draws %s.\n", sub_str.c_str());
 					continue;
 				}
 
-				random->algorithm = static_cast<uint16>(constant_algo);
+				random->draws = static_cast<e_group_draws_type>(constant_str);
 			} else {
 				if (!random_exists) {
-					random->algorithm = SUBGROUP_ALGO_RANDOM;
+					random->draws = GROUP_DRAWS_REPLACEMENT;
 				}
 			}
 
@@ -3410,12 +3451,12 @@ uint64 ItemGroupDatabase::parseBodyNode(const ryml::NodeRef& node) {
 						entry->rate = 0;
 				}
 
-				if (random->algorithm == SUBGROUP_ALGO_MUST && entry->rate > 0) {
-					this->invalidWarning(listit["Item"], "Item cannot have a rate with \"Must\" algorithm. Defaulting Rate to 0.\n");
+				if (random->draws == GROUP_DRAWS_MUST && entry->rate > 0) {
+					this->invalidWarning(listit["Item"], "Item cannot have a rate with \"Must\" draws. Defaulting Rate to 0.\n");
 					entry->rate = 0;
 				}
-				if (random->algorithm != SUBGROUP_ALGO_MUST && entry->rate == 0) {
-					this->invalidWarning(listit["Item"], "Item must have a Rate for algorithms other than \"Must\", item skipped.\n");
+				if (random->draws != GROUP_DRAWS_MUST && entry->rate == 0) {
+					this->invalidWarning(listit["Item"], "Item must have a Rate for draws other than \"Must\", item skipped.\n");
 					continue;
 				}
 

+ 9 - 12
src/map/itemdb.hpp

@@ -2961,12 +2961,6 @@ 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,
@@ -3015,9 +3009,11 @@ enum e_delay_consume : uint8 {
 };
 
 /// Enum for different ways to search an item group
-enum e_group_search_type : uint8 {
-	GROUP_SEARCH_BOX = 0, // Always return an item from the group, rate determines which item is more likely to be returned
-	GROUP_SEARCH_DROP = 1, // Pick one item from the group and check use rate as drop rate, on fail, do not return any item
+enum e_group_draws_type : uint8 {
+	GROUP_DRAWS_REPLACEMENT, // Draws with replacement. Always return an item from the group, rate determines which item is more likely to be returned
+	GROUP_DRAWS_DROP, // Draws with replacement. Pick one item from the group and check use rate as drop rate, on fail, do not return any item
+	GROUP_DRAWS_NOREPLACEMENT, // Draws without replacement. Always return an item from the group, rate determines which item is more likely to be returned
+	GROUP_DRAWS_MUST, // Give all items of a subgroup without using rates
 };
 
 /// Item combo struct
@@ -3145,7 +3141,7 @@ struct s_item_group_entry
 struct s_item_group_random
 {
 	uint32 total_rate;
-	uint16 algorithm;
+	e_group_draws_type draws;
 	std::unordered_map<uint32, std::shared_ptr<s_item_group_entry>> data; /// index, s_item_group_entry
 };
 
@@ -3314,11 +3310,12 @@ public:
 	// Additional
 	bool item_exists(uint16 group_id, t_itemid nameid);
 	int16 item_exists_pc(map_session_data *sd, uint16 group_id);
-	std::shared_ptr<s_item_group_entry> get_random_entry(uint16 group_id, uint8 sub_group, e_group_search_type search_type = GROUP_SEARCH_BOX);
+	std::shared_ptr<s_item_group_entry> get_random_entry(uint16 group_id, uint8 sub_group, e_group_draws_type search_type);
+	std::shared_ptr<s_item_group_entry> get_random_entry(uint16 group_id, uint8 sub_group);
 	uint8 pc_get_itemgroup( uint16 group_id, bool identify, map_session_data& sd );
 
 private:
-	std::shared_ptr<s_item_group_entry> get_random_itemsubgroup(std::shared_ptr<s_item_group_random> random, e_group_search_type search_type = GROUP_SEARCH_BOX);
+	std::shared_ptr<s_item_group_entry> get_random_itemsubgroup(std::shared_ptr<s_item_group_random> random, e_group_draws_type search_type = GROUP_DRAWS_REPLACEMENT);
 	void pc_get_itemgroup_sub( map_session_data& sd, bool identify, std::shared_ptr<s_item_group_entry> data );
 };
 

+ 2 - 2
src/map/mob.cpp

@@ -2961,7 +2961,7 @@ int32 mob_dead(struct mob_data *md, struct block_list *src, int32 type)
 						mobdrop.rate = drop_rate;
 					}
 					else {
-						std::shared_ptr<s_item_group_entry> entry = itemdb_group.get_random_entry(it.group, 1, GROUP_SEARCH_DROP);
+						std::shared_ptr<s_item_group_entry> entry = itemdb_group.get_random_entry(it.group, 1, GROUP_DRAWS_DROP);
 						if (entry == nullptr) continue;
 						mobdrop.nameid = entry->nameid;
 						mobdrop.rate = entry->rate * drop_rate / 10000;
@@ -3018,7 +3018,7 @@ int32 mob_dead(struct mob_data *md, struct block_list *src, int32 type)
 
 		// Ore Discovery (triggers if owner has loot priority, does not require to be the killer)
 		if (mvp_sd && pc_checkskill(mvp_sd, BS_FINDINGORE) > 0) {
-			std::shared_ptr<s_item_group_entry> entry = itemdb_group.get_random_entry(IG_ORE, 1, GROUP_SEARCH_DROP);
+			std::shared_ptr<s_item_group_entry> entry = itemdb_group.get_random_entry(IG_ORE, 1, GROUP_DRAWS_DROP);
 			if (entry != nullptr) {
 				s_mob_drop mobdrop = {};
 				mobdrop.nameid = entry->nameid;

+ 4 - 4
src/map/script_constants.hpp

@@ -16,10 +16,6 @@
 	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);
@@ -10561,6 +10557,10 @@
 	export_constant(SEARCHSTORE_EFFECT_NORMAL);
 	export_constant(SEARCHSTORE_EFFECT_REMOTE);
 
+	export_constant(GROUP_DRAWS_REPLACEMENT);
+	export_constant(GROUP_DRAWS_NOREPLACEMENT);
+	export_constant(GROUP_DRAWS_MUST);
+
 	#undef export_constant
 	#undef export_constant2
 	#undef export_parameter

+ 1 - 73
src/tool/yamlupgrade.cpp

@@ -436,79 +436,7 @@ static bool upgrade_item_group_db( std::string file, const uint32 source_version
 	size_t entries = 0;
 
 	for( const auto input : inNode["Body"] ){
-		// If under version 3
-		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() ){
-						body << YAML::Key << "SubGroup" << YAML::Value << it["SubGroup"];
-					}
-
-					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;
-		}
-
-		if( source_version == 3 ){
+		if( source_version < 4 ){
 			body << YAML::BeginMap;
 			body << YAML::Key << "Group" << YAML::Value << input["Group"];
 

Beberapa file tidak ditampilkan karena terlalu banyak file yang berubah dalam diff ini