Extended item_group_db.yml (#6173)
* Added Index field The structure now allows to define the same item with different data * Updated the tool yamlupgrade for version upgrade
This commit is contained in:
parent
61311f5912
commit
b4e066a37f
@ -26,8 +26,9 @@
|
||||
# SubGroups:
|
||||
# - SubGroup: SubGroup number associated with the list of item. See doc/item_group.txt for more information.
|
||||
# List: List of item(s) for the SubGroup.
|
||||
# - Item AegisName of item that will be obtained from this item group.
|
||||
# Rate Probability to get the item. See doc/item_group.txt for more information. (Default: 0)
|
||||
# - 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.
|
||||
# Rate Probability to get the item. (Default: 0)
|
||||
# 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)
|
||||
@ -38,10 +39,10 @@
|
||||
# RandomOptionGroup Applies random options of this group to all equipable items (Default: None)
|
||||
# RefineMinimum Applies at least this refine level to all equipable items (Default: 0)
|
||||
# RefineMaximum Applies at most this refine level to all equipable items (Default: 0)
|
||||
# Clear Remove the given item. (Optional)
|
||||
# Clear Whether the current datas should be removed. (Optional)
|
||||
# Clear Remove the given SubGroup. (Optional)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: ITEM_GROUP_DB
|
||||
Version: 2
|
||||
Version: 3
|
||||
|
@ -26,8 +26,9 @@
|
||||
# SubGroups:
|
||||
# - SubGroup: SubGroup number associated with the list of item. See doc/item_group.txt for more information.
|
||||
# List: List of item(s) for the SubGroup.
|
||||
# - Item AegisName of item that will be obtained from this item group.
|
||||
# Rate Probability to get the item. See doc/item_group.txt for more information. (Default: 0)
|
||||
# - 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.
|
||||
# Rate Probability to get the item. (Default: 0)
|
||||
# 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)
|
||||
@ -38,13 +39,13 @@
|
||||
# RandomOptionGroup Applies random options of this group to all equipable items (Default: None)
|
||||
# RefineMinimum Applies at least this refine level to all equipable items (Default: 0)
|
||||
# RefineMaximum Applies at most this refine level to all equipable items (Default: 0)
|
||||
# Clear Remove the given item. (Optional)
|
||||
# Clear Whether the current datas should be removed. (Optional)
|
||||
# Clear Remove the given SubGroup. (Optional)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: ITEM_GROUP_DB
|
||||
Version: 2
|
||||
Version: 3
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
|
File diff suppressed because it is too large
Load Diff
61155
db/re/item_group_db.yml
61155
db/re/item_group_db.yml
File diff suppressed because it is too large
Load Diff
@ -43,8 +43,12 @@ GroupID: See the "Item Group ID" section in 'src/map/itemdb.hpp' and the "item g
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Index: Unique number that can be used to add the same Item with different data in the list.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
Item: Available item that will be obtained from this item group.
|
||||
Requires the AegisName of the item.
|
||||
Requires the AegisName of the item.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@ -52,12 +56,14 @@ Rate: Probability to get the item. Not a percentage value!
|
||||
|
||||
Examples:
|
||||
- Group: MyItemGroup
|
||||
Contain:
|
||||
SubGroups:
|
||||
- SubGroup: 1
|
||||
List:
|
||||
- Item: Knife
|
||||
- Index: 0
|
||||
Item: Knife
|
||||
Rate: 5
|
||||
- Item: Dagger
|
||||
- Index: 1
|
||||
Item: Dagger
|
||||
Rate: 1
|
||||
|
||||
- Knife has chance 5/6 (83.3%) to be obtained
|
||||
@ -74,22 +80,28 @@ SubGroup: Setting this to '0' makes the item always obtainable ("must" item).
|
||||
|
||||
Item Group:
|
||||
- Group: MyItemGroup
|
||||
Contain:
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Knife # "must" item(s)
|
||||
- Item: Dagger # "must" item(s)
|
||||
- Index: 0
|
||||
Item: Knife # "must" item(s)
|
||||
- Index: 1
|
||||
Item: Dagger # "must" item(s)
|
||||
- SubGroup: 1
|
||||
List:
|
||||
- Item: Stiletto # random at SubGroup 1
|
||||
- Index: 0
|
||||
Item: Stiletto # random at SubGroup 1
|
||||
Rate: 5
|
||||
- Item: Stiletto_ # random at SubGroup 1
|
||||
- Index: 1
|
||||
Item: Stiletto_ # random at SubGroup 1
|
||||
Rate: 2
|
||||
- SubGroup: 2
|
||||
List:
|
||||
- Item: Stiletto # random at SubGroup 2
|
||||
- Index: 0
|
||||
Item: Stiletto # random at SubGroup 2
|
||||
Rate: 5
|
||||
- Item: Dagger_ # random at SubGroup 2
|
||||
- Index: 1
|
||||
Item: Dagger_ # random at SubGroup 2
|
||||
Rate: 4
|
||||
|
||||
Usages:
|
||||
|
@ -9,8 +9,9 @@
|
||||
# SubGroups:
|
||||
# - SubGroup: SubGroup number associated with the list of item. See doc/item_group.txt for more information.
|
||||
# List: List of item(s) for the SubGroup.
|
||||
# - Item AegisName of item that will be obtained from this item group.
|
||||
# Rate Probability to get the item. See doc/item_group.txt for more information. (Default: 0)
|
||||
# - 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.
|
||||
# Rate Probability to get the item. (Default: 0)
|
||||
# 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)
|
||||
@ -21,6 +22,6 @@
|
||||
# RandomOptionGroup Applies random options of this group to all equipable items (Default: None)
|
||||
# RefineMinimum Applies at least this refine level to all equipable items (Default: 0)
|
||||
# RefineMaximum Applies at most this refine level to all equipable items (Default: 0)
|
||||
# Clear Remove the given item. (Optional)
|
||||
# Clear Whether the current datas should be removed. (Optional)
|
||||
# Clear Remove the given SubGroup. (Optional)
|
||||
###########################################################################
|
||||
|
@ -3300,43 +3300,58 @@ uint64 ItemGroupDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
const auto& listNode = subit["List"];
|
||||
|
||||
for (const auto& listit : listNode) {
|
||||
uint32 index;
|
||||
|
||||
if (!this->asUInt32(listit, "Index", index))
|
||||
continue;
|
||||
|
||||
if (this->nodeExists(listit, "Clear")) {
|
||||
std::string item_name;
|
||||
bool active;
|
||||
|
||||
if (!this->asString(listit, "Clear", item_name))
|
||||
if (!this->asBool(listit, "Clear", active) || !active)
|
||||
continue;
|
||||
|
||||
std::shared_ptr<item_data> item = item_db.search_aegisname( item_name.c_str() );
|
||||
|
||||
if (item == nullptr) {
|
||||
this->invalidWarning(listit["Clear"], "Unknown Item %s. Clear failed.\n", item_name.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (random->data.erase(item->nameid) == 0)
|
||||
this->invalidWarning(listit["Clear"], "Item %hu doesn't exist in the SubGroup %hu (group %s). Clear failed.\n", item->nameid, subgroup, group_name.c_str());
|
||||
if (random->data.erase(index) == 0)
|
||||
this->invalidWarning(listit["Clear"], "Index %u doesn't exist in the SubGroup %hu (group %s). Clear failed.\n", index, subgroup, group_name.c_str());
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
std::string item_name;
|
||||
|
||||
if (!this->asString(listit, "Item", item_name))
|
||||
continue;
|
||||
|
||||
std::shared_ptr<item_data> item = item_db.search_aegisname( item_name.c_str() );
|
||||
|
||||
if (item == nullptr) {
|
||||
this->invalidWarning(listit["Item"], "Unknown Item %s.\n", item_name.c_str());
|
||||
continue;
|
||||
}
|
||||
|
||||
std::shared_ptr<s_item_group_entry> entry = util::umap_find(random->data, item->nameid);
|
||||
std::shared_ptr<s_item_group_entry> entry = util::umap_find(random->data, index);
|
||||
bool entry_exists = entry != nullptr;
|
||||
|
||||
if (!entry_exists) {
|
||||
if (!this->nodesExist(listit, { "Item" }))
|
||||
return 0;
|
||||
|
||||
entry = std::make_shared<s_item_group_entry>();
|
||||
random->data[item->nameid] = entry;
|
||||
random->data[index] = entry;
|
||||
}
|
||||
|
||||
std::shared_ptr<item_data> item = nullptr;
|
||||
|
||||
if (this->nodeExists(listit, "Item")) {
|
||||
std::string item_name;
|
||||
|
||||
if (!this->asString(listit, "Item", item_name))
|
||||
continue;
|
||||
|
||||
item = item_db.search_aegisname( item_name.c_str() );
|
||||
|
||||
if (item == nullptr) {
|
||||
this->invalidWarning(listit["Item"], "Unknown Item %s.\n", item_name.c_str());
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
if (!entry_exists) {
|
||||
item = item_db.find( entry->nameid );
|
||||
}
|
||||
}
|
||||
|
||||
// (shouldn't happen)
|
||||
if (item == nullptr) {
|
||||
this->invalidWarning(listit["index"], "Missing Item definition for Index %u.\n", index);
|
||||
continue;
|
||||
}
|
||||
|
||||
entry->nameid = item->nameid;
|
||||
|
@ -2016,7 +2016,7 @@ struct s_item_group_entry
|
||||
struct s_item_group_random
|
||||
{
|
||||
uint32 total_rate;
|
||||
std::unordered_map<t_itemid, std::shared_ptr<s_item_group_entry>> data; /// item ID, s_item_group_entry
|
||||
std::unordered_map<uint32, std::shared_ptr<s_item_group_entry>> data; /// index, s_item_group_entry
|
||||
|
||||
std::shared_ptr<s_item_group_entry> get_random_itemsubgroup();
|
||||
};
|
||||
@ -2175,7 +2175,7 @@ extern ItemDatabase item_db;
|
||||
|
||||
class ItemGroupDatabase : public TypesafeCachedYamlDatabase<uint16, s_item_group_db> {
|
||||
public:
|
||||
ItemGroupDatabase() : TypesafeCachedYamlDatabase("ITEM_GROUP_DB", 2, 1) {
|
||||
ItemGroupDatabase() : TypesafeCachedYamlDatabase("ITEM_GROUP_DB", 3, 1) {
|
||||
|
||||
}
|
||||
|
||||
|
@ -11,6 +11,7 @@ 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 );
|
||||
static bool upgrade_item_group_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) {
|
||||
@ -144,6 +145,11 @@ bool YamlUpgradeTool::initialize( int 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 {
|
||||
return upgrade_item_group_db( path + name_ext, source_version );
|
||||
} ) ){
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -426,6 +432,90 @@ static bool upgrade_enchantgrade_db( std::string file, const uint32 source_versi
|
||||
return true;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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 );
|
||||
|
Loading…
x
Reference in New Issue
Block a user