summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2016-06-19 01:00:50 +0300
committerAndrei Karas <akaras@inbox.ru>2016-06-19 17:37:00 +0300
commit7910c013eeda513e26711c61a650d23a581b9f28 (patch)
tree743e691c364508786b27cede22cb2a455204ed9c
parent2cfa1a8f0f8bb224654126eb08b67566ee4bc721 (diff)
downloadevol-hercules-7910c013eeda513e26711c61a650d23a581b9f28.tar.gz
evol-hercules-7910c013eeda513e26711c61a650d23a581b9f28.tar.bz2
evol-hercules-7910c013eeda513e26711c61a650d23a581b9f28.tar.xz
evol-hercules-7910c013eeda513e26711c61a650d23a581b9f28.zip
Allow full npc copy in instances.
-rw-r--r--src/emap/data/npcd.c12
-rw-r--r--src/emap/data/npcd.h2
-rw-r--r--src/emap/init.c2
-rw-r--r--src/emap/npc.c137
-rw-r--r--src/emap/npc.h16
-rw-r--r--src/emap/status.c11
6 files changed, 173 insertions, 7 deletions
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);
}
}
}