summaryrefslogtreecommitdiff
path: root/src/map/script.c
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2014-03-14 13:41:30 -0300
committershennetsind <ind@henn.et>2014-03-14 13:41:30 -0300
commitf4b1ff7426b1c4cd5e8cac37f7e3983cc03c706e (patch)
tree68b403b855daca7d11b86b02fcf2d95b8de974b4 /src/map/script.c
parent571d9e25008d8b386e28d7f1fd02f2690edf1f8c (diff)
downloadhercules-f4b1ff7426b1c4cd5e8cac37f7e3983cc03c706e.tar.gz
hercules-f4b1ff7426b1c4cd5e8cac37f7e3983cc03c706e.tar.bz2
hercules-f4b1ff7426b1c4cd5e8cac37f7e3983cc03c706e.tar.xz
hercules-f4b1ff7426b1c4cd5e8cac37f7e3983cc03c706e.zip
Added internal awareness of active script instances
Fixes the following issues: - donpcevent could cause a crash when used to a event of the same npc - input/other-dialog-interactions could cause a crash when sending data to a disabled-fakenpc-id'd. Special Thanks to Haruna, ossi0110. Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src/map/script.c')
-rw-r--r--src/map/script.c25
1 files changed, 21 insertions, 4 deletions
diff --git a/src/map/script.c b/src/map/script.c
index bba771a3c..fca87a81d 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -3208,9 +3208,8 @@ void script_free_vars(struct DBMap* var_storage) {
void script_free_code(struct script_code* code)
{
- script->free_vars(code->local.vars);
- if( code->local.arrays )
- code->local.arrays->destroy(code->local.arrays,script->array_free_db);
+ if( code->instances )
+ script->stop_instances(code);
aFree( code->script_buf );
aFree( code );
}
@@ -3242,6 +3241,13 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
st->oid = oid;
st->sleep.timer = INVALID_TIMER;
st->npc_item_flag = battle_config.item_enabled_npc;
+
+ if( st->script->instances != USHRT_MAX )
+ st->script->instances++;
+ else {
+ struct npc_data *nd = map->id2nd(oid);
+ ShowError("over 65k instances of '%s' script are being run\n",nd ? nd->name : "unknown");
+ }
if( !st->script->local.vars )
st->script->local.vars = i64db_alloc(DB_OPT_RELEASE_DATA);
@@ -3259,9 +3265,20 @@ struct script_state* script_alloc_state(struct script_code* rootscript, int pos,
/// @param st Script state
void script_free_state(struct script_state* st) {
if( idb_exists(script->st_db,st->id) ) {
+ struct map_session_data *sd = st->rid ? map->id2sd(st->rid) : NULL;
+
if(st->bk_st) {// backup was not restored
ShowDebug("script_free_state: Previous script state lost (rid=%d, oid=%d, state=%d, bk_npcid=%d).\n", st->bk_st->rid, st->bk_st->oid, st->bk_st->state, st->bk_npcid);
}
+
+ if(sd && sd->st == st) { //Current script is aborted.
+ if(sd->state.using_fake_npc){
+ clif->clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
+ sd->state.using_fake_npc = 0;
+ }
+ sd->st = NULL;
+ sd->npc_id = 0;
+ }
if( st->sleep.timer != INVALID_TIMER )
timer->delete(st->sleep.timer, script->run_timer);
@@ -3274,7 +3291,7 @@ void script_free_state(struct script_state* st) {
ers_free(script->stack_ers, st->stack);
st->stack = NULL;
}
- if( st->script ) {
+ if( st->script && st->script->instances != USHRT_MAX && --st->script->instances == 0 ) {
if( st->script->local.vars && !db_size(st->script->local.vars) ) {
script->free_vars(st->script->local.vars);
st->script->local.vars = NULL;