Browse Source

Added reloadbarterdb (#7530)

Fixes #7520

Thanks to @attackjom
Lemongrass3110 2 năm trước cách đây
mục cha
commit
c9aaf540bf
5 tập tin đã thay đổi với 54 bổ sung21 xóa
  1. 4 1
      conf/msg_conf/map_msg.conf
  2. 5 2
      doc/atcommands.txt
  3. 4 0
      src/map/atcommand.cpp
  4. 38 18
      src/map/npc.cpp
  5. 3 0
      src/map/npc.hpp

+ 4 - 1
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

+ 5 - 2
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

+ 4 - 0
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),

+ 38 - 18
src/map/npc.cpp

@@ -410,6 +410,7 @@ uint64 BarterDatabase::parseBodyNode( const ryml::NodeRef& node ){
 	if( !exists ){
 		barter = std::make_shared<s_npc_barter>();
 		barter->name = npcname;
+		barter->npcid = 0;
 	}
 
 	if( this->nodeExists( node, "Map" ) ){
@@ -729,59 +730,64 @@ void BarterDatabase::loadingFinished(){
 
 		std::shared_ptr<s_npc_barter> barter = pair.second;
 
-		struct npc_data* nd = npc_create_npc( barter->m, barter->x, barter->y );
-
-		npc_parsename( nd, barter->name.c_str(), nullptr, nullptr, __FILE__ ":" QUOTE(__LINE__) );
-
-		nd->class_ = barter->sprite;
-		nd->speed = 200;
-
-		nd->bl.type = BL_NPC;
-		nd->subtype = NPCTYPE_BARTER;
-
-		nd->u.barter.extended = false;
+		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 ){
-				nd->u.barter.extended = true;
+				extended = true;
 				break;
 			}
 
 			// Normal barter needs to have exchange items defined
 			if( itemPair.second->requirements.empty() ){
-				nd->u.barter.extended = true;
+				extended = true;
 				break;
 			}
 
 			// Normal barter can only exchange 1:1
 			if( itemPair.second->requirements.size() > 1 ){
-				nd->u.barter.extended = true;
+				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;
+					extended = true;
 					break;
 				}
 			}
 
 			// Check if a refine requirement has been set in the loop above
-			if( nd->u.barter.extended ){
+			if( extended ){
 				break;
 			}
 		}
 
-		if( nd->u.barter.extended && !battle_config.feature_barter_extended ){
+		if( extended && !battle_config.feature_barter_extended ){
 #ifndef BUILDBOT
-			ShowError( "Barter %s uses extended mechanics but this is not enabled.\n", nd->name );
+			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;
+		nd->speed = 200;
+
+		nd->bl.type = BL_NPC;
+		nd->subtype = NPCTYPE_BARTER;
+
+		nd->u.barter.extended = extended;
+
 		if( nd->bl.m >= 0 ){
 			map_addnpc( nd->bl.m, nd );
 			npc_setcells( 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;
 
 /**

+ 3 - 0
src/map/npc.hpp

@@ -104,6 +104,9 @@ struct s_npc_barter{
 	uint8 dir;
 	int16 sprite;
 	std::map<uint16, std::shared_ptr<s_npc_barter_item>> items;
+	int32 npcid;
+
+	~s_npc_barter();
 };
 
 class BarterDatabase : public TypesafeYamlDatabase<std::string, s_npc_barter>{