From 7910c013eeda513e26711c61a650d23a581b9f28 Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Sun, 19 Jun 2016 01:00:50 +0300 Subject: Allow full npc copy in instances. --- src/emap/data/npcd.c | 12 +++++ src/emap/data/npcd.h | 2 + src/emap/init.c | 2 + src/emap/npc.c | 137 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/emap/npc.h | 16 ++++++ src/emap/status.c | 11 ++--- 6 files changed, 173 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/emap/data/npcd.c b/src/emap/data/npcd.c index 9a57a12..91d92e7 100644 --- a/src/emap/data/npcd.c +++ b/src/emap/data/npcd.c @@ -40,3 +40,15 @@ struct NpcdExt *npcd_create(void) data->walkMask = 0; return data; } + +void npcd_copy(TBL_NPC *snd, + TBL_NPC *nd) +{ + const struct NpcdExt *sData = npcd_get(snd); + struct NpcdExt *dData = npcd_get(nd); + if (!snd || !nd) + return; + dData->init = sData->init; + dData->language = sData->language; + dData->walkMask = sData->walkMask; +} diff --git a/src/emap/data/npcd.h b/src/emap/data/npcd.h index 43479f1..8cbba2f 100644 --- a/src/emap/data/npcd.h +++ b/src/emap/data/npcd.h @@ -8,5 +8,7 @@ struct NpcdExt; struct NpcdExt *npcd_get(TBL_NPC *nd); struct NpcdExt *npcd_create(void); +void npcd_copy(TBL_NPC *snd, + TBL_NPC *nd); #endif // EVOL_MAP_NPCD diff --git a/src/emap/init.c b/src/emap/init.c index 3a586dd..88a6be9 100644 --- a/src/emap/init.c +++ b/src/emap/init.c @@ -205,6 +205,8 @@ HPExport void plugin_init (void) addHookPre(npc, parse_unknown_mapflag, enpc_parse_unknown_mapflag_pre); addHookPre(npc, buysellsel, enpc_buysellsel_pre); addHookPre(npc, db_checkid, enpc_db_checkid_pre); + addHookPre(npc, duplicate_script_sub, enpc_duplicate_script_sub_pre); + addHookPre(npc, unload, enpc_unload_pre); addHookPre(clif, quest_send_list, eclif_quest_send_list_pre); addHookPre(clif, quest_add, eclif_quest_add_pre); addHookPre(clif, charnameack, eclif_charnameack_pre); diff --git a/src/emap/npc.c b/src/emap/npc.c index 3a6f395..727ea76 100644 --- a/src/emap/npc.c +++ b/src/emap/npc.c @@ -10,8 +10,10 @@ #include "common/HPMi.h" #include "common/memmgr.h" #include "common/mmo.h" +#include "common/nullpo.h" #include "common/socket.h" #include "common/strlib.h" +#include "common/timer.h" #include "map/map.h" #include "map/npc.h" #include "map/pc.h" @@ -146,3 +148,138 @@ bool enpc_db_checkid_pre(const int *idPtr) // Anything else is invalid return false; } + +bool enpc_duplicate_script_sub_pre(struct npc_data **ndPtr, + const struct npc_data **sndPtr, + int *xsPtr, + int *ysPtr, + int *optionsPtr __attribute__ ((unused))) +{ + struct npc_data *nd = *ndPtr; + const struct npc_data *snd = *sndPtr; + + hookStop(); + nullpo_retr(false, nd); + nullpo_retr(false, snd); + + int xs = *xsPtr; + int ys = *ysPtr; + + int i; + bool retval = true; + + ++npc->npc_script; + nd->u.scr.xs = xs; + nd->u.scr.ys = ys; + nd->u.scr.script = snd->u.scr.script; + nd->u.scr.label_list = snd->u.scr.label_list; + nd->u.scr.label_list_num = snd->u.scr.label_list_num; + nd->u.scr.shop = snd->u.scr.shop; + nd->u.scr.trader = snd->u.scr.trader; + + struct script_code *code; + const int sz = snd->u.scr.script->script_size; + CREATE(code, struct script_code, 1); + code->script_buf = (unsigned char *)aMalloc(sz * sizeof(unsigned char)); + memcpy(code->script_buf, snd->u.scr.script->script_buf, sz); + code->script_size = sz; + code->local.vars = NULL; + code->local.arrays = NULL; + nd->u.scr.script = code; + + enpc_set_var_num(nd, ".parent", snd->bl.id); + + //add the npc to its location + npc->add_to_location(nd); + + // Loop through labels to export them as necessary + for (i = 0; i < nd->u.scr.label_list_num; i++) + { + if (npc->event_export(nd, i)) + { + ShowWarning("npc_parse_duplicate: duplicate event %s::%s in file '%s'.\n", + nd->exname, nd->u.scr.label_list[i].name, nd->path); + retval = false; + } + npc->timerevent_export(nd, i); + } + + nd->u.scr.timerid = INVALID_TIMER; + +// run OnInit always +// if (options&NPO_ONINIT) + { + // From npc_parse_script + char evname[EVENT_NAME_LENGTH]; + struct event_data *ev; + + snprintf(evname, ARRAYLENGTH(evname), "%s::OnInit", nd->exname); + + if ((ev = (struct event_data*)strdb_get(npc->ev_db, evname)) != NULL) + { + //Execute OnInit + script->run_npc(nd->u.scr.script,ev->pos,0,nd->bl.id); + } + } + hookStop(); + return retval; +} + +void enpc_set_var_num(TBL_NPC *const npc, + const char *var, + const int val) +{ + const int num = (int)reference_uid(script->add_str(var), 0); + if (!npc->u.scr.script->local.vars) + npc->u.scr.script->local.vars = i64db_alloc(DB_OPT_RELEASE_DATA); + i64db_iput(npc->u.scr.script->local.vars, num, val); +} + +int enpc_get_var_num(const TBL_NPC *const npc, + const char *var) +{ + const int num = (int)reference_uid(script->add_str(var), 0); + if (npc->u.scr.script->local.vars) + { + return i64db_iget(npc->u.scr.script->local.vars, num); + } + else + { + return 0; + } +} + +int enpc_unload_pre(struct npc_data** ndPtr, + bool *singlePtr __attribute__ ((unused))) +{ + struct npc_data *nd = *ndPtr; + nullpo_ret(nd); + if (nd->subtype == SCRIPT) + { + if (nd->src_id != 0) + { + ShowWarning("npc_unload 5: %d\n", nd->bl.id); + if (nd->u.scr.script) + { + script->free_code(nd->u.scr.script); + nd->u.scr.script = NULL; + } +/* +// this need to clean if we copy this structs too. + if (nd->u.scr.label_list) + { + aFree(nd->u.scr.label_list); + nd->u.scr.label_list = NULL; + nd->u.scr.label_list_num = 0; + } + if (nd->u.scr.shop) + { + if(nd->u.scr.shop->item) + aFree(nd->u.scr.shop->item); + aFree(nd->u.scr.shop); + } +*/ + } + } + return 0; +} diff --git a/src/emap/npc.h b/src/emap/npc.h index 1d6c254..ea6c77f 100644 --- a/src/emap/npc.h +++ b/src/emap/npc.h @@ -18,4 +18,20 @@ int enpc_buysellsel_pre(TBL_PC **sdPtr, bool enpc_db_checkid_pre(const int *idPtr); +bool enpc_duplicate_script_sub_pre(struct npc_data **ndPtr, + const struct npc_data **sndPtr, + int *xsPtr, + int *ysPtr, + int *optionsPtr); + +void enpc_set_var_num(TBL_NPC *const npc, + const char *var, + const int val); + +int enpc_get_var_num(const TBL_NPC *const npc, + const char *var); + +int enpc_unload_pre(struct npc_data** ndPtr, + bool *singlePtr); + #endif // EVOL_MAP_NPC diff --git a/src/emap/status.c b/src/emap/status.c index 90c25d4..1b27a0f 100644 --- a/src/emap/status.c +++ b/src/emap/status.c @@ -10,6 +10,7 @@ #include "common/HPMi.h" #include "common/memmgr.h" #include "common/mmo.h" +#include "common/nullpo.h" #include "common/socket.h" #include "common/strlib.h" #include "map/itemdb.h" @@ -21,6 +22,8 @@ #include "plugins/HPMHooking.h" +#include "emap/npc.h" + #include "emap/horse.h" #include "emap/data/itemd.h" #include "emap/data/npcd.h" @@ -52,13 +55,7 @@ void estatus_set_viewdata_post(struct block_list *bl, if (npc->subtype == SCRIPT) { if (npc->u.scr.script) - { - // here some magic to set npc local variable .id to bl.id - const int num = (int)reference_uid(script->add_str(".id"), 0); - if (!npc->u.scr.script->local.vars) - npc->u.scr.script->local.vars = i64db_alloc(DB_OPT_RELEASE_DATA); - i64db_iput(npc->u.scr.script->local.vars, num, npc->bl.id); - } + enpc_set_var_num(npc, ".id", npc->bl.id); } } } -- cgit v1.2.3-70-g09d2