Yudax Posted May 8, 2013 Group: Members Topic Count: 57 Topics Per Day: 0.01 Content Count: 248 Reputation: 7 Joined: 11/27/12 Last Seen: July 21, 2016 Share Posted May 8, 2013 (edited) I really got confused on adding patch manually; we take for example; this patch Index: src/map/clif.c =================================================================== --- src/map/clif.c (revision 16809) +++ src/map/clif.c (working copy) @@ -17032,6 +17032,79 @@ return 0; } + /*========================================== + * Custom vending list (script based) + *------------------------------------------*/ +int clif_vending_script(struct map_session_data* sd, struct npc_data* nd) +{ + int i, j, fd, len; +#if PACKETVER < 20100105 + const int cmd = 0x133; + const int offset = 8; +#else + const int cmd = 0x800; + const int offset = 12; +#endif + + nullpo_retr(0, sd); + nullpo_retr(0, nd); + + ARR_FIND( 0, MAX_VENDING, i, nd->vending[i].nameid > 0 ); + + if( i == MAX_VENDING ) + return 0; + + fd = sd->fd; + len = offset; + + WFIFOHEAD(fd, offset+MAX_VENDING*22); + WFIFOW(fd,0) = cmd; + WFIFOL(fd,4) = sd->bl.id; +#if PACKETVER >= 20100105 + WFIFOL(fd,8) = nd->bl.id; +#endif + + for( i = 0; MAX_VENDING > i; i++ ) + { + int k; + struct item_data* data; + struct npc_item_vend* v; + + if( nd->vending[i].nameid == 0 ) + continue; + + v = &nd->vending[i]; + + data = itemdb_search(v->nameid); + + WFIFOL(fd,offset+ 0+i*22) = v->value; + WFIFOW(fd,offset+ 4+i*22) = 1; + WFIFOW(fd,offset+ 6+i*22) = i + 2; + WFIFOB(fd,offset+ 8+i*22) = itemtype(data->type); + WFIFOW(fd,offset+ 9+i*22) = ( data->view_id > 0 ) ? data->view_id : data->nameid; + WFIFOB(fd,offset+11+i*22) = 1; + WFIFOB(fd,offset+12+i*22) = v->attribute; + WFIFOB(fd,offset+13+i*22) = v->refine; + + for( j = 0; MAX_SLOTS > j; j++ ) + { + if( v->card[j] > 0 && ( k = itemdb_viewid(v->card[j]) ) > 0 ) + WFIFOW(fd,offset+14+(j*2)+i*22) = k; + else + WFIFOW(fd,offset+14+(j*2)+i*22) = v->card[j]; + } + + len += 22; + } + + WFIFOW(fd,2) = len; + WFIFOSET(fd,WFIFOW(fd,2)); + + sd->state.npc_vending = nd->bl.id; + + return 0; +} + void do_final_clif(void) { ers_destroy(delay_clearunit_ers); } Index: src/map/clif.h =================================================================== --- src/map/clif.h (revision 16809) +++ src/map/clif.h (working copy) @@ -308,6 +308,7 @@ uint32 clif_refresh_ip(void); uint16 clif_getport(void); +int clif_vending_script(struct map_session_data* sd, struct npc_data* nd); void clif_authok(struct map_session_data *sd); void clif_authrefuse(int fd, uint8 error_code); void clif_authfail_fd(int fd, int type); Index: src/map/npc.h =================================================================== --- src/map/npc.h (revision 16809) +++ src/map/npc.h (working copy) @@ -23,6 +23,14 @@ unsigned int nameid,value; }; +struct npc_item_vend { + short nameid; + char refine; + char attribute; + short card[MAX_SLOTS]; + unsigned int value; +}; + struct npc_data { struct block_list bl; struct unit_data ud; //Because they need to be able to move.... @@ -36,6 +44,7 @@ int chat_id; int touching_id; unsigned int next_walktime; + struct npc_item_vend vending[MAX_VENDING]; unsigned size : 2; Index: src/map/pc.h =================================================================== --- src/map/pc.h (revision 16809) +++ src/map/pc.h (working copy) @@ -135,6 +135,7 @@ unsigned int vending : 1; unsigned int noks : 3; // [Zeph Kill Steal Protection] unsigned int changemap : 1; + unsigned int npc_vending; // Player has a vending open from a script unsigned int callshop : 1; // flag to indicate that a script used callshop; on a shop short pmap; // Previous map on Map Change unsigned short autoloot; Index: src/map/script.c =================================================================== --- src/map/script.c (revision 16809) +++ src/map/script.c (working copy) @@ -14614,6 +14614,137 @@ return 0; } +/*==================================================* + * vending_add <item id>, <price>{, <refine>{, <attribute>{, <card1>, <card2>, <card3>, <card4>{, "<name>"}}}}; + *--------------------------------------------------*/ +BUILDIN_FUNC(vending_add) +{ + int i; + struct npc_data* nd; + struct npc_item_vend* vend; + + nd = script_hasdata(st, 10) ? npc_name2id(script_getstr(st, 10)) : map_id2nd(st->oid); + + if( nd == NULL ) + { + ShowWarning("script:vending_add: no script attached\n"); + return 0; + } + + ARR_FIND( 0, MAX_VENDING, i, nd->vending[i].nameid == 0 ); + + if( i == MAX_VENDING ) + { + ShowWarning("script:vending_add: reached maximum vending capacity (%d)\n", MAX_VENDING); + return 0; + } + + vend = &nd->vending[i]; + + if( itemdb_exists(script_getnum(st, 2)) == NULL ) + { + ShowWarning("script:vending_add: unknown item id %d\n", script_getnum(st, 2)); + return 0; + } + + memset( vend, 0, sizeof (struct npc_item_vend) ); + + vend->nameid = script_getnum(st, 2); + vend->value = script_getnum(st, 3); + + FETCH(4, vend->refine); + FETCH(5, vend->attribute); + + for( i = 0; MAX_SLOTS > i; i++ ) + FETCH(6 + i, vend->card[i]); + + script_pushint(st, i + 1); + + return 0; +} + +/*==================================================* + * vending_remove <item id>{, "<name>"}; + *--------------------------------------------------*/ +BUILDIN_FUNC(vending_remove) +{ + int i; + struct npc_data* nd; + + nd = script_hasdata(st, 3) ? npc_name2id(script_getstr(st, 3)) : map_id2nd(st->oid); + + if( nd == NULL ) + { + ShowWarning("script:vending_remove: no script attached\n"); + return 0; + } + + i = script_getnum(st, 2); + + if( i > 0 && i <= MAX_VENDING ) + i--; + else + { + ARR_FIND( 0, MAX_VENDING, i, nd->vending[i].nameid == script_getnum(st, 2) ); + + if( i == MAX_VENDING ) + { + ShowWarning("script:vending_remove: couldn't find item %d to remove\n", script_getnum(st, 2)); + return 0; + } + } + + memset( &nd->vending[i], 0, sizeof (struct npc_item_vend) ); + + return 0; +} + +/*==================================================* + * vending_open {"<name>"}; + *--------------------------------------------------*/ +BUILDIN_FUNC(vending_open) +{ + struct npc_data* nd; + struct map_session_data* sd = script_rid2sd(st); + + nullpo_retr(0, sd); + + nd = script_hasdata(st, 2) ? npc_name2id(script_getstr(st, 2)) : map_id2nd(st->oid); + + if( nd == NULL ) + { + ShowWarning("script:vending_open: no script attached\n"); + return 0; + } + + clif_vending_script(sd, nd); + + return 0; +} + +/*==================================================* + * vending_reset {"<name>"}; + *--------------------------------------------------*/ +BUILDIN_FUNC(vending_reset) +{ + struct npc_data* nd; + struct map_session_data* sd = script_rid2sd(st); + + nullpo_retr(0, sd); + + nd = script_hasdata(st, 2) ? npc_name2id(script_getstr(st, 2)) : map_id2nd(st->oid); + + if( nd == NULL ) + { + ShowWarning("script:vending_reset: no script attached\n"); + return 0; + } + + memset( nd->vending, 0, sizeof (nd->vending) ); + + return 0; +} + /*========================================== * Returns some values of an item [Lupus] * Price, Weight, etc... @@ -17433,5 +17564,9 @@ BUILDIN_DEF(checkquest, "i?"), BUILDIN_DEF(changequest, "ii"), BUILDIN_DEF(showevent, "ii"), + BUILDIN_DEF(vending_add, "ii*"), + BUILDIN_DEF(vending_remove, "i*"), + BUILDIN_DEF(vending_open, "*"), + BUILDIN_DEF(vending_reset, "*"), {NULL,NULL,NULL}, }; Index: src/map/vending.c =================================================================== --- src/map/vending.c (revision 16809) +++ src/map/vending.c (working copy) @@ -16,6 +16,7 @@ #include "skill.h" #include "battle.h" #include "log.h" +#include "npc.h" #include <stdio.h> #include <string.h> @@ -66,6 +67,108 @@ clif_vendinglist(sd, id, vsd->vending); } + /*========================================== + * Purchase item(s) from a script + *------------------------------------------*/ +void vending_purchasereq_script(struct map_session_data* sd, struct npc_data* nd, int uid, const uint8* data, int count) +{ + int i; + int add; + int blank; + int weight; + double zeny; + + nullpo_retv(sd); + nullpo_retv(nd); + + if( sd->state.npc_vending != nd->bl.id || uid != nd->bl.id ) + { + clif_buyvending(sd, 0, 0, 6); + return; + } + + if( count < 1 || count > MAX_VENDING ) + return; + + blank = pc_inventoryblank(sd); + + add = 0; + zeny = 0; + weight = 0; + + for( i = 0; count > i; i++ ) + { + short amount = *(uint16*)(data + 4*i + 0); + short index = *(uint16*)(data + 4*i + 2); + struct item_data* data; + + if( amount <= 0 ) + continue; + + index -= 2; + + if( index < 0 || index >= MAX_VENDING || nd->vending[index].nameid == 0 ) + continue; + + data = itemdb_exists(nd->vending[index].nameid); + + if( data == NULL ) + continue; + + zeny += (double)( nd->vending[index].value * amount ); + + if( zeny > (double)sd->status.zeny || zeny < 0.0 || zeny > (double)MAX_ZENY ) + { + clif_buyvending(sd, index, amount, 1); + return; + } + + weight += data->weight * amount; + + if( weight + sd->weight > sd->max_weight ) + { + clif_buyvending(sd, index, amount, 2); + return; + } + + switch( pc_checkadditem(sd, nd->vending[index].nameid, amount) ) + { + case ADDITEM_OVERAMOUNT: + return; + case ADDITEM_NEW: + add++; + } + } + + if( add > blank ) + return; + + pc_payzeny(sd, (int)zeny); + + for( i = 0; count > i; i++ ) + { + short amount = *(uint16*)(data + 4*i + 0); + short index = *(uint16*)(data + 4*i + 2); + struct item add_item; + + index -= 2; + + memset( &add_item, 0, sizeof(struct item) ); + + add_item.nameid = nd->vending[index].nameid; + add_item.refine = nd->vending[index].refine; + add_item.identify = 1; + add_item.attribute = nd->vending[index].attribute; + + memcpy( add_item.card, nd->vending[index].card, sizeof(nd->vending[index].card) ); + + pc_additem(sd, &add_item, amount, LOG_TYPE_BUYING_STORE); + } + + if( save_settings&2 ) + chrif_save(sd, 0); +} + /*========================================== * Purchase item(s) from a shop *------------------------------------------*/ @@ -76,6 +179,17 @@ struct s_vending vending[MAX_VENDING]; // against duplicate packets struct map_session_data* vsd = map_id2sd(aid); + if( sd->state.npc_vending == uid ) + {// a script vend has been requests + struct npc_data* nd = map_id2nd(uid); + + if( nd == NULL ) + return; + + vending_purchasereq_script(sd, nd, uid, data, count); + return; + } + nullpo_retv(sd); if( vsd == NULL || !vsd->state.vending || vsd->bl.id == sd->bl.id ) return; // invalid shop About this; @@ -17032,6 +17032,79 @@ I've read in the wiki but I cant understand the @@ -17032,6 +17032,79 @@ Other than that; Is it possible to put these lines on a different location while not following the @@ -17032,6 +17032,79 @@ itself? + /*========================================== + * Custom vending list (script based) + *------------------------------------------*/ +int clif_vending_script(struct map_session_data* sd, struct npc_data* nd) +{ + int i, j, fd, len; +#if PACKETVER < 20100105 + const int cmd = 0x133; + const int offset = 8; +#else + const int cmd = 0x800; + const int offset = 12; +#endif + + nullpo_retr(0, sd); + nullpo_retr(0, nd); + + ARR_FIND( 0, MAX_VENDING, i, nd->vending[i].nameid > 0 ); + + if( i == MAX_VENDING ) + return 0; + + fd = sd->fd; + len = offset; + + WFIFOHEAD(fd, offset+MAX_VENDING*22); + WFIFOW(fd,0) = cmd; + WFIFOL(fd,4) = sd->bl.id; +#if PACKETVER >= 20100105 + WFIFOL(fd,8) = nd->bl.id; +#endif + + for( i = 0; MAX_VENDING > i; i++ ) + { + int k; + struct item_data* data; + struct npc_item_vend* v; + + if( nd->vending[i].nameid == 0 ) + continue; + + v = &nd->vending[i]; + + data = itemdb_search(v->nameid); + + WFIFOL(fd,offset+ 0+i*22) = v->value; + WFIFOW(fd,offset+ 4+i*22) = 1; + WFIFOW(fd,offset+ 6+i*22) = i + 2; + WFIFOB(fd,offset+ 8+i*22) = itemtype(data->type); + WFIFOW(fd,offset+ 9+i*22) = ( data->view_id > 0 ) ? data->view_id : data->nameid; + WFIFOB(fd,offset+11+i*22) = 1; + WFIFOB(fd,offset+12+i*22) = v->attribute; + WFIFOB(fd,offset+13+i*22) = v->refine; + + for( j = 0; MAX_SLOTS > j; j++ ) + { + if( v->card[j] > 0 && ( k = itemdb_viewid(v->card[j]) ) > 0 ) + WFIFOW(fd,offset+14+(j*2)+i*22) = k; + else + WFIFOW(fd,offset+14+(j*2)+i*22) = v->card[j]; + } + + len += 22; + } + + WFIFOW(fd,2) = len; + WFIFOSET(fd,WFIFOW(fd,2)); + + sd->state.npc_vending = nd->bl.id; + + return 0; +} + void do_final_clif(void) { ers_destroy(delay_clearunit_ers); } Index: src/map/clif.h =================================================================== --- src/map/clif.h (revision 16809) +++ src/map/clif.h (working copy) @@ -308,6 +308,7 @@ uint32 clif_refresh_ip(void); uint16 clif_getport(void); +int clif_vending_script(struct map_session_data* sd, struct npc_data* nd); void clif_authok(struct map_session_data *sd); void clif_authrefuse(int fd, uint8 error_code); void clif_authfail_ Edited May 8, 2013 by Yudax Quote Link to comment Share on other sites More sharing options...
Mootie Posted May 8, 2013 Group: Members Topic Count: 43 Topics Per Day: 0.01 Content Count: 815 Reputation: 86 Joined: 10/26/12 Last Seen: June 10, 2022 Share Posted May 8, 2013 Yes thats possible.but you have to make sure tht tou are going to close them if you are making new line Quote Link to comment Share on other sites More sharing options...
Yudax Posted May 8, 2013 Group: Members Topic Count: 57 Topics Per Day: 0.01 Content Count: 248 Reputation: 7 Joined: 11/27/12 Last Seen: July 21, 2016 Author Share Posted May 8, 2013 Yes thats possible.but you have to make sure tht tou are going to close them if you are making new line Thanks for the reply, What do you mean by going to close them? I mean just adding them manually in a different locations Quote Link to comment Share on other sites More sharing options...
uDe Posted May 8, 2013 Group: Members Topic Count: 43 Topics Per Day: 0.01 Content Count: 400 Reputation: 5 Joined: 12/05/11 Last Seen: September 27, 2015 Share Posted May 8, 2013 Well, I've been manually applying .diff to my server. It's kinda easy if you know how the modification works. For me, it's same like scripting. Let me give you some tips. From your example, the mod is for src/map/clif.c So, open your clif.c with notepad++ (recommended) Then, what do you need to do is to find or identify which line you need to apply the mods. In this case, for me, I'll simply ignore the @@ -17032,6 +17032,79 @@ Because, different SVN have different lines. So, how to know at which line you need to add it? Easy, just refer to the .diff , and find something like this : void do_final_clif(void) { ers_destroy(delay_clearunit_ers); } The lines above is the default lines from clif.c file. So, simply use CTRL+F to find any line from above. After you found it, copy the modification lines and ADD it ABOVE the line that you're just found. Make sure that your new lines (modification line) is below return 0; } and above void do_final_clif(void) { ers_destroy(delay_clearunit_ers); } Then, you just remove the + sign. IF in the .diff file have line like this - chrif_save(sd, 0); You need to remove the ENTIRE line. Usually, line like that is for default line and you need to replace it with new line (with + sign) from the .diff file. Sorry for my poor English and for other rA members, please correct me if I'm wrong. Quote Link to comment Share on other sites More sharing options...
Yudax Posted May 8, 2013 Group: Members Topic Count: 57 Topics Per Day: 0.01 Content Count: 248 Reputation: 7 Joined: 11/27/12 Last Seen: July 21, 2016 Author Share Posted May 8, 2013 Thank you, So we just neglect the @@ -17032,6 +17032,79 @@ So other problem is that when there is an error, how do you usually fix it? Try to patch that .diff its actually from http://rathena.org/board/topic/82555-auto-vend/#entry198691. Well, I've been manually applying .diff to my server. It's kinda easy if you know how the modification works. For me, it's same like scripting. Let me give you some tips. From your example, the mod is for src/map/clif.c So, open your clif.c with notepad++ (recommended) Then, what do you need to do is to find or identify which line you need to apply the mods. In this case, for me, I'll simply ignore the @@ -17032,6 +17032,79 @@ Because, different SVN have different lines. So, how to know at which line you need to add it? Easy, just refer to the .diff , and find something like this : void do_final_clif(void) { ers_destroy(delay_clearunit_ers); } The lines above is the default lines from clif.c file. So, simply use CTRL+F to find any line from above. After you found it, copy the modification lines and ADD it ABOVE the line that you're just found. Make sure that your new lines (modification line) is below return 0; } and above void do_final_clif(void) { ers_destroy(delay_clearunit_ers); } Then, you just remove the + sign. IF in the .diff file have line like this - chrif_save(sd, 0); You need to remove the ENTIRE line. Usually, line like that is for default line and you need to replace it with new line (with + sign) from the .diff file. Sorry for my poor English and for other rA members, please correct me if I'm wrong. Quote Link to comment Share on other sites More sharing options...
uDe Posted May 8, 2013 Group: Members Topic Count: 43 Topics Per Day: 0.01 Content Count: 400 Reputation: 5 Joined: 12/05/11 Last Seen: September 27, 2015 Share Posted May 8, 2013 So other problem is that when there is an error, how do you usually fix it? Try to patch that .diff its actually from http://rathena.org/b...d/#entry198691. You should make a new thread or maybe replying on that thread about the errors. Please provide some screen shot of map-server. If not, other members can't help you because they don't know what errors occurred. Quote Link to comment Share on other sites More sharing options...
Question
Yudax
I really got confused on adding patch manually;
we take for example; this patch
About this;
I've read in the wiki but I cant understand the @@ -17032,6 +17032,79 @@
Other than that; Is it possible to put these lines on a different location while not following the @@ -17032,6 +17032,79 @@ itself?
Edited by YudaxLink to comment
Share on other sites
5 answers to this question
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.