diff options
Diffstat (limited to 'src/map/skill.c')
-rw-r--r-- | src/map/skill.c | 107 |
1 files changed, 88 insertions, 19 deletions
diff --git a/src/map/skill.c b/src/map/skill.c index 24fbe7892..c2a336d7e 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -47,6 +47,7 @@ #include "map/refine.h" #include "map/script.h" #include "map/status.h" +#include "map/storage.h" #include "map/unit.h" #include "common/cbasetypes.h" #include "common/ers.h" @@ -370,6 +371,41 @@ static int skill_get_spiritball(int skill_id, int skill_lv) } /** + * Gets the index of the first required item for a skill at given level. + * + * @param skill_id The skill's ID. + * @param skill_lv The skill's level. + * @return The required item's index. Defaults to INDEX_NOT_FOUND (-1) in case of error or if no appropriate index was found. + * + **/ +static int skill_get_item_index(int skill_id, int skill_lv) +{ + if (skill_id == 0) + return INDEX_NOT_FOUND; + + Assert_retr(INDEX_NOT_FOUND, skill_lv > 0); + + int idx = skill->get_index(skill_id); + + Assert_retr(INDEX_NOT_FOUND, idx != 0); + + int item_index = INDEX_NOT_FOUND; + int level_index = skill_get_lvl_idx(skill_lv); + + for (int i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++) { + if (skill->dbs->db[idx].req_items.item[i].id == 0) + continue; + + if (skill->dbs->db[idx].req_items.item[i].amount[level_index] != -1) { + item_index = i; + break; + } + } + + return item_index; +} + +/** * Gets a skill's required item's ID by the skill's ID and the item's index. * * @param skill_id The skill's ID. @@ -1613,11 +1649,15 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl if( pc_iswug(sd) && (temp=pc->checkskill(sd,RA_WUGSTRIKE)) > 0 && rnd()%1000 <= sstatus->luk*3 ) skill->castend_damage_id(src,bl,RA_WUGSTRIKE,temp,tick,0); // Gank - if(dstmd && sd->weapontype != W_BOW && - (temp=pc->checkskill(sd,RG_SNATCHER)) > 0 && - (temp*15 + 55) + pc->checkskill(sd,TF_STEAL)*10 > rnd()%1000) { - if(pc->steal_item(sd,bl,pc->checkskill(sd,TF_STEAL))) - clif->skill_nodamage(src,bl,TF_STEAL,temp,1); + if (dstmd && sd->weapontype != W_BOW && + (temp = pc->checkskill(sd, RG_SNATCHER)) > 0 && +#ifdef RENEWAL + (temp * 10) + pc->checkskill(sd, TF_STEAL) * 10 > rnd() % 1000) { +#else + (temp * 15 + 55) + pc->checkskill(sd, TF_STEAL) * 10 > rnd() % 1000) { +#endif + if (pc->steal_item(sd, bl, pc->checkskill(sd, TF_STEAL))) + clif->skill_nodamage(src, bl, TF_STEAL, temp, 1); else clif->skill_fail(sd, RG_SNATCHER, USESKILL_FAIL_LEVEL, 0, 0); } @@ -7937,7 +7977,14 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list * } if( sd ) { int bonus = 100, potion = min(500+skill_lv,505); - int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE; + int item_idx = skill->get_item_index(skill_id, skill_lv); + + if (item_idx == INDEX_NOT_FOUND) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); + map->freeblock_unlock(); + return 1; + } + int item_id = skill->get_itemid(skill_id, item_idx); int inventory_idx = pc->search_inventory(sd, item_id); if (inventory_idx == INDEX_NOT_FOUND || item_id <= 0) { @@ -11312,17 +11359,21 @@ static int skill_castend_map(struct map_session_data *sd, uint16 skill_id, const return 0; } - switch(skill_id) { + switch (skill_id) { case AL_TELEPORT: - // The storage window is closed automatically by the client when there's - // any kind of map change, so we need to restore it automatically - // issue: 8027 - if(strcmp(mapname,"Random")==0) - pc->randomwarp(sd,CLR_TELEPORT); - else if (sd->menuskill_val > 1) //Need lv2 to be able to warp here. - pc->setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT); - - clif->refresh_storagewindow(sd); + if (strcmp(mapname, "Random") == 0) + pc->randomwarp(sd, CLR_TELEPORT); + else if (sd->menuskill_val > 1) // Need lv2 to be able to warp here. + pc->setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT); + + if (battle_config.teleport_close_storage == 1 && sd->state.storage_flag != STORAGE_FLAG_CLOSED) { + if (sd->state.storage_flag == STORAGE_FLAG_NORMAL) + storage->close(sd); + if (sd->state.storage_flag == STORAGE_FLAG_GUILD) + gstorage->close(sd); + } else { + clif->refresh_storagewindow(sd); + } break; case AL_WARP: @@ -11797,7 +11848,13 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill // Slim Pitcher [Celest] case CR_SLIMPITCHER: if (sd) { - int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE; + int item_idx = skill->get_item_index(skill_id, skill_lv); + + if (item_idx == INDEX_NOT_FOUND) { + clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0); + return 1; + } + int item_id = skill->get_itemid(skill_id, item_idx); int inventory_idx = pc->search_inventory(sd, item_id); int bonus; @@ -11830,7 +11887,11 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill skill->castend_nodamage_id); } } else { - int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE; + int item_idx = skill->get_item_index(skill_id, skill_lv); + + if (item_idx == INDEX_NOT_FOUND) + return 1; + int item_id = skill->get_itemid(skill_id, item_idx); struct item_data *item = itemdb->search(item_id); int bonus; @@ -17766,13 +17827,20 @@ static int skill_get_new_group_id(void) static struct skill_unit_group *skill_initunitgroup(struct block_list *src, int count, uint16 skill_id, uint16 skill_lv, int unit_id, int limit, int interval) { - struct unit_data* ud = unit->bl2ud( src ); struct skill_unit_group* group; int i; if(!(skill_id && skill_lv)) return 0; nullpo_retr(NULL, src); + + struct unit_data *ud; + + if (src->type == BL_NPC) + ud = unit->bl2ud2(src); + else + ud = unit->bl2ud(src); + nullpo_retr(NULL, ud); // find a free spot to store the new unit group @@ -23937,6 +24005,7 @@ void skill_defaults(void) skill->get_sp_rate = skill_get_sp_rate; skill->get_state = skill_get_state; skill->get_spiritball = skill_get_spiritball; + skill->get_item_index = skill_get_item_index; skill->get_itemid = skill_get_itemid; skill->get_itemqty = skill_get_itemqty; skill->get_item_any_flag = skill_get_item_any_flag; |