summaryrefslogtreecommitdiff
path: root/src/map/npc.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/npc.cpp')
-rw-r--r--src/map/npc.cpp43
1 files changed, 35 insertions, 8 deletions
diff --git a/src/map/npc.cpp b/src/map/npc.cpp
index ee2f30c..7d3e62b 100644
--- a/src/map/npc.cpp
+++ b/src/map/npc.cpp
@@ -357,7 +357,7 @@ void npc_eventtimer(TimerData *, tick_t, BlockId, NpcEvent data)
data);
return;
});
- if ((nd = ev->nd) == nullptr || nd->deletion_pending == true)
+ if ((nd = ev->nd) == nullptr || nd->deletion_pending != npc_data::NOT_DELETING)
{
if (battle_config.error_log)
PRINTF("npc_event: event not found [%s]\n"_fmt,
@@ -591,7 +591,7 @@ int npc_event(dumb_ptr<map_session_data> sd, NpcEvent eventname,
ev.pos = ev2->pos;
}
- if ((nd = ev.nd) == nullptr || nd->deletion_pending == true)
+ if ((nd = ev.nd) == nullptr || nd->deletion_pending != npc_data::NOT_DELETING)
{
if (!mob_kill && battle_config.error_log)
PRINTF("npc_event: event not found [%s]\n"_fmt,
@@ -767,13 +767,22 @@ int npc_click(dumb_ptr<map_session_data> sd, BlockId id)
}
}
- if (npc_checknear(sd, id)) {
+ if (npc_checknear(sd, id))
+ {
clif_scriptclose(sd, id);
return 1;
}
nd = map_id_is_npc(id);
+ // If someone clicked on an NPC that is about to no longer exist, then
+ // release them
+ if (nd->deletion_pending != npc_data::NOT_DELETING)
+ {
+ clif_scriptclose(sd, id);
+ return 1;
+ }
+
if (nd->flag & 1) // 無効化されている
return 1;
@@ -818,18 +827,19 @@ int npc_scriptcont(dumb_ptr<map_session_data> sd, BlockId id)
nd = map_id_is_npc(id);
- if (!nd /* NPC was disposed? */)
+ // If the NPC is about to be deleted, release the PC
+ if (nd->deletion_pending != npc_data::NOT_DELETING)
{
clif_scriptclose(sd, id);
npc_event_dequeue(sd);
- return 0;
+ return 1;
}
if (nd->is_script()->scr.parent &&
map_id2bl(nd->is_script()->scr.parent) == nullptr)
{
npc_free(nd);
- return 0;
+ return 1;
}
sd->npc_pos = run_script(ScriptPointer(script_or_parent(nd->is_script()), sd->npc_pos), sd->bl_id, id);
@@ -1050,6 +1060,23 @@ void npc_free_internal(dumb_ptr<npc_data> nd_)
nd_->bl_m->npc[nd_->n] = nullptr;
}
+ // Also clean up any events we registered to the global ev_db
+ if (auto nd = nd_->is_script())
+ {
+ std::vector<NpcEvent> to_erase;
+ for (auto& pair : ev_db)
+ {
+ if (pair.second.nd == nd)
+ {
+ to_erase.push_back(pair.first);
+ }
+ }
+ for (auto& key : to_erase)
+ {
+ ev_db.erase(key);
+ }
+ }
+
nd_.delete_();
}
@@ -1074,10 +1101,10 @@ void npc_propagate_update(dumb_ptr<npc_data> nd)
void npc_free(dumb_ptr<npc_data> nd)
{
- if (nd == nullptr || nd->deletion_pending == true)
+ if (nd == nullptr || nd->deletion_pending == npc_data::DELETION_ACTIVE)
return;
- nd->deletion_pending = true;
+ nd->deletion_pending = npc_data::DELETION_ACTIVE;
nd->flag |= 1;
clif_clearchar(nd, BeingRemoveWhy::GONE);
npc_propagate_update(nd);