Advertisement
Guest User

Untitled

a guest
Aug 2nd, 2015
341
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 11.20 KB | None | 0 0
  1. Index: doc/script_commands.txt
  2. ===================================================================
  3. --- doc/script_commands.txt (revision 15269)
  4. +++ doc/script_commands.txt (working copy)
  5. @@ -4,7 +4,7 @@
  6.  //= A reference manual for the eAthena scripting language.
  7.  //= Commands are sorted depending on their functionality.
  8.  //===== Version ===========================================
  9. -//= 3.50.20120416
  10. +//= 3.51.20150324
  11.  //=========================================================
  12.  //= 1.0 - First release, filled will as much info as I could
  13.  //=       remember or figure out, most likely there are errors,
  14. @@ -191,6 +191,8 @@
  15.  //=       Added 'getnpcid' command. [Ai4rei]
  16.  //= 3.50.20120416
  17.  //=       Allow any type of argument in 'escape_sql' command. [FlavioJS]
  18. +//= 3.51.20150324
  19. +//=       Added 'bindatcmd', 'unbindatcmd', 'useatcmd' [15peaces]
  20.  //=========================================================
  21.  
  22.  This document is a reference manual for all the scripting commands and functions
  23. @@ -2148,6 +2150,28 @@
  24.  
  25.      deletearray @array[1],3
  26.  
  27. +---------------------------------------
  28. +
  29. +*bindatcmd "command","{NPC NAME}::<event label>"{,atcommand level,charcommand level};
  30. +*bindatcmd ("command","{NPC NAME}::<event label>"{,atcommand level,charcommand level});
  31. +
  32. +This command will bind a NPC event label to an atcommand. Upon execution of
  33. +the atcommand the user will invoke the NPC event label.
  34. +
  35. +---------------------------------------
  36. +
  37. +*unbindatcmd "command";
  38. +*unbindatcmd ("command");
  39. +
  40. +This command will unbind a NPC event label from an atcommand.
  41. +
  42. +---------------------------------------
  43. +
  44. +*useatcmd "command";
  45. +*useatcmd ("command");
  46. +
  47. +This command will execute a custom atcommand on the attached RID from a script.
  48. +  
  49.  ---------------------------------------
  50.  
  51.  ======================================
  52. Index: src/map/atcommand.c
  53. ===================================================================
  54. --- src/map/atcommand.c (revision 15269)
  55. +++ src/map/atcommand.c (working copy)
  56. @@ -65,6 +65,17 @@
  57.  static AtCommandInfo* get_atcommandinfo_byname(const char* name);
  58.  static AtCommandInfo* get_atcommandinfo_byfunc(const AtCommandFunc func);
  59.  
  60. +// @commands (script-based)
  61. +struct Atcmd_Binding* get_atcommandbind_byname(const char* name)
  62. +{
  63. +   int i = 0;
  64. +   if( *name == atcommand_symbol || *name == charcommand_symbol )
  65. +       name++; // for backwards compatibility
  66. +   ARR_FIND( 0, ARRAYLENGTH(atcmd_binding), i, strcmp(atcmd_binding[i].command, name) == 0 );
  67. +   return ( i < ARRAYLENGTH(atcmd_binding) ) ? &atcmd_binding[i] : NULL;
  68. +   return NULL;
  69. +}
  70. +
  71.  ACMD_FUNC(commands);
  72.  
  73.  
  74. @@ -9199,6 +9210,9 @@
  75.     TBL_PC * ssd = NULL; //sd for target
  76.     AtCommandInfo * info;
  77.  
  78. +   // @commands (script based)
  79. +   Atcmd_Binding * binding;
  80. +
  81.     nullpo_retr(false, sd);
  82.    
  83.     //Shouldn't happen
  84. @@ -9286,7 +9300,33 @@
  85.     //check to see if any params exist within this command
  86.     if( sscanf(atcmd_msg, "%99s %99[^\n]", command, params) < 2 )
  87.         params[0] = '\0';
  88. -  
  89. +
  90. +   // @commands (script based)
  91. +   if(type == 1) {
  92. +       // Check if the command initiated is a character command
  93. +       if (*message == charcommand_symbol &&
  94. +       (ssd = map_nick2sd(charname)) == NULL && (ssd = map_nick2sd(charname2)) == NULL )
  95. +       {
  96. +           sprintf(output, "%s failed. Player not found.", command);
  97. +           clif_displaymessage(fd, output);
  98. +           return true;
  99. +       }
  100. +
  101. +       // Get atcommand binding
  102. +       binding = get_atcommandbind_byname(command);
  103. +
  104. +       // Check if the binding isn't NULL and there is a NPC event, level of usage met, et cetera
  105. +       if( binding != NULL && binding->npc_event[0] &&
  106. +       ((*atcmd_msg == atcommand_symbol && pc_isGM(sd) >= binding->level) ||
  107. +       (*atcmd_msg == charcommand_symbol && pc_isGM(sd) >= binding->level2)))
  108. +       {
  109. +           // Check if self or character invoking; if self == character invoked, then self invoke.
  110. +           bool invokeFlag = ((*atcmd_msg == atcommand_symbol) ? 1 : 0);
  111. +           npc_do_atcmd_event((invokeFlag ? sd : ssd), command, params, binding->npc_event);
  112. +           return true;
  113. +       }
  114. +   }
  115. +
  116.     //Grab the command information and check for the proper GM level required to use it or if the command exists
  117.     info = get_atcommandinfo_byname(command);
  118.     if( info == NULL || info->func == NULL || ( type && ((*atcmd_msg == atcommand_symbol && pc_isGM(sd) < info->level) || (*atcmd_msg == charcommand_symbol && pc_isGM(sd) < info->level2)) ) )
  119. Index: src/map/atcommand.h
  120. ===================================================================
  121. --- src/map/atcommand.h (revision 15269)
  122. +++ src/map/atcommand.h (working copy)
  123. @@ -45,4 +45,17 @@
  124.  int msg_config_read(const char* cfgName);
  125.  void do_final_msg(void);
  126.  
  127. +#define MAX_ATCMD_BINDINGS 100
  128. +
  129. +// @commands (script based)
  130. +typedef struct Atcmd_Binding {
  131. +   char command[50];
  132. +   char npc_event[50];
  133. +   int level;
  134. +   int level2;
  135. +} Atcmd_Binding;
  136. +
  137. +struct Atcmd_Binding atcmd_binding[MAX_ATCMD_BINDINGS];
  138. +struct Atcmd_Binding* get_atcommandbind_byname(const char* name);
  139. +
  140.  #endif /* _ATCOMMAND_H_ */
  141. Index: src/map/npc.c
  142. ===================================================================
  143. --- src/map/npc.c   (revision 15269)
  144. +++ src/map/npc.c   (working copy)
  145. @@ -2649,6 +2649,72 @@
  146.     clif_spawn(&nd->bl);// fade in
  147.  }
  148.  
  149. +// @commands (script based)
  150. +int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname)
  151. +{
  152. +   struct event_data* ev = (struct event_data*)strdb_get(ev_db, eventname);
  153. +   struct npc_data *nd;
  154. +   struct script_state *st;
  155. +   int i = 0, j = 0, k = 0;
  156. +   char *temp;
  157. +   temp = (char*)aMalloc(strlen(message) + 1);
  158. +
  159. +   nullpo_ret(sd);
  160. +
  161. +   if( ev == NULL || (nd = ev->nd) == NULL )
  162. +   {
  163. +       ShowError("npc_event: event not found [%s]\n", eventname);
  164. +       return 0;
  165. +   }
  166. +
  167. +   if( sd->npc_id != 0 )
  168. +   { // Enqueue the event trigger.
  169. +       int i;
  170. +       ARR_FIND( 0, MAX_EVENTQUEUE, i, sd->eventqueue[i][0] == '\0' );
  171. +       if( i < MAX_EVENTQUEUE )
  172. +       {
  173. +           safestrncpy(sd->eventqueue[i],eventname,50); //Event enqueued.
  174. +           return 0;
  175. +       }
  176. +
  177. +       ShowWarning("npc_event: player's event queue is full, can't add event '%s' !\n", eventname);
  178. +       return 1;
  179. +   }
  180. +
  181. +   if( ev->nd->sc.option&OPTION_INVISIBLE )
  182. +   { // Disabled npc, shouldn't trigger event.
  183. +       npc_event_dequeue(sd);
  184. +       return 2;
  185. +   }
  186. +
  187. +   st = script_alloc_state(ev->nd->u.scr.script, ev->pos, sd->bl.id, ev->nd->bl.id);
  188. +   setd_sub(st, NULL, ".@atcmd_command$", 0, (void *)command, NULL);
  189. +
  190. +   // split atcmd parameters based on spaces
  191. +   i = 0;
  192. +   j = 0;
  193. +   while( message[i] != '\0' )
  194. +   {
  195. +       if( message[i] == ' ' && k < 127 )
  196. +       {
  197. +           temp[j] = '\0';
  198. +           setd_sub(st, NULL, ".@atcmd_parameters$", k++, (void *)temp, NULL);
  199. +           j = 0;
  200. +           ++i;
  201. +       }
  202. +       else
  203. +           temp[j++] = message[i++];
  204. +   }
  205. +
  206. +   temp[j] = '\0';
  207. +   setd_sub(st, NULL, ".@atcmd_parameters$", k++, (void *)temp, NULL);
  208. +   setd_sub(st, NULL, ".@atcmd_numparameters", 0, (void *)&k, NULL);
  209. +   aFree(temp);
  210. +
  211. +   run_script_main(st);
  212. +   return 0;
  213. +}
  214. +
  215.  /// Parses a function.
  216.  /// function%TAB%script%TAB%<function name>%TAB%{<code>}
  217.  static const char* npc_parse_function(char* w1, char* w2, char* w3, char* w4, const char* start, const char* buffer, const char* filepath)
  218. Index: src/map/npc.h
  219. ===================================================================
  220. --- src/map/npc.h   (revision 15269)
  221. +++ src/map/npc.h   (working copy)
  222. @@ -156,4 +156,7 @@
  223.  
  224.  extern struct npc_data* fake_nd;
  225.  
  226. +// @commands (script-based)
  227. +int npc_do_atcmd_event(struct map_session_data* sd, const char* command, const char* message, const char* eventname);
  228. +
  229.  #endif /* _NPC_H_ */
  230. Index: src/map/script.c
  231. ===================================================================
  232. --- src/map/script.c    (revision 15269)
  233. +++ src/map/script.c    (working copy)
  234. @@ -3823,6 +3823,10 @@
  235.  {
  236.     userfunc_db->clear(userfunc_db,do_final_userfunc_sub);
  237.     scriptlabel_db->clear(scriptlabel_db, NULL);
  238. +  
  239. +   // @commands (script based)
  240. +   // Clear bindings
  241. +   memset(atcmd_binding,0,sizeof(atcmd_binding));
  242.  
  243.     if(sleep_db) {
  244.         struct linkdb_node *n = (struct linkdb_node *)sleep_db;
  245. @@ -15418,6 +15422,99 @@
  246.  }
  247.  
  248.  
  249. +/**
  250. + * @commands (script based)
  251. + **/
  252. +BUILDIN_FUNC(bindatcmd)
  253. +{
  254. +   const char* atcmd;
  255. +   const char* eventName;
  256. +   int i = 0, level = 0, level2 = 0;
  257. +
  258. +   atcmd = script_getstr(st,2);
  259. +   eventName = script_getstr(st,3);
  260. +
  261. +   if( script_hasdata(st,4) ) level = script_getnum(st,4);
  262. +   if( script_hasdata(st,5) ) level2 = script_getnum(st,5);
  263. +
  264. +   // check if event is already binded
  265. +   ARR_FIND(0, MAX_ATCMD_BINDINGS, i, strcmp(atcmd_binding[i].command,atcmd) == 0);
  266. +   if( i < MAX_ATCMD_BINDINGS )
  267. +   {
  268. +       safestrncpy(atcmd_binding[i].npc_event, eventName, 50);
  269. +       atcmd_binding[i].level = level;
  270. +       atcmd_binding[i].level2 = level2;
  271. +   }
  272. +   else
  273. +   { // make new binding
  274. +       ARR_FIND(0, MAX_ATCMD_BINDINGS, i, atcmd_binding[i].command[0] == '\0');
  275. +       if( i < MAX_ATCMD_BINDINGS )
  276. +       {
  277. +           safestrncpy(atcmd_binding[i].command, atcmd, 50);
  278. +           safestrncpy(atcmd_binding[i].npc_event, eventName, 50);
  279. +           atcmd_binding[i].level = level;
  280. +           atcmd_binding[i].level2 = level2;
  281. +       }
  282. +   }
  283. +
  284. +   return 0;
  285. +}
  286. +
  287. +BUILDIN_FUNC(unbindatcmd)
  288. +{
  289. +   const char* atcmd;
  290. +   int i =  0;
  291. +
  292. +   atcmd = script_getstr(st, 2);
  293. +
  294. +   ARR_FIND(0, MAX_ATCMD_BINDINGS, i, strcmp(atcmd_binding[i].command, atcmd) == 0);
  295. +   if( i < MAX_ATCMD_BINDINGS )
  296. +       memset(&atcmd_binding[i],0,sizeof(atcmd_binding[0]));
  297. +
  298. +   return 0;
  299. +}
  300. +
  301. +BUILDIN_FUNC(useatcmd)
  302. +{
  303. +   TBL_PC dummy_sd;
  304. +   TBL_PC* sd;
  305. +   int fd;
  306. +   const char* cmd;
  307. +
  308. +   cmd = script_getstr(st,2);
  309. +
  310. +   if( st->rid )
  311. +   {
  312. +       sd = script_rid2sd(st);
  313. +       fd = sd->fd;
  314. +   }
  315. +   else
  316. +   { // Use a dummy character.
  317. +       sd = &dummy_sd;
  318. +       fd = 0;
  319. +
  320. +       memset(&dummy_sd, 0, sizeof(TBL_PC));
  321. +       if( st->oid )
  322. +       {
  323. +           struct block_list* bl = map_id2bl(st->oid);
  324. +           memcpy(&dummy_sd.bl, bl, sizeof(struct block_list));
  325. +           if( bl->type == BL_NPC )
  326. +               safestrncpy(dummy_sd.status.name, ((TBL_NPC*)bl)->name, NAME_LENGTH);
  327. +       }
  328. +   }
  329. +
  330. +   // compatibility with previous implementation (deprecated!)
  331. +   /*if( cmd[0] != atcommand_symbol )
  332. +   {
  333. +       cmd += strlen(sd->status.name);
  334. +       while( *cmd != atcommand_symbol && *cmd != 0 )
  335. +           cmd++;
  336. +   } */
  337. +
  338. +   is_atcommand(fd, sd, cmd, 1);
  339. +   return 0;
  340. +}
  341. +
  342.  // declarations that were supposed to be exported from npc_chat.c
  343.  #ifdef PCRE_SUPPORT
  344.  BUILDIN_FUNC(defpattern);
  345. @@ -15827,6 +15924,13 @@
  346.     BUILDIN_DEF(has_instance,"s?"),
  347.     BUILDIN_DEF(instance_warpall,"sii?"),
  348.  
  349. +   /**
  350. +    * @commands (script based)
  351. +    **/
  352. +   BUILDIN_DEF(bindatcmd, "ss??"),
  353. +   BUILDIN_DEF(unbindatcmd, "s"),
  354. +   BUILDIN_DEF(useatcmd, "s"),
  355. +
  356.     //Quest Log System [Inkfish]
  357.     BUILDIN_DEF(setquest, "i"),
  358.     BUILDIN_DEF(erasequest, "i"),
  359. Index: src/map/script.h
  360. ===================================================================
  361. --- src/map/script.h    (revision 15269)
  362. +++ src/map/script.h    (working copy)
  363. @@ -182,4 +182,7 @@
  364.  const char* get_str(int id);
  365.  int script_reload(void);
  366.  
  367. +// @commands (script based)
  368. +void setd_sub(struct script_state *st, TBL_PC *sd, const char *varname, int elem, void *value, struct DBMap **ref);
  369. +
  370.  #endif /* _SCRIPT_H_ */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement