From c9aaf540bf3738eb92db59015ba521f0b60f1e0c Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Fri, 6 Jan 2023 00:23:25 +0100 Subject: [PATCH] Added reloadbarterdb (#7530) Fixes #7520 Thanks to @attackjom --- conf/msg_conf/map_msg.conf | 5 +- doc/atcommands.txt | 7 ++- src/map/atcommand.cpp | 4 ++ src/map/npc.cpp | 104 ++++++++++++++++++++++--------------- src/map/npc.hpp | 3 ++ 5 files changed, 78 insertions(+), 45 deletions(-) diff --git a/conf/msg_conf/map_msg.conf b/conf/msg_conf/map_msg.conf index fb61704159..e5c845c265 100644 --- a/conf/msg_conf/map_msg.conf +++ b/conf/msg_conf/map_msg.conf @@ -927,7 +927,10 @@ // Enchant UI 829: Enchanting is not possible for your item's enchant grade. -//830-899 free +// @reloadbarterdb +830: Barter database has been reloaded. + +//831-899 free //------------------------------------ // More atcommands message diff --git a/doc/atcommands.txt b/doc/atcommands.txt index 43918c3d6e..c22ab7d16e 100644 --- a/doc/atcommands.txt +++ b/doc/atcommands.txt @@ -1419,6 +1419,7 @@ This will also send a packet to clients causing them to close. @reloadstatusdb @reloadachievementdb @reloadattendancedb +@reloadbarterdb Reloads a database or configuration file. @@ -1427,10 +1428,11 @@ Databases: -- itemdb: Item Database -- mobdb: Monster Database -- questdb: Quest Database --- script: NPC Scripts +-- script: NPC Scripts and Barter Database -- skilldb: Skill Database -- achievementdb: Achievement Database -- attendancedb: Attendance Database +-- barterdb: Barter Database Configuration files: -- atcommand: Atcommand Settings @@ -1450,11 +1452,12 @@ Affected files: -- msgconf: atcommands.yml -- pcdb: statpoint.yml, job_exp.yml, skill_tree.yml, attr_fix.yml, job_stats.yml, job_basepoints.yml, level_penalty.yml -- questdb: quest_db.yml --- script: /npc/*.txt, /npc/*.conf +-- script: /npc/*.txt, /npc/*.conf, /npc/barters.yml -- skilldb: skill_db.yml, skill_nocast_db.txt, skill_changematerial_db.txt, skill_damage_db.txt, abra_db.yml, create_arrow_db.yml, produce_db.txt, spellbook_db.yml, magicmushroom_db.yml -- statusdb: attr_fix.yml, size_fix.yml, refine.yml -- achievementdb: achievement_db.yml -- attendancedb: attendance.yml +-- barterdb: /npc/barters.yml Restriction: - Used from 'atcommand' or 'useatcmd'. For @reload & @reloadscript diff --git a/src/map/atcommand.cpp b/src/map/atcommand.cpp index ec7d804fd5..9a3eeeebc8 100644 --- a/src/map/atcommand.cpp +++ b/src/map/atcommand.cpp @@ -4319,6 +4319,9 @@ ACMD_FUNC(reload) { } else if (strstr(command, "attendancedb") || strncmp(message, "attendancedb", 4) == 0) { attendance_db.reload(); clif_displaymessage(fd, msg_txt(sd, 795)); // Attendance database has been reloaded. + }else if( strstr( command, "barterdb" ) || strncmp( message, "barterdb", 4 ) == 0 ){ + barter_db.reload(); + clif_displaymessage(fd, msg_txt(sd, 830)); // Barter database has been reloaded. } return 0; @@ -10951,6 +10954,7 @@ void atcommand_basecommands(void) { ACMD_DEF2("reloadinstancedb", reload), ACMD_DEF2("reloadachievementdb",reload), ACMD_DEF2("reloadattendancedb",reload), + ACMD_DEF2("reloadbarterdb",reload), ACMD_DEF(partysharelvl), ACMD_DEF(mapinfo), ACMD_DEF(dye), diff --git a/src/map/npc.cpp b/src/map/npc.cpp index d227467ed6..1e5dd21eef 100644 --- a/src/map/npc.cpp +++ b/src/map/npc.cpp @@ -410,6 +410,7 @@ uint64 BarterDatabase::parseBodyNode( const ryml::NodeRef& node ){ if( !exists ){ barter = std::make_shared(); barter->name = npcname; + barter->npcid = 0; } if( this->nodeExists( node, "Map" ) ){ @@ -729,8 +730,54 @@ void BarterDatabase::loadingFinished(){ std::shared_ptr barter = pair.second; + bool extended = false; + + // Check if it has to use the extended barter feature or not + for( const auto& itemPair : barter->items ){ + // Normal barter cannot have zeny requirements + if( itemPair.second->price > 0 ){ + extended = true; + break; + } + + // Normal barter needs to have exchange items defined + if( itemPair.second->requirements.empty() ){ + extended = true; + break; + } + + // Normal barter can only exchange 1:1 + if( itemPair.second->requirements.size() > 1 ){ + extended = true; + break; + } + + // Normal barter cannot handle refine + for( const auto& requirement : itemPair.second->requirements ){ + if( requirement.second->refine >= 0 ){ + extended = true; + break; + } + } + + // Check if a refine requirement has been set in the loop above + if( extended ){ + break; + } + } + + if( extended && !battle_config.feature_barter_extended ){ +#ifndef BUILDBOT + ShowError( "Barter %s uses extended mechanics but this is not enabled.\n", barter->name.c_str() ); +#endif + continue; + } + struct npc_data* nd = npc_create_npc( barter->m, barter->x, barter->y ); + // Store the npcid for the destructor + barter->npcid = nd->bl.id; + npc_parsename( nd, barter->name.c_str(), nullptr, nullptr, __FILE__ ":" QUOTE(__LINE__) ); nd->class_ = barter->sprite; @@ -739,48 +786,7 @@ void BarterDatabase::loadingFinished(){ nd->bl.type = BL_NPC; nd->subtype = NPCTYPE_BARTER; - nd->u.barter.extended = false; - - // Check if it has to use the extended barter feature or not - for( const auto& itemPair : barter->items ){ - // Normal barter cannot have zeny requirements - if( itemPair.second->price > 0 ){ - nd->u.barter.extended = true; - break; - } - - // Normal barter needs to have exchange items defined - if( itemPair.second->requirements.empty() ){ - nd->u.barter.extended = true; - break; - } - - // Normal barter can only exchange 1:1 - if( itemPair.second->requirements.size() > 1 ){ - nd->u.barter.extended = true; - break; - } - - // Normal barter cannot handle refine - for( const auto& requirement : itemPair.second->requirements ){ - if( requirement.second->refine >= 0 ){ - nd->u.barter.extended = true; - break; - } - } - - // Check if a refine requirement has been set in the loop above - if( nd->u.barter.extended ){ - break; - } - } - - if( nd->u.barter.extended && !battle_config.feature_barter_extended ){ -#ifndef BUILDBOT - ShowError( "Barter %s uses extended mechanics but this is not enabled.\n", nd->name ); -#endif - continue; - } + nd->u.barter.extended = extended; if( nd->bl.m >= 0 ){ map_addnpc( nd->bl.m, nd ); @@ -840,6 +846,20 @@ void BarterDatabase::loadingFinished(){ TypesafeYamlDatabase::loadingFinished(); } +s_npc_barter::~s_npc_barter(){ + if( this->npcid != 0 ){ + struct npc_data* nd = map_id2nd( this->npcid ); + + // Check if the NPC still exists or has been removed already + if( nd != nullptr ){ + // Delete the NPC + npc_unload( nd, true ); + // Update NPC event database + npc_read_event_script(); + } + } +} + BarterDatabase barter_db; /** diff --git a/src/map/npc.hpp b/src/map/npc.hpp index 0a0c104e63..5b0c223e40 100644 --- a/src/map/npc.hpp +++ b/src/map/npc.hpp @@ -104,6 +104,9 @@ struct s_npc_barter{ uint8 dir; int16 sprite; std::map> items; + int32 npcid; + + ~s_npc_barter(); }; class BarterDatabase : public TypesafeYamlDatabase{