Advertisement
Guest User

Untitled

a guest
Oct 1st, 2012
889
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 10.49 KB | None | 0 0
  1. Index: src/map/clif.c
  2. ===================================================================
  3. --- src/map/clif.c  (revision 14901)
  4. +++ src/map/clif.c  (working copy)
  5. @@ -158,6 +158,79 @@
  6.  }
  7.  
  8.  /*==========================================
  9. + * Custom vending list (script based)
  10. + *------------------------------------------*/
  11. +int clif_vending_script(struct map_session_data* sd, struct npc_data* nd)
  12. +{
  13. +   int i, j, fd, len;
  14. +#if PACKETVER < 20100105
  15. +   const int cmd = 0x133;
  16. +   const int offset = 8;
  17. +#else
  18. +   const int cmd = 0x800;
  19. +   const int offset = 12;
  20. +#endif
  21. +
  22. +   nullpo_retr(0, sd);
  23. +   nullpo_retr(0, nd);
  24. +
  25. +   ARR_FIND( 0, MAX_VENDING, i, nd->vending[i].nameid > 0 );
  26. +
  27. +   if( i == MAX_VENDING )
  28. +       return 0;
  29. +
  30. +   fd = sd->fd;
  31. +   len = offset;
  32. +
  33. +   WFIFOHEAD(fd, offset+MAX_VENDING*22);
  34. +   WFIFOW(fd,0) = cmd;
  35. +   WFIFOL(fd,4) = sd->bl.id;
  36. +#if PACKETVER >= 20100105
  37. +   WFIFOL(fd,8) = nd->bl.id;
  38. +#endif
  39. +
  40. +   for( i = 0; MAX_VENDING > i; i++ )
  41. +   {
  42. +       int k;
  43. +       struct item_data* data;
  44. +       struct npc_item_vend* v;
  45. +
  46. +       if( nd->vending[i].nameid == 0 )
  47. +           continue;
  48. +
  49. +       v = &nd->vending[i];
  50. +      
  51. +       data = itemdb_search(v->nameid);
  52. +
  53. +       WFIFOL(fd,offset+ 0+i*22) = v->value;
  54. +       WFIFOW(fd,offset+ 4+i*22) = 1;
  55. +       WFIFOW(fd,offset+ 6+i*22) = i + 2;
  56. +       WFIFOB(fd,offset+ 8+i*22) = itemtype(data->type);
  57. +       WFIFOW(fd,offset+ 9+i*22) = ( data->view_id > 0 ) ? data->view_id : data->nameid;
  58. +       WFIFOB(fd,offset+11+i*22) = 1;
  59. +       WFIFOB(fd,offset+12+i*22) = v->attribute;
  60. +       WFIFOB(fd,offset+13+i*22) = v->refine;
  61. +
  62. +       for( j = 0; MAX_SLOTS > j; j++ )
  63. +       {
  64. +           if( v->card[j] > 0 && ( k = itemdb_viewid(v->card[j]) ) > 0 )
  65. +               WFIFOW(fd,offset+14+(j*2)+i*22) = k;
  66. +           else
  67. +               WFIFOW(fd,offset+14+(j*2)+i*22) = v->card[j];
  68. +       }
  69. +
  70. +       len += 22;
  71. +   }
  72. +
  73. +   WFIFOW(fd,2) = len;
  74. +   WFIFOSET(fd,WFIFOW(fd,2));
  75. +
  76. +   sd->state.npc_vending = nd->bl.id;
  77. +
  78. +   return 0;
  79. +}
  80. +
  81. +/*==========================================
  82.   * mapŽI‚Ìport“ǂݏo‚µ
  83.   *------------------------------------------*/
  84.  uint16 clif_getport(void)
  85. Index: src/map/clif.h
  86. ===================================================================
  87. --- src/map/clif.h  (revision 14901)
  88. +++ src/map/clif.h  (working copy)
  89. @@ -218,6 +218,8 @@
  90.  uint32 clif_refresh_ip(void);
  91.  uint16 clif_getport(void);
  92.  
  93. +int clif_vending_script(struct map_session_data* sd, struct npc_data* nd);
  94. +
  95.  int clif_authok(struct map_session_data *);
  96.  int clif_authfail_fd(int fd,int type);
  97.  int clif_charselectok(int id, uint8 ok);
  98. Index: src/map/npc.h
  99. ===================================================================
  100. --- src/map/npc.h   (revision 14901)
  101. +++ src/map/npc.h   (working copy)
  102. @@ -22,6 +22,13 @@
  103.  struct npc_item_list {
  104.     unsigned int nameid,value;
  105.  };
  106. +struct npc_item_vend {
  107. +   short nameid;
  108. +   char refine;
  109. +   char attribute;
  110. +   short card[MAX_SLOTS];
  111. +   unsigned int value;
  112. +};
  113.  
  114.  struct npc_data {
  115.     struct block_list bl;
  116. @@ -36,6 +43,7 @@
  117.     int chat_id;
  118.     int touching_id;
  119.     unsigned int next_walktime;
  120. +   struct npc_item_vend vending[MAX_VENDING];
  121.  
  122.     unsigned size : 2;
  123.  
  124. Index: src/map/pc.h
  125. ===================================================================
  126. --- src/map/pc.h    (revision 14901)
  127. +++ src/map/pc.h    (working copy)
  128. @@ -134,6 +134,7 @@
  129.         unsigned int vending : 1;
  130.         unsigned int noks : 3; // [Zeph Kill Steal Protection]
  131.         unsigned int changemap : 1;
  132. +       unsigned int npc_vending; // Player has a vending open from a script
  133.         short pmap; // Previous map on Map Change
  134.         unsigned short autoloot;
  135.         unsigned short autolootid; // [Zephyrus]
  136. Index: src/map/script.c
  137. ===================================================================
  138. --- src/map/script.c    (revision 14901)
  139. +++ src/map/script.c    (working copy)
  140. @@ -3837,6 +3837,137 @@
  141.  // NPC interaction
  142.  //
  143.  
  144. +/*==================================================*
  145. + * vending_add <item id>, <price>{, <refine>{, <attribute>{, <card1>, <card2>, <card3>, <card4>{, "<name>"}}}};
  146. + *--------------------------------------------------*/
  147. +BUILDIN_FUNC(vending_add)
  148. +{
  149. +   int i;
  150. +   struct npc_data* nd;
  151. +   struct npc_item_vend* vend;
  152. +
  153. +   nd = script_hasdata(st, 10) ? npc_name2id(script_getstr(st, 10)) : map_id2nd(st->oid);
  154. +
  155. +   if( nd == NULL )
  156. +   {
  157. +       ShowWarning("script:vending_add: no script attached\n");
  158. +       return 0;
  159. +   }
  160. +
  161. +   ARR_FIND( 0, MAX_VENDING, i, nd->vending[i].nameid == 0 );
  162. +
  163. +   if( i == MAX_VENDING )
  164. +   {
  165. +       ShowWarning("script:vending_add: reached maximum vending capacity (%d)\n", MAX_VENDING);
  166. +       return 0;
  167. +   }
  168. +
  169. +   vend = &nd->vending[i];
  170. +
  171. +   if( itemdb_exists(script_getnum(st, 2)) == NULL )
  172. +   {
  173. +       ShowWarning("script:vending_add: unknown item id %d\n", script_getnum(st, 2));
  174. +       return 0;
  175. +   }
  176. +
  177. +   memset( vend, 0, sizeof (struct npc_item_vend) );
  178. +
  179. +   vend->nameid = script_getnum(st, 2);
  180. +   vend->value = script_getnum(st, 3);
  181. +  
  182. +   FETCH(4, vend->refine);
  183. +   FETCH(5, vend->attribute);
  184. +
  185. +   for( i = 0; MAX_SLOTS > i; i++ )
  186. +       FETCH(6 + i, vend->card[i]);
  187. +
  188. +   script_pushint(st, i + 1);
  189. +
  190. +   return 0;
  191. +}
  192. +
  193. +/*==================================================*
  194. + * vending_remove <item id>{, "<name>"};
  195. + *--------------------------------------------------*/
  196. +BUILDIN_FUNC(vending_remove)
  197. +{
  198. +   int i;
  199. +   struct npc_data* nd;
  200. +
  201. +   nd = script_hasdata(st, 3) ? npc_name2id(script_getstr(st, 3)) : map_id2nd(st->oid);
  202. +
  203. +   if( nd == NULL )
  204. +   {
  205. +       ShowWarning("script:vending_remove: no script attached\n");
  206. +       return 0;
  207. +   }
  208. +
  209. +   i = script_getnum(st, 2);
  210. +
  211. +   if( i > 0 && i <= MAX_VENDING )
  212. +       i--;
  213. +   else
  214. +   {
  215. +       ARR_FIND( 0, MAX_VENDING, i, nd->vending[i].nameid == script_getnum(st, 2) );
  216. +
  217. +       if( i == MAX_VENDING )
  218. +       {
  219. +           ShowWarning("script:vending_remove: couldn't find item %d to remove\n", script_getnum(st, 2));
  220. +           return 0;
  221. +       }
  222. +   }
  223. +
  224. +   memset( &nd->vending[i], 0, sizeof (struct npc_item_vend) );
  225. +
  226. +   return 0;
  227. +}
  228. +
  229. +/*==================================================*
  230. + * vending_open {"<name>"};
  231. + *--------------------------------------------------*/
  232. +BUILDIN_FUNC(vending_open)
  233. +{
  234. +   struct npc_data* nd;
  235. +   struct map_session_data* sd = script_rid2sd(st);
  236. +
  237. +   nullpo_retr(0, sd);
  238. +  
  239. +   nd = script_hasdata(st, 2) ? npc_name2id(script_getstr(st, 2)) : map_id2nd(st->oid);
  240. +
  241. +   if( nd == NULL )
  242. +   {
  243. +       ShowWarning("script:vending_open: no script attached\n");
  244. +       return 0;
  245. +   }
  246. +  
  247. +   clif_vending_script(sd, nd);
  248. +
  249. +   return 0;
  250. +}
  251. +
  252. +/*==================================================*
  253. + * vending_reset {"<name>"};
  254. + *--------------------------------------------------*/
  255. +BUILDIN_FUNC(vending_reset)
  256. +{
  257. +   struct npc_data* nd;
  258. +   struct map_session_data* sd = script_rid2sd(st);
  259. +
  260. +   nullpo_retr(0, sd);
  261. +  
  262. +   nd = script_hasdata(st, 2) ? npc_name2id(script_getstr(st, 2)) : map_id2nd(st->oid);
  263. +
  264. +   if( nd == NULL )
  265. +   {
  266. +       ShowWarning("script:vending_reset: no script attached\n");
  267. +       return 0;
  268. +   }
  269. +  
  270. +   memset( nd->vending, 0, sizeof (nd->vending) );
  271. +
  272. +   return 0;
  273. +}
  274. +
  275.  /// Appends a message to the npc dialog.
  276.  /// If a dialog doesn't exist yet, one is created.
  277.  ///
  278. @@ -15329,5 +15460,11 @@
  279.     BUILDIN_DEF(checkquest, "i?"),
  280.     BUILDIN_DEF(changequest, "ii"),
  281.     BUILDIN_DEF(showevent, "ii"),
  282. +
  283. +   BUILDIN_DEF(vending_add, "ii*"),
  284. +   BUILDIN_DEF(vending_remove, "i*"),
  285. +   BUILDIN_DEF(vending_open, "*"),
  286. +   BUILDIN_DEF(vending_reset, "*"),
  287. +
  288.     {NULL,NULL,NULL},
  289.  };
  290. Index: src/map/vending.c
  291. ===================================================================
  292. --- src/map/vending.c   (revision 14901)
  293. +++ src/map/vending.c   (working copy)
  294. @@ -15,6 +15,7 @@
  295.  #include "skill.h"
  296.  #include "battle.h"
  297.  #include "log.h"
  298. +#include "npc.h"
  299.  
  300.  #include <stdio.h>
  301.  #include <string.h>
  302. @@ -66,6 +67,108 @@
  303.  }
  304.  
  305.  /*==========================================
  306. + * Purchase item(s) from a script
  307. + *------------------------------------------*/
  308. +void vending_purchasereq_script(struct map_session_data* sd, struct npc_data* nd, int uid, const uint8* data, int count)
  309. +{
  310. +   int i;
  311. +   int add;
  312. +   int blank;
  313. +   int weight;
  314. +   double zeny;
  315. +
  316. +   nullpo_retv(sd);
  317. +   nullpo_retv(nd);
  318. +  
  319. +   if( sd->state.npc_vending != nd->bl.id || uid != nd->bl.id )
  320. +   {
  321. +       clif_buyvending(sd, 0, 0, 6);
  322. +       return;
  323. +   }
  324. +
  325. +   if( count < 1 || count > MAX_VENDING )
  326. +       return;
  327. +
  328. +   blank = pc_inventoryblank(sd);
  329. +
  330. +   add = 0;
  331. +   zeny = 0;
  332. +   weight = 0;
  333. +
  334. +   for( i = 0; count > i; i++ )
  335. +   {
  336. +       short amount = *(uint16*)(data + 4*i + 0);
  337. +       short index  = *(uint16*)(data + 4*i + 2);
  338. +       struct item_data* data;
  339. +
  340. +       if( amount <= 0 )
  341. +           continue;
  342. +
  343. +       index -= 2;
  344. +
  345. +       if( index < 0 || index >= MAX_VENDING || nd->vending[index].nameid == 0 )
  346. +           continue;
  347. +      
  348. +       data = itemdb_exists(nd->vending[index].nameid);
  349. +
  350. +       if( data == NULL )
  351. +           continue;
  352. +
  353. +       zeny += (double)( nd->vending[index].value * amount );
  354. +
  355. +       if( zeny > (double)sd->status.zeny || zeny < 0.0 || zeny > (double)MAX_ZENY )
  356. +       {
  357. +           clif_buyvending(sd, index, amount, 1);
  358. +           return;
  359. +       }
  360. +
  361. +       weight += data->weight * amount;
  362. +
  363. +       if( weight + sd->weight > sd->max_weight )
  364. +       {
  365. +           clif_buyvending(sd, index, amount, 2);
  366. +           return;
  367. +       }
  368. +
  369. +       switch( pc_checkadditem(sd, nd->vending[index].nameid, amount) )
  370. +       {
  371. +           case ADDITEM_OVERAMOUNT:
  372. +               return;
  373. +           case ADDITEM_NEW:
  374. +               add++;
  375. +       }
  376. +   }
  377. +
  378. +   if( add > blank )
  379. +       return;
  380. +
  381. +   pc_payzeny(sd, (int)zeny);
  382. +
  383. +   for( i = 0; count > i; i++ )
  384. +   {
  385. +       short amount = *(uint16*)(data + 4*i + 0);
  386. +       short index  = *(uint16*)(data + 4*i + 2);
  387. +       struct item add_item;
  388. +      
  389. +       index -= 2;
  390. +
  391. +       memset( &add_item, 0, sizeof(struct item) );
  392. +
  393. +       add_item.nameid = nd->vending[index].nameid;
  394. +       add_item.refine = nd->vending[index].refine;
  395. +       add_item.identify = 1;
  396. +       add_item.attribute = nd->vending[index].attribute;
  397. +      
  398. +       memcpy( add_item.card, nd->vending[index].card, sizeof(nd->vending[index].card) );
  399. +
  400. +       pc_additem(sd, &add_item, amount);
  401. +   }
  402. +
  403. +   if( save_settings&2 )
  404. +       chrif_save(sd, 0);
  405. +}
  406. +
  407. +/*==========================================
  408.   * Purchase item(s) from a shop
  409.   *------------------------------------------*/
  410.  void vending_purchasereq(struct map_session_data* sd, int aid, int uid, const uint8* data, int count)
  411. @@ -76,6 +179,18 @@
  412.     struct map_session_data* vsd = map_id2sd(aid);
  413.  
  414.     nullpo_retv(sd);
  415. +  
  416. +   if( sd->state.npc_vending == uid )
  417. +   {// a script vend has been requests
  418. +       struct npc_data* nd = map_id2nd(uid);
  419. +
  420. +       if( nd == NULL )
  421. +           return;
  422. +
  423. +       vending_purchasereq_script(sd, nd, uid, data, count);
  424. +       return;
  425. +   }
  426. +
  427.     if( vsd == NULL || !vsd->state.vending || vsd->bl.id == sd->bl.id )
  428.         return; // invalid shop
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement