|
@@ -3528,7 +3528,7 @@ int npc_unload(struct npc_data* nd, bool single) {
|
|
|
map_session_data* owner = map_charid2sd( nd->dynamicnpc.owner_char_id );
|
|
|
|
|
|
if( owner != nullptr ){
|
|
|
- owner->npc_id_dynamic = 0;
|
|
|
+ util::vector_erase_if_exists(owner->npc_id_dynamic, nd->bl.id);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -4515,7 +4515,7 @@ const char* npc_parse_duplicate( char* w1, char* w2, char* w3, char* w4, const c
|
|
|
|
|
|
if( owner != nullptr ){
|
|
|
nd->dynamicnpc.owner_char_id = owner->status.char_id;
|
|
|
- owner->npc_id_dynamic = nd->bl.id;
|
|
|
+ owner->npc_id_dynamic.push_back(nd->bl.id);
|
|
|
}
|
|
|
|
|
|
switch( type ) {
|
|
@@ -5796,7 +5796,7 @@ TIMER_FUNC(npc_dynamicnpc_removal_timer){
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- sd->npc_id_dynamic = 0;
|
|
|
+ // npc id from sd->npc_id_dynamic is removed in npc_unload
|
|
|
}
|
|
|
|
|
|
// Delete the NPC
|
|
@@ -5808,9 +5808,17 @@ TIMER_FUNC(npc_dynamicnpc_removal_timer){
|
|
|
}
|
|
|
|
|
|
struct npc_data* npc_duplicate_npc_for_player( struct npc_data& nd, map_session_data& sd ){
|
|
|
- if( sd.npc_id_dynamic != 0 ){
|
|
|
- clif_msg_color( &sd, C_DYNAMICNPC_TWICE, color_table[COLOR_LIGHT_YELLOW] );
|
|
|
- return nullptr;
|
|
|
+ // A duplicate of a duplicate is still a duplicate of the same NPC
|
|
|
+ int src_id = nd.src_id > 0 ? nd.src_id : nd.bl.id;
|
|
|
+
|
|
|
+ for (const auto &it : sd.npc_id_dynamic) {
|
|
|
+ struct npc_data* src_nd = map_id2nd( it );
|
|
|
+
|
|
|
+ // Check if the source NPC id of currently active duplicates already exists.
|
|
|
+ if( src_nd != nullptr && src_nd->src_id == src_id ){
|
|
|
+ clif_msg_color( &sd, C_DYNAMICNPC_TWICE, color_table[COLOR_LIGHT_YELLOW] );
|
|
|
+ return nullptr;
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
if( map_getmapflag( sd.bl.m, MF_NODYNAMICNPC ) ){
|