Advertisement
Emistry

[RO] rA - NPC Duplicate / Remove - Script Commands

Nov 1st, 2018
2,378
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 8.64 KB | None | 0 0
  1. diff --git a/src/custom/script.inc b/src/custom/script.inc
  2. index 839b990cb..624cecb8a 100644
  3. --- a/src/custom/script.inc
  4. +++ b/src/custom/script.inc
  5. @@ -17,3 +17,227 @@
  6.  // script_pushint(st,1);
  7.  // return 0;
  8.  //}
  9. +
  10. +/*==========================================
  11. + * Duplicate any npc on live server
  12. + * duplicatenpc "<Source NPC name>","<New NPC shown name>","<New NPC hidden name>","<mapname>",<map_x>,<map_y>,<dir>{, spriteid{, map_xs, map_ys}}};
  13. + *------------------------------------------*/
  14. +BUILDIN_FUNC(duplicatenpc)
  15. +{
  16. +   int map_x = script_getnum(st, 6);
  17. +   int map_y = script_getnum(st, 7);
  18. +   int dir = script_getnum(st, 8);
  19. +   int spriteid, map_xs = -1, map_ys = -1, sourceid, type, mapid, i;
  20. +   const char *sourcename = script_getstr(st, 2);
  21. +   const char *new_shown_name = script_getstr(st, 3);
  22. +   const char *new_hidden_name = script_getstr(st, 4);
  23. +   const char *mapname = script_getstr(st, 5);
  24. +
  25. +   char new_npc_name[24] = "";
  26. +   struct npc_data *nd_source, *nd_target;
  27. +
  28. +   if(script_hasdata(st, 10))
  29. +       map_xs = (script_getnum(st, 10) < -1) ? -1 : script_getnum(st, 10);
  30. +
  31. +   if(script_hasdata(st, 11))
  32. +       map_ys = (script_getnum(st, 11) < -1) ? -1 : script_getnum(st, 10);
  33. +
  34. +   if(map_xs == -1 && map_ys != -1)
  35. +       map_xs = 0;
  36. +
  37. +   if(map_xs != - 1 && map_ys == -1)
  38. +       map_ys = 0;
  39. +
  40. +   if(strlen(new_shown_name) + strlen(new_hidden_name) > NAME_LENGTH) {
  41. +       ShowError("buildin_duplicatenpc: New NPC shown name + New NPC hidden name is too long (max %d chars). (%s)\n", sourcename, NAME_LENGTH);
  42. +       script_pushint(st, 0);
  43. +       return SCRIPT_CMD_FAILURE;
  44. +   }
  45. +
  46. +   nd_source = npc_name2id(sourcename);
  47. +
  48. +   if(script_hasdata(st, 9))
  49. +       spriteid = (script_getnum(st, 9) < -1) ? -1 : script_getnum(st, 9);
  50. +   else
  51. +       spriteid = nd_source->class_;
  52. +
  53. +   if(nd_source == NULL) {
  54. +       ShowError("buildin_duplicatenpc: original npc not found for duplicate. (%s)\n", sourcename);
  55. +       script_pushint(st, 0);
  56. +       return SCRIPT_CMD_FAILURE;
  57. +   }
  58. +  
  59. +   sourceid = nd_source->bl.id;
  60. +   type = nd_source->subtype;
  61. +   mapid = map_mapname2mapid(mapname);
  62. +
  63. +   if(mapid < 0) {
  64. +       ShowError("buildin_duplicatenpc: target map not found. (%s)\n", mapname);
  65. +       script_pushint(st, 0);
  66. +       return SCRIPT_CMD_FAILURE;
  67. +   }
  68. +
  69. +   CREATE(nd_target, struct npc_data, 1);
  70. +  
  71. +   strcat(new_npc_name, new_shown_name);
  72. +   strncat(new_npc_name, "#", 1);
  73. +   strncat(new_npc_name, new_hidden_name, strlen(new_hidden_name));
  74. +
  75. +   safestrncpy(nd_target->name, new_npc_name , sizeof(nd_target->name));
  76. +   safestrncpy(nd_target->exname, new_npc_name, sizeof(nd_target->exname));
  77. +
  78. +   nd_target->bl.prev = nd_target->bl.next = NULL;
  79. +   nd_target->bl.m = mapid;
  80. +   nd_target->bl.x = map_x;
  81. +   nd_target->bl.y = map_y;
  82. +   nd_target->bl.id = npc_get_new_npc_id();
  83. +   nd_target->class_ = spriteid;
  84. +   nd_target->speed = 200;
  85. +   nd_target->src_id = sourceid;
  86. +   nd_target->bl.type = BL_NPC;
  87. +   nd_target->subtype = (enum npc_subtype)type;
  88. +
  89. +   switch(type) {
  90. +       case NPCTYPE_SCRIPT:
  91. +           nd_target->u.scr.xs = map_xs;
  92. +           nd_target->u.scr.ys = map_ys;
  93. +           nd_target->u.scr.script = nd_source->u.scr.script;
  94. +           nd_target->u.scr.label_list = nd_source->u.scr.label_list;
  95. +           nd_target->u.scr.label_list_num = nd_source->u.scr.label_list_num;
  96. +           break;
  97. +       case NPCTYPE_SHOP:
  98. +       case NPCTYPE_CASHSHOP:
  99. +       case NPCTYPE_ITEMSHOP:
  100. +       case NPCTYPE_POINTSHOP:
  101. +       case NPCTYPE_MARKETSHOP:
  102. +           nd_target->u.shop.shop_item = nd_source->u.shop.shop_item;
  103. +           nd_target->u.shop.count = nd_source->u.shop.count;
  104. +           break;
  105. +       case NPCTYPE_WARP:
  106. +           if( !battle_config.warp_point_debug )
  107. +               nd_target->class_ = JT_WARPNPC;
  108. +           else
  109. +               nd_target->class_ = JT_GUILD_FLAG;
  110. +           nd_target->u.warp.xs = map_xs;
  111. +           nd_target->u.warp.ys = map_ys;
  112. +           nd_target->u.warp.mapindex = nd_source->u.warp.mapindex;
  113. +           nd_target->u.warp.x = nd_source->u.warp.x;
  114. +           nd_target->u.warp.y = nd_source->u.warp.y;
  115. +           nd_target->trigger_on_hidden = nd_source->trigger_on_hidden;
  116. +           break;
  117. +   }
  118. +
  119. +   map_addnpc(mapid, nd_target);
  120. +   status_change_init(&nd_target->bl);
  121. +   unit_dataset(&nd_target->bl);
  122. +   nd_target->ud.dir = dir;
  123. +   npc_setcells(nd_target);
  124. +   map_addblock(&nd_target->bl);
  125. +
  126. +   if(spriteid >= 0) {
  127. +       status_set_viewdata(&nd_target->bl, nd_target->class_);
  128. +       clif_spawn(&nd_target->bl);
  129. +   }
  130. +
  131. +   strdb_put(npcname_db, nd_target->exname, nd_target);
  132. +
  133. +   if(type == NPCTYPE_SCRIPT) {
  134. +       for (i = 0; i < nd_target->u.scr.label_list_num; i++) {
  135. +           char* lname = nd_target->u.scr.label_list[i].name;
  136. +           int pos = nd_target->u.scr.label_list[i].pos;
  137. +
  138. +           if ((lname[0] == 'O' || lname[0] == 'o') && (lname[1] == 'N' || lname[1] == 'n')) {
  139. +               struct event_data* ev;
  140. +               char buf[NAME_LENGTH*2+3];
  141. +               snprintf(buf, ARRAYLENGTH(buf), "%s::%s", nd_target->exname, lname);
  142. +
  143. +               CREATE(ev, struct event_data, 1);
  144. +               ev->nd = nd_target;
  145. +               ev->pos = pos;
  146. +               if(strdb_put(ev_db, buf, ev))
  147. +                   ShowWarning("npc_parse_duplicate : duplicate event %s (%s)\n", buf, nd_target->name);
  148. +           }
  149. +       }
  150. +
  151. +       for (i = 0; i < nd_target->u.scr.label_list_num; i++) {
  152. +           int t = 0, k = 0;
  153. +           char *lname = nd_target->u.scr.label_list[i].name;
  154. +           int pos = nd_target->u.scr.label_list[i].pos;
  155. +           if (sscanf(lname, "OnTimer%d%n", &t, &k) == 1 && lname[k] == '\0') {
  156. +               struct npc_timerevent_list *te = nd_target->u.scr.timer_event;
  157. +               int j, k = nd_target->u.scr.timeramount;
  158. +               if (te == NULL)
  159. +                   te = (struct npc_timerevent_list *)aMalloc(sizeof(struct npc_timerevent_list));
  160. +               else
  161. +                   te = (struct npc_timerevent_list *)aRealloc( te, sizeof(struct npc_timerevent_list) * (k+1) );
  162. +               for (j = 0; j < k; j++) {
  163. +                   if (te[j].timer > t) {
  164. +                       memmove(te+j+1, te+j, sizeof(struct npc_timerevent_list)*(k-j));
  165. +                       break;
  166. +                   }
  167. +               }
  168. +               te[j].timer = t;
  169. +               te[j].pos = pos;
  170. +               nd_target->u.scr.timer_event = te;
  171. +               nd_target->u.scr.timeramount++;
  172. +           }
  173. +       }
  174. +       nd_target->u.scr.timerid = INVALID_TIMER;
  175. +   }
  176. +
  177. +   script_pushint(st, 1);
  178. +   return SCRIPT_CMD_SUCCESS;
  179. +}
  180. +
  181. +/*==========================================
  182. + * Remove any npc duplicate on live server
  183. + * duplicateremove "<NPC name>";
  184. + *------------------------------------------*/
  185. +BUILDIN_FUNC(duplicateremove)
  186. +{
  187. +   struct npc_data *nd;
  188. +
  189. +   if(script_hasdata(st, 2)) {
  190. +       nd = npc_name2id(script_getstr(st, 2));
  191. +       if(nd == NULL) {
  192. +           script_pushint(st, -1);
  193. +           return SCRIPT_CMD_FAILURE;
  194. +       }
  195. +   } else
  196. +       nd = (struct npc_data *)map_id2bl(st->oid);
  197. +
  198. +   if(!nd->src_id)
  199. +       npc_unload_duplicates(nd);
  200. +   else
  201. +       npc_unload(nd,true);
  202. +
  203. +   script_pushint(st, 1);
  204. +   return SCRIPT_CMD_SUCCESS;
  205. +}
  206. +
  207. diff --git a/src/custom/script_def.inc b/src/custom/script_def.inc
  208. index 886399273..ed7956a7f 100644
  209. --- a/src/custom/script_def.inc
  210. +++ b/src/custom/script_def.inc
  211. @@ -9,3 +9,6 @@
  212.   **/
  213.  
  214.  //BUILDIN_DEF(example,""),
  215. +BUILDIN_DEF(duplicatenpc, "ssssiii???"),
  216. +BUILDIN_DEF(duplicateremove, "?"),
  217. diff --git a/src/map/npc.cpp b/src/map/npc.cpp
  218. index 558c019fe..ce9e5f039 100644
  219. --- a/src/map/npc.cpp
  220. +++ b/src/map/npc.cpp
  221. @@ -85,13 +85,8 @@ int npc_get_new_npc_id(void) {
  222.     }
  223.  }
  224.  
  225. -static DBMap* ev_db; // const char* event_name -> struct event_data*
  226. -static DBMap* npcname_db; // const char* npc_name -> struct npc_data*
  227. -
  228. -struct event_data {
  229. -   struct npc_data *nd;
  230. -   int pos;
  231. -};
  232. +DBMap* ev_db; // const char* event_name -> struct event_data*
  233. +DBMap* npcname_db; // const char* npc_name -> struct npc_data*
  234.  
  235.  static struct eri *timer_event_ers; //For the npc timer data. [Skotlex]
  236.  
  237. @@ -2136,7 +2131,7 @@ static int npc_unload_ev(DBKey key, DBData *data, va_list ap)
  238.  
  239.  //Chk if npc matches src_id, then unload.
  240.  //Sub-function used to find duplicates.
  241. -static int npc_unload_dup_sub(struct npc_data* nd, va_list args)
  242. +int npc_unload_dup_sub(struct npc_data* nd, va_list args)
  243.  {
  244.     int src_id;
  245.  
  246. diff --git a/src/map/npc.hpp b/src/map/npc.hpp
  247. index af71f3507..c2a1817de 100644
  248. --- a/src/map/npc.hpp
  249. +++ b/src/map/npc.hpp
  250. @@ -107,6 +107,14 @@ struct npc_data {
  251.  struct eri;
  252.  extern struct eri *npc_sc_display_ers;
  253.  
  254. +extern DBMap* ev_db; // const char* event_name -> struct event_data*
  255. +extern DBMap* npcname_db; // const char* npc_name -> struct npc_data*
  256. +
  257. +struct event_data {
  258. +   struct npc_data *nd;
  259. +   int pos;
  260. +};
  261. +
  262.  #define START_NPC_NUM 110000000
  263.  
  264.  enum e_job_types
  265. @@ -1206,6 +1214,8 @@ int npc_instanceinit(struct npc_data* nd);
  266.  int npc_instancedestroy(struct npc_data* nd);
  267.  int npc_cashshop_buy(struct map_session_data *sd, unsigned short nameid, int amount, int points);
  268.  
  269. +int npc_unload_dup_sub(struct npc_data *nd, va_list args);
  270. +
  271.  void npc_shop_currency_type(struct map_session_data *sd, struct npc_data *nd, int cost[2], bool display);
  272.  
  273.  extern struct npc_data* fake_nd;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement