Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- diff --git a/src/custom/script.inc b/src/custom/script.inc
- index 839b990cb..624cecb8a 100644
- --- a/src/custom/script.inc
- +++ b/src/custom/script.inc
- @@ -17,3 +17,227 @@
- // script_pushint(st,1);
- // return 0;
- //}
- +
- +/*==========================================
- + * Duplicate any npc on live server
- + * duplicatenpc "<Source NPC name>","<New NPC shown name>","<New NPC hidden name>","<mapname>",<map_x>,<map_y>,<dir>{, spriteid{, map_xs, map_ys}}};
- + *------------------------------------------*/
- +BUILDIN_FUNC(duplicatenpc)
- +{
- + int map_x = script_getnum(st, 6);
- + int map_y = script_getnum(st, 7);
- + int dir = script_getnum(st, 8);
- + int spriteid, map_xs = -1, map_ys = -1, sourceid, type, mapid, i;
- + const char *sourcename = script_getstr(st, 2);
- + const char *new_shown_name = script_getstr(st, 3);
- + const char *new_hidden_name = script_getstr(st, 4);
- + const char *mapname = script_getstr(st, 5);
- +
- + char new_npc_name[24] = "";
- + struct npc_data *nd_source, *nd_target;
- +
- + if(script_hasdata(st, 10))
- + map_xs = (script_getnum(st, 10) < -1) ? -1 : script_getnum(st, 10);
- +
- + if(script_hasdata(st, 11))
- + map_ys = (script_getnum(st, 11) < -1) ? -1 : script_getnum(st, 10);
- +
- + if(map_xs == -1 && map_ys != -1)
- + map_xs = 0;
- +
- + if(map_xs != - 1 && map_ys == -1)
- + map_ys = 0;
- +
- + if(strlen(new_shown_name) + strlen(new_hidden_name) > NAME_LENGTH) {
- + ShowError("buildin_duplicatenpc: New NPC shown name + New NPC hidden name is too long (max %d chars). (%s)\n", sourcename, NAME_LENGTH);
- + script_pushint(st, 0);
- + return SCRIPT_CMD_FAILURE;
- + }
- +
- + nd_source = npc_name2id(sourcename);
- +
- + if(script_hasdata(st, 9))
- + spriteid = (script_getnum(st, 9) < -1) ? -1 : script_getnum(st, 9);
- + else
- + spriteid = nd_source->class_;
- +
- + if(nd_source == NULL) {
- + ShowError("buildin_duplicatenpc: original npc not found for duplicate. (%s)\n", sourcename);
- + script_pushint(st, 0);
- + return SCRIPT_CMD_FAILURE;
- + }
- +
- + sourceid = nd_source->bl.id;
- + type = nd_source->subtype;
- + mapid = map_mapname2mapid(mapname);
- +
- + if(mapid < 0) {
- + ShowError("buildin_duplicatenpc: target map not found. (%s)\n", mapname);
- + script_pushint(st, 0);
- + return SCRIPT_CMD_FAILURE;
- + }
- +
- + CREATE(nd_target, struct npc_data, 1);
- +
- + strcat(new_npc_name, new_shown_name);
- + strncat(new_npc_name, "#", 1);
- + strncat(new_npc_name, new_hidden_name, strlen(new_hidden_name));
- +
- + safestrncpy(nd_target->name, new_npc_name , sizeof(nd_target->name));
- + safestrncpy(nd_target->exname, new_npc_name, sizeof(nd_target->exname));
- +
- + nd_target->bl.prev = nd_target->bl.next = NULL;
- + nd_target->bl.m = mapid;
- + nd_target->bl.x = map_x;
- + nd_target->bl.y = map_y;
- + nd_target->bl.id = npc_get_new_npc_id();
- + nd_target->class_ = spriteid;
- + nd_target->speed = 200;
- + nd_target->src_id = sourceid;
- + nd_target->bl.type = BL_NPC;
- + nd_target->subtype = (enum npc_subtype)type;
- +
- + switch(type) {
- + case NPCTYPE_SCRIPT:
- + nd_target->u.scr.xs = map_xs;
- + nd_target->u.scr.ys = map_ys;
- + nd_target->u.scr.script = nd_source->u.scr.script;
- + nd_target->u.scr.label_list = nd_source->u.scr.label_list;
- + nd_target->u.scr.label_list_num = nd_source->u.scr.label_list_num;
- + break;
- + case NPCTYPE_SHOP:
- + case NPCTYPE_CASHSHOP:
- + case NPCTYPE_ITEMSHOP:
- + case NPCTYPE_POINTSHOP:
- + case NPCTYPE_MARKETSHOP:
- + nd_target->u.shop.shop_item = nd_source->u.shop.shop_item;
- + nd_target->u.shop.count = nd_source->u.shop.count;
- + break;
- + case NPCTYPE_WARP:
- + if( !battle_config.warp_point_debug )
- + nd_target->class_ = JT_WARPNPC;
- + else
- + nd_target->class_ = JT_GUILD_FLAG;
- + nd_target->u.warp.xs = map_xs;
- + nd_target->u.warp.ys = map_ys;
- + nd_target->u.warp.mapindex = nd_source->u.warp.mapindex;
- + nd_target->u.warp.x = nd_source->u.warp.x;
- + nd_target->u.warp.y = nd_source->u.warp.y;
- + nd_target->trigger_on_hidden = nd_source->trigger_on_hidden;
- + break;
- + }
- +
- + map_addnpc(mapid, nd_target);
- + status_change_init(&nd_target->bl);
- + unit_dataset(&nd_target->bl);
- + nd_target->ud.dir = dir;
- + npc_setcells(nd_target);
- + map_addblock(&nd_target->bl);
- +
- + if(spriteid >= 0) {
- + status_set_viewdata(&nd_target->bl, nd_target->class_);
- + clif_spawn(&nd_target->bl);
- + }
- +
- + strdb_put(npcname_db, nd_target->exname, nd_target);
- +
- + if(type == NPCTYPE_SCRIPT) {
- + for (i = 0; i < nd_target->u.scr.label_list_num; i++) {
- + char* lname = nd_target->u.scr.label_list[i].name;
- + int pos = nd_target->u.scr.label_list[i].pos;
- +
- + if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n')) {
- + struct event_data* ev;
- + char buf[NAME_LENGTH*2+3];
- + snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd_target->exname, lname);
- +
- + CREATE(ev, struct event_data, 1);
- + ev->nd = nd_target;
- + ev->pos = pos;
- + if(strdb_put(ev_db, buf, ev))
- + ShowWarning("npc_parse_duplicate : duplicate event %s (%s)\n", buf, nd_target->name);
- + }
- + }
- +
- + for (i = 0; i < nd_target->u.scr.label_list_num; i++) {
- + int t = 0, k = 0;
- + char *lname = nd_target->u.scr.label_list[i].name;
- + int pos = nd_target->u.scr.label_list[i].pos;
- + if (sscanf(lname, "OnTimer%d%n", &t, &k) == 1 && lname[k] == '\0') {
- + struct npc_timerevent_list *te = nd_target->u.scr.timer_event;
- + int j, k = nd_target->u.scr.timeramount;
- + if (te == NULL)
- + te = (struct npc_timerevent_list *)aMalloc(sizeof(struct npc_timerevent_list));
- + else
- + te = (struct npc_timerevent_list *)aRealloc( te, sizeof(struct npc_timerevent_list) * (k+1) );
- + for (j = 0; j < k; j++) {
- + if (te[j].timer > t) {
- + memmove(te+j+1, te+j, sizeof(struct npc_timerevent_list)*(k-j));
- + break;
- + }
- + }
- + te[j].timer = t;
- + te[j].pos = pos;
- + nd_target->u.scr.timer_event = te;
- + nd_target->u.scr.timeramount++;
- + }
- + }
- + nd_target->u.scr.timerid = INVALID_TIMER;
- + }
- +
- + script_pushint(st, 1);
- + return SCRIPT_CMD_SUCCESS;
- +}
- +
- +/*==========================================
- + * Remove any npc duplicate on live server
- + * duplicateremove "<NPC name>";
- + *------------------------------------------*/
- +BUILDIN_FUNC(duplicateremove)
- +{
- + struct npc_data *nd;
- +
- + if(script_hasdata(st, 2)) {
- + nd = npc_name2id(script_getstr(st, 2));
- + if(nd == NULL) {
- + script_pushint(st, -1);
- + return SCRIPT_CMD_FAILURE;
- + }
- + } else
- + nd = (struct npc_data *)map_id2bl(st->oid);
- +
- + if(!nd->src_id)
- + npc_unload_duplicates(nd);
- + else
- + npc_unload(nd,true);
- +
- + script_pushint(st, 1);
- + return SCRIPT_CMD_SUCCESS;
- +}
- +
- diff --git a/src/custom/script_def.inc b/src/custom/script_def.inc
- index 886399273..ed7956a7f 100644
- --- a/src/custom/script_def.inc
- +++ b/src/custom/script_def.inc
- @@ -9,3 +9,6 @@
- **/
- //BUILDIN_DEF(example,""),
- +BUILDIN_DEF(duplicatenpc, "ssssiii???"),
- +BUILDIN_DEF(duplicateremove, "?"),
- diff --git a/src/map/npc.cpp b/src/map/npc.cpp
- index 558c019fe..ce9e5f039 100644
- --- a/src/map/npc.cpp
- +++ b/src/map/npc.cpp
- @@ -85,13 +85,8 @@ int npc_get_new_npc_id(void) {
- }
- }
- -static DBMap* ev_db; // const char* event_name -> struct event_data*
- -static DBMap* npcname_db; // const char* npc_name -> struct npc_data*
- -
- -struct event_data {
- - struct npc_data *nd;
- - int pos;
- -};
- +DBMap* ev_db; // const char* event_name -> struct event_data*
- +DBMap* npcname_db; // const char* npc_name -> struct npc_data*
- static struct eri *timer_event_ers; //For the npc timer data. [Skotlex]
- @@ -2136,7 +2131,7 @@ static int npc_unload_ev(DBKey key, DBData *data, va_list ap)
- //Chk if npc matches src_id, then unload.
- //Sub-function used to find duplicates.
- -static int npc_unload_dup_sub(struct npc_data* nd, va_list args)
- +int npc_unload_dup_sub(struct npc_data* nd, va_list args)
- {
- int src_id;
- diff --git a/src/map/npc.hpp b/src/map/npc.hpp
- index af71f3507..c2a1817de 100644
- --- a/src/map/npc.hpp
- +++ b/src/map/npc.hpp
- @@ -107,6 +107,14 @@ struct npc_data {
- struct eri;
- extern struct eri *npc_sc_display_ers;
- +extern DBMap* ev_db; // const char* event_name -> struct event_data*
- +extern DBMap* npcname_db; // const char* npc_name -> struct npc_data*
- +
- +struct event_data {
- + struct npc_data *nd;
- + int pos;
- +};
- +
- #define START_NPC_NUM 110000000
- enum e_job_types
- @@ -1206,6 +1214,8 @@ int npc_instanceinit(struct npc_data* nd);
- int npc_instancedestroy(struct npc_data* nd);
- int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amount, int points);
- +int npc_unload_dup_sub(struct npc_data *nd, va_list args);
- +
- void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, int cost[2], bool display);
- extern struct npc_data* fake_nd;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement