diff options
author | Haru <haru@dotalux.com> | 2016-02-22 03:10:04 +0100 |
---|---|---|
committer | Haru <haru@dotalux.com> | 2016-02-24 21:02:17 +0100 |
commit | 23f1ef310719081c79aebf3f8921240773f5a507 (patch) | |
tree | 1b873269dba4d5b9f88b6db3f215c2d245a6b90b /src/map/skill.c | |
parent | c1ab5a9db773d399c86eb59a3dded649387480c0 (diff) | |
download | hercules-23f1ef310719081c79aebf3f8921240773f5a507.tar.gz hercules-23f1ef310719081c79aebf3f8921240773f5a507.tar.bz2 hercules-23f1ef310719081c79aebf3f8921240773f5a507.tar.xz hercules-23f1ef310719081c79aebf3f8921240773f5a507.zip |
Edited skill->changematerial() and skill->elementalanalysis() to use the new struct itemlist
- The skill-side code no longer depends on the client packet data layout.
- Some data validation has been added.
Signed-off-by: Haru <haru@dotalux.com>
Diffstat (limited to 'src/map/skill.c')
-rw-r--r-- | src/map/skill.c | 35 |
1 files changed, 21 insertions, 14 deletions
diff --git a/src/map/skill.c b/src/map/skill.c index a13e3a071..68cb3ff0e 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -17879,27 +17879,31 @@ int skill_select_menu(struct map_session_data *sd,uint16 skill_id) { sc_start4(&sd->bl,&sd->bl,SC__AUTOSHADOWSPELL,100,id,lv,prob,0,skill->get_time(SC_AUTOSHADOWSPELL,aslvl)); return 0; } -int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, unsigned short* item_list) { + +int skill_elementalanalysis(struct map_session_data *sd, uint16 skill_lv, const struct itemlist *item_list) +{ int i; nullpo_ret(sd); nullpo_ret(item_list); - if( n <= 0 ) + if (VECTOR_LENGTH(*item_list) <= 0) return 1; - for (i = 0; i < n; i++) { - int nameid, add_amount, del_amount, idx, product; + for (i = 0; i < VECTOR_LENGTH(*item_list); i++) { struct item tmp_item; - - idx = item_list[i*2+0]-2; - del_amount = item_list[i*2+1]; + const struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i); + int nameid, add_amount, product; + int del_amount = entry->amount; + int idx = entry->id; if( skill_lv == 2 ) del_amount -= (del_amount % 10); add_amount = (skill_lv == 1) ? del_amount * (5 + rnd()%5) : del_amount / 10 ; - if( (nameid = sd->status.inventory[idx].nameid) <= 0 || del_amount > sd->status.inventory[idx].amount ) { + if (idx < 0 || idx >= MAX_INVENTORY + || (nameid = sd->status.inventory[idx].nameid) <= 0 + || del_amount < 0 || del_amount > sd->status.inventory[idx].amount) { clif->skill_fail(sd,SO_EL_ANALYSIS,USESKILL_FAIL_LEVEL,0); return 1; } @@ -17949,7 +17953,8 @@ int skill_elementalanalysis(struct map_session_data* sd, int n, uint16 skill_lv, return 0; } -int skill_changematerial(struct map_session_data *sd, int n, unsigned short *item_list) { +int skill_changematerial(struct map_session_data *sd, const struct itemlist *item_list) +{ int i, j, k, c, p = 0, nameid, amount; nullpo_ret(sd); @@ -17964,11 +17969,13 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite // Verification of overlap between the objects required and the list submitted. for( j = 0; j < MAX_PRODUCE_RESOURCE; j++ ) { if( skill->dbs->produce_db[i].mat_id[j] > 0 ) { - for( k = 0; k < n; k++ ) { - int idx = item_list[k*2+0]-2; + for (k = 0; k < VECTOR_LENGTH(*item_list); k++) { + const struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, k); + int idx = entry->id; + Assert_ret(idx >= 0 && idx < MAX_INVENTORY); + amount = entry->amount; nameid = sd->status.inventory[idx].nameid; - amount = item_list[k*2+1]; - if( nameid > 0 && sd->status.inventory[idx].identify == 0 ){ + if (nameid > 0 && sd->status.inventory[idx].identify == 0) { clif->msgtable_skill(sd, GN_CHANGEMATERIAL, MSG_SKILL_ITEM_NEED_IDENTIFY); return 0; } @@ -17981,7 +17988,7 @@ int skill_changematerial(struct map_session_data *sd, int n, unsigned short *ite break; // No more items required } p++; - } while(n == j && c == n); + } while (c == j && VECTOR_LENGTH(*item_list) == c); p--; if ( p > 0 ) { skill->produce_mix(sd,GN_CHANGEMATERIAL,skill->dbs->produce_db[i].nameid,0,0,0,p); |