From 6e559e0a621030b51c3590b5e163b4d9554b410a Mon Sep 17 00:00:00 2001 From: Freeyorp Date: Fri, 23 Mar 2018 21:09:32 +1300 Subject: Fix NPC script softlock When an NPC called destroy; from an attached script, npc_id, and associated state, was not properly cleared. This meant that the server considered the PC to still be in conversation, preventing many actions including walking, but with an invalid NPC. This clears state for the specific case of the a PC attached to the script instance that called destroy. It is still not safe to call destroy; if other players may be attached to it. --- src/map/script-fun.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/map/script-fun.cpp b/src/map/script-fun.cpp index e1866bc..8292bdb 100644 --- a/src/map/script-fun.cpp +++ b/src/map/script-fun.cpp @@ -1121,6 +1121,7 @@ void builtin_foreach(ScriptState *st) x1, y1, block_type); } + /*======================================== * Destructs a temp NPC *---------------------------------------- @@ -1129,6 +1130,8 @@ static void builtin_destroy(ScriptState *st) { BlockId id; + dumb_ptr sd; + if (HARG(0)) id = wrap(conv_num(st, &AARG(0))); else @@ -1138,6 +1141,14 @@ void builtin_destroy(ScriptState *st) if(!nd || nd->npc_subtype != NpcSubtype::SCRIPT) return; + /* If we have a player attached, make sure it is cleared. */ + /* Not safe to call destroy if others may also be paused on this NPC! */ + if (st->rid) { + sd = script_rid2sd(st); + nullpo_retv(sd); + npc_event_dequeue(sd); + } + nd = nd->is_script(); npc_free(nd); st->oid = BlockId(); -- cgit v1.2.3-60-g2f50