From 0f4a50d13538c3e5d3ca4d3822f92217c8da0479 Mon Sep 17 00:00:00 2001 From: shennetsind Date: Sat, 27 Apr 2013 13:33:10 -0300 Subject: Skill ID Processing Overhaul http://hercules.ws/board/topic/512-skill-id-processing-overhaul/ Signed-off-by: shennetsind --- src/map/pc.c | 360 +++++++++++++++++++++++++++++------------------------------ 1 file changed, 176 insertions(+), 184 deletions(-) (limited to 'src/map/pc.c') diff --git a/src/map/pc.c b/src/map/pc.c index 671cea6c4..afc92594b 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -940,19 +940,16 @@ bool pc_authok(struct map_session_data *sd, int login_id2, time_t expiration_tim // Checks and fixes to character status data, that are required // in case of configuration change or stuff, which cannot be // checked on char-server. - if( sd->status.hair < MIN_HAIR_STYLE || sd->status.hair > MAX_HAIR_STYLE ) - { + if( sd->status.hair < MIN_HAIR_STYLE || sd->status.hair > MAX_HAIR_STYLE ) { sd->status.hair = MIN_HAIR_STYLE; } - if( sd->status.hair_color < MIN_HAIR_COLOR || sd->status.hair_color > MAX_HAIR_COLOR ) - { + if( sd->status.hair_color < MIN_HAIR_COLOR || sd->status.hair_color > MAX_HAIR_COLOR ) { sd->status.hair_color = MIN_HAIR_COLOR; } - if( sd->status.clothes_color < MIN_CLOTH_COLOR || sd->status.clothes_color > MAX_CLOTH_COLOR ) - { + if( sd->status.clothes_color < MIN_CLOTH_COLOR || sd->status.clothes_color > MAX_CLOTH_COLOR ) { sd->status.clothes_color = MIN_CLOTH_COLOR; } - + //Initializations to null/0 unneeded since map_session_data was filled with 0 upon allocation. if(!sd->status.hp) pc_setdead(sd); sd->state.connect_new = 1; @@ -1145,7 +1142,7 @@ int pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl) *------------------------------------------*/ int pc_reg_received(struct map_session_data *sd) { - int i,j; + int i,j, idx = 0; sd->change_level_2nd = pc_readglobalreg(sd,"jobchange_level"); sd->change_level_3rd = pc_readglobalreg(sd,"jobchange_level_3rd"); @@ -1158,15 +1155,14 @@ int pc_reg_received(struct map_session_data *sd) // Cooking Exp sd->cook_mastery = pc_readglobalreg(sd,"COOK_MASTERY"); - if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON ) - { // Better check for class rather than skill to prevent "skill resets" from unsetting this + if( (sd->class_&MAPID_BASEMASK) == MAPID_TAEKWON ) { + // Better check for class rather than skill to prevent "skill resets" from unsetting this sd->mission_mobid = pc_readglobalreg(sd,"TK_MISSION_ID"); sd->mission_count = pc_readglobalreg(sd,"TK_MISSION_COUNT"); } //SG map and mob read [Komurka] - for(i=0;ifeel_map[i].index = j; sd->feel_map[i].m = map_mapindex2mapid(j); @@ -1179,22 +1175,22 @@ int pc_reg_received(struct map_session_data *sd) if ((i = pc_checkskill(sd,RG_PLAGIARISM)) > 0) { sd->cloneskill_id = pc_readglobalreg(sd,"CLONE_SKILL"); - if (sd->cloneskill_id > 0) { - sd->status.skill[sd->cloneskill_id].id = sd->cloneskill_id; - sd->status.skill[sd->cloneskill_id].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV"); - if (sd->status.skill[sd->cloneskill_id].lv > i) - sd->status.skill[sd->cloneskill_id].lv = i; - sd->status.skill[sd->cloneskill_id].flag = SKILL_FLAG_PLAGIARIZED; + if (sd->cloneskill_id > 0 && (idx = skill->get_index(sd->cloneskill_id))) { + sd->status.skill[idx].id = sd->cloneskill_id; + sd->status.skill[idx].lv = pc_readglobalreg(sd,"CLONE_SKILL_LV"); + if (sd->status.skill[idx].lv > i) + sd->status.skill[idx].lv = i; + sd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED; } } if ((i = pc_checkskill(sd,SC_REPRODUCE)) > 0) { sd->reproduceskill_id = pc_readglobalreg(sd,"REPRODUCE_SKILL"); - if( sd->reproduceskill_id > 0) { - sd->status.skill[sd->reproduceskill_id].id = sd->reproduceskill_id; - sd->status.skill[sd->reproduceskill_id].lv = pc_readglobalreg(sd,"REPRODUCE_SKILL_LV"); - if( i < sd->status.skill[sd->reproduceskill_id].lv) - sd->status.skill[sd->reproduceskill_id].lv = i; - sd->status.skill[sd->reproduceskill_id].flag = SKILL_FLAG_PLAGIARIZED; + if( sd->reproduceskill_id > 0 && (idx = skill->get_index(sd->reproduceskill_id))) { + sd->status.skill[idx].id = sd->reproduceskill_id; + sd->status.skill[idx].lv = pc_readglobalreg(sd,"REPRODUCE_SKILL_LV"); + if( i < sd->status.skill[idx].lv) + sd->status.skill[idx].lv = i; + sd->status.skill[idx].flag = SKILL_FLAG_PLAGIARIZED; } } //Weird... maybe registries were reloaded? @@ -1263,15 +1259,14 @@ static int pc_calc_skillpoint(struct map_session_data* sd) nullpo_ret(sd); for(i=1;i 0) { - inf2 = skill->get_inf2(i); + if( (skill_lv = pc_checkskill2(sd,i)) > 0) { + inf2 = skill_db[i].inf2; if((!(inf2&INF2_QUEST_SKILL) || battle_config.quest_skill_learn) && !(inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) //Do not count wedding/link skills. [Skotlex] ) { if(sd->status.skill[i].flag == SKILL_FLAG_PERMANENT) skill_point += skill_lv; - else - if(sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0) + else if(sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0) skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0); } } @@ -1298,13 +1293,13 @@ int pc_calc_skilltree(struct map_session_data *sd) return 1; } c = pc_class2idx(c); - + for( i = 0; i < MAX_SKILL; i++ ) { if( sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED ) //Don't touch these sd->status.skill[i].id = 0; //First clear skills. /* permanent skills that must be re-checked */ if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED ) { - switch( i ) { + switch( skill_db[i].nameid ) { case NV_TRICKDEAD: if( (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) { sd->status.skill[i].id = 0; @@ -1316,29 +1311,26 @@ int pc_calc_skilltree(struct map_session_data *sd) } } - for( i = 0; i < MAX_SKILL; i++ ) - { + for( i = 0; i < MAX_SKILL; i++ ) { if( sd->status.skill[i].flag != SKILL_FLAG_PERMANENT && sd->status.skill[i].flag != SKILL_FLAG_PERM_GRANTED && sd->status.skill[i].flag != SKILL_FLAG_PLAGIARIZED ) { // Restore original level of skills after deleting earned skills. sd->status.skill[i].lv = (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY) ? 0 : sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0; sd->status.skill[i].flag = SKILL_FLAG_PERMANENT; } - if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && i >= DC_HUMMING && i<= DC_SERVICEFORYOU ) + if( sd->sc.count && sd->sc.data[SC_SPIRIT] && sd->sc.data[SC_SPIRIT]->val2 == SL_BARDDANCER && skill_db[i].nameid >= DC_HUMMING && skill_db[i].nameid <= DC_SERVICEFORYOU ) { //Enable Bard/Dancer spirit linked skills. if( sd->status.sex ) { //Link dancer skills to bard. if( sd->status.skill[i-8].lv < 10 ) continue; - sd->status.skill[i].id = i; + sd->status.skill[i].id = skill_db[i].nameid; sd->status.skill[i].lv = sd->status.skill[i-8].lv; // Set the level to the same as the linking skill sd->status.skill[i].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill - } - else - { //Link bard skills to dancer. + } else { //Link bard skills to dancer. if( sd->status.skill[i].lv < 10 ) continue; - sd->status.skill[i-8].id = i - 8; + sd->status.skill[i-8].id = skill_db[i-8].nameid; sd->status.skill[i-8].lv = sd->status.skill[i].lv; // Set the level to the same as the linking skill sd->status.skill[i-8].flag = SKILL_FLAG_TEMPORARY; // Tag it as a non-savable, non-uppable, bonus skill } @@ -1347,7 +1339,7 @@ int pc_calc_skilltree(struct map_session_data *sd) if( pc_has_permission(sd, PC_PERM_ALL_SKILL) ) { for( i = 0; i < MAX_SKILL; i++ ) { - switch(i) { + switch(skill_db[i].nameid) { /** * Dummy skills must be added here otherwise they'll be displayed in the, * skill tree and since they have no icons they'll give resource errors @@ -1371,20 +1363,19 @@ int pc_calc_skilltree(struct map_session_data *sd) default: break; } - if( skill->get_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL) ) + if( skill_db[i].inf2&(INF2_NPC_SKILL|INF2_GUILD_SKILL) ) continue; //Only skills you can't have are npc/guild ones - if( skill->get_max(i) > 0 ) - sd->status.skill[i].id = i; + if( skill_db[i].max > 0 ) + sd->status.skill[i].id = skill_db[i].nameid; } return 0; } do { flag = 0; - for( i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++ ) - { - int f; - if( sd->status.skill[id].id ) + for( i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++ ) { + int f, idx = skill_tree[c][i].idx; + if( sd->status.skill[idx].id ) continue; //Skill already known. f = 1; @@ -1392,17 +1383,15 @@ int pc_calc_skilltree(struct map_session_data *sd) int j; for(j = 0; j < MAX_PC_SKILL_REQUIRE; j++) { int k; - if((k=skill_tree[c][i].need[j].id)) - { - if (sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED) + if((k=skill_tree[c][i].need[j].id)) { + int idx2 = skill_tree[c][i].need[j].idx; + if (sd->status.skill[idx2].id == 0 || sd->status.skill[idx2].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[idx2].flag == SKILL_FLAG_PLAGIARIZED) k = 0; //Not learned. + else if (sd->status.skill[idx2].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level + k = sd->status.skill[idx2].flag - SKILL_FLAG_REPLACED_LV_0; else - if (sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level - k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0; - else - k = pc_checkskill(sd,k); - if (k < skill_tree[c][i].need[j].lv) - { + k = pc_checkskill2(sd,idx2); + if (k < skill_tree[c][i].need[j].lv) { f = 0; break; } @@ -1411,23 +1400,22 @@ int pc_calc_skilltree(struct map_session_data *sd) if( sd->status.job_level < skill_tree[c][i].joblv ) f = 0; // job level requirement wasn't satisfied } - if( f ) { int inf2; - inf2 = skill->get_inf2(id); - - if(!sd->status.skill[id].lv && ( + inf2 = skill_db[idx].inf2; + + if(!sd->status.skill[idx].lv && ( (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) || inf2&INF2_WEDDING_SKILL || (inf2&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT]) )) continue; //Cannot be learned via normal means. Note this check DOES allows raising already known skills. - sd->status.skill[id].id = id; + sd->status.skill[idx].id = id; if(inf2&INF2_SPIRIT_SKILL) { //Spirit skills cannot be learned, they will only show up on your tree when you get buffed. - sd->status.skill[id].lv = 1; // need to manually specify a skill level - sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill. + sd->status.skill[idx].lv = 1; // need to manually specify a skill level + sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY; //So it is not saved, and tagged as a "bonus" skill. } flag = 1; // skill list has changed, perform another pass } @@ -1443,22 +1431,19 @@ int pc_calc_skilltree(struct map_session_data *sd) - (c > 0) to avoid grant Novice Skill Tree in case of Skill Reset (need more logic) - (sd->status.skill_point == 0) to wait until all skill points are asigned to avoid problems with Job Change quest. */ - for( i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++ ) - { - if( (skill->get_inf2(id)&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) ) + for( i = 0; i < MAX_SKILL_TREE && (id = skill_tree[c][i].id) > 0; i++ ) { + int idx = skill_tree[c][i].idx; + if( (skill_db[idx].inf2&(INF2_QUEST_SKILL|INF2_WEDDING_SKILL)) ) continue; //Do not include Quest/Wedding skills. - if( sd->status.skill[id].id == 0 ) - { - sd->status.skill[id].id = id; - sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill. - } - else if( id != NV_BASIC) - { - sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Remember original level + if( sd->status.skill[idx].id == 0 ) { + sd->status.skill[idx].id = id; + sd->status.skill[idx].flag = SKILL_FLAG_TEMPORARY; // So it is not saved, and tagged as a "bonus" skill. + } else if( id != NV_BASIC) { + sd->status.skill[idx].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[idx].lv; // Remember original level } - sd->status.skill[id].lv = skill->tree_get_max(id, sd->status.class_); + sd->status.skill[idx].lv = skill->tree_get_max(id, sd->status.class_); } } @@ -1483,26 +1468,22 @@ static void pc_check_skilltree(struct map_session_data *sd, int skill_id) c = pc_class2idx(c); do { flag = 0; - for( i = 0; i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0; i++ ) - { - int j, f = 1, k; + for( i = 0; i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0; i++ ) { + int j, f = 1, k, idx = skill_tree[c][i].idx; - if( sd->status.skill[id].id ) //Already learned + if( sd->status.skill[idx].id ) //Already learned continue; - for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ) - { - if( (k = skill_tree[c][i].need[j].id) ) - { - if( sd->status.skill[k].id == 0 || sd->status.skill[k].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[k].flag == SKILL_FLAG_PLAGIARIZED ) + for( j = 0; j < MAX_PC_SKILL_REQUIRE; j++ ) { + if( (k = skill_tree[c][i].need[j].id) ) { + int idx2 = skill_tree[c][i].need[j].idx; + if( sd->status.skill[idx2].id == 0 || sd->status.skill[idx2].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[idx2].flag == SKILL_FLAG_PLAGIARIZED ) k = 0; //Not learned. + else if( sd->status.skill[idx2].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level + k = sd->status.skill[idx2].flag - SKILL_FLAG_REPLACED_LV_0; else - if( sd->status.skill[k].flag >= SKILL_FLAG_REPLACED_LV_0) //Real lerned level - k = sd->status.skill[skill_tree[c][i].need[j].id].flag - SKILL_FLAG_REPLACED_LV_0; - else - k = pc_checkskill(sd,k); - if( k < skill_tree[c][i].need[j].lv ) - { + k = pc_checkskill2(sd,idx2); + if( k < skill_tree[c][i].need[j].lv ) { f = 0; break; } @@ -1513,15 +1494,15 @@ static void pc_check_skilltree(struct map_session_data *sd, int skill_id) if( sd->status.job_level < skill_tree[c][i].joblv ) continue; - j = skill->get_inf2(id); - if( !sd->status.skill[id].lv && ( + j = skill_db[idx].inf2; + if( !sd->status.skill[idx].lv && ( (j&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) || j&INF2_WEDDING_SKILL || (j&INF2_SPIRIT_SKILL && !sd->sc.data[SC_SPIRIT]) ) ) continue; //Cannot be learned via normal means. - sd->status.skill[id].id = id; + sd->status.skill[idx].id = id; flag = 1; } } while(flag); @@ -1533,14 +1514,11 @@ int pc_clean_skilltree(struct map_session_data *sd) { int i; for (i = 0; i < MAX_SKILL; i++){ - if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED) - { + if (sd->status.skill[i].flag == SKILL_FLAG_TEMPORARY || sd->status.skill[i].flag == SKILL_FLAG_PLAGIARIZED) { sd->status.skill[i].id = 0; sd->status.skill[i].lv = 0; sd->status.skill[i].flag = 0; - } - else - if (sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0){ + } else if (sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0) { sd->status.skill[i].lv = sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0; sd->status.skill[i].flag = 0; } @@ -3452,11 +3430,11 @@ int pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type4 * 2 - Like 1, except the level granted can stack with previously learned level. * 3 - Grant skill unconditionally and forever (persistent to job changes and skill resets) *------------------------------------------*/ -int pc_skill(TBL_PC* sd, int id, int level, int flag) -{ +int pc_skill(TBL_PC* sd, int id, int level, int flag) { + uint16 index = 0; nullpo_ret(sd); - if( id <= 0 || id >= MAX_SKILL || skill_db[id].name == NULL) { + if( !(index = skill->get_index(id)) || skill_db[index].name == NULL) { ShowError("pc_skill: Skill with id %d does not exist in the skill database\n", id); return 0; } @@ -3464,56 +3442,56 @@ int pc_skill(TBL_PC* sd, int id, int level, int flag) ShowError("pc_skill: Skill level %d too high. Max lv supported is %d\n", level, MAX_SKILL_LEVEL); return 0; } - if( flag == 2 && sd->status.skill[id].lv + level > MAX_SKILL_LEVEL ) { - ShowError("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d\n", level, MAX_SKILL_LEVEL, sd->status.skill[id].lv); + if( flag == 2 && sd->status.skill[index].lv + level > MAX_SKILL_LEVEL ) { + ShowError("pc_skill: Skill level bonus %d too high. Max lv supported is %d. Curr lv is %d\n", level, MAX_SKILL_LEVEL, sd->status.skill[index].lv); return 0; } switch( flag ){ case 0: //Set skill data overwriting whatever was there before. - sd->status.skill[id].id = id; - sd->status.skill[id].lv = level; - sd->status.skill[id].flag = SKILL_FLAG_PERMANENT; + sd->status.skill[index].id = id; + sd->status.skill[index].lv = level; + sd->status.skill[index].flag = SKILL_FLAG_PERMANENT; if( level == 0 ) { //Remove skill. - sd->status.skill[id].id = 0; + sd->status.skill[index].id = 0; clif->deleteskill(sd,id); } else clif->addskill(sd,id); - if( !skill->get_inf(id) ) //Only recalculate for passive skills. + if( !skill_db[index].inf ) //Only recalculate for passive skills. status_calc_pc(sd, 0); break; case 1: //Item bonus skill. - if( sd->status.skill[id].id == id ) { - if( sd->status.skill[id].lv >= level ) + if( sd->status.skill[index].id == id ) { + if( sd->status.skill[index].lv >= level ) return 0; - if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level. - sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; + if( sd->status.skill[index].flag == SKILL_FLAG_PERMANENT ) //Non-granted skill, store it's level. + sd->status.skill[index].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[index].lv; } else { - sd->status.skill[id].id = id; - sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; + sd->status.skill[index].id = id; + sd->status.skill[index].flag = SKILL_FLAG_TEMPORARY; } - sd->status.skill[id].lv = level; + sd->status.skill[index].lv = level; break; case 2: //Add skill bonus on top of what you had. - if( sd->status.skill[id].id == id ) { - if( sd->status.skill[id].flag == SKILL_FLAG_PERMANENT ) - sd->status.skill[id].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[id].lv; // Store previous level. + if( sd->status.skill[index].id == id ) { + if( sd->status.skill[index].flag == SKILL_FLAG_PERMANENT ) + sd->status.skill[index].flag = SKILL_FLAG_REPLACED_LV_0 + sd->status.skill[index].lv; // Store previous level. } else { - sd->status.skill[id].id = id; - sd->status.skill[id].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill. + sd->status.skill[index].id = id; + sd->status.skill[index].flag = SKILL_FLAG_TEMPORARY; //Set that this is a bonus skill. } - sd->status.skill[id].lv += level; + sd->status.skill[index].lv += level; break; case 3: - sd->status.skill[id].id = id; - sd->status.skill[id].lv = level; - sd->status.skill[id].flag = SKILL_FLAG_PERM_GRANTED; + sd->status.skill[index].id = id; + sd->status.skill[index].lv = level; + sd->status.skill[index].flag = SKILL_FLAG_PERM_GRANTED; if( level == 0 ) { //Remove skill. - sd->status.skill[id].id = 0; + sd->status.skill[index].id = 0; clif->deleteskill(sd,id); } else clif->addskill(sd,id); - if( !skill->get_inf(id) ) //Only recalculate for passive skills. + if( !skill_db[index].inf ) //Only recalculate for passive skills. status_calc_pc(sd, 0); break; default: //Unknown flag? @@ -4959,8 +4937,8 @@ int pc_memo(struct map_session_data* sd, int pos) /*========================================== * Return player sd skill_lv learned for given skill *------------------------------------------*/ -int pc_checkskill(struct map_session_data *sd,uint16 skill_id) -{ +int pc_checkskill(struct map_session_data *sd,uint16 skill_id) { + uint16 index = 0; if(sd == NULL) return 0; if( skill_id >= GD_SKILLBASE && skill_id < GD_MAX ) { struct guild *g; @@ -4968,16 +4946,34 @@ int pc_checkskill(struct map_session_data *sd,uint16 skill_id) if( sd->status.guild_id>0 && (g=sd->guild)!=NULL) return guild_checkskill(g,skill_id); return 0; - } else if(skill_id >= ARRAYLENGTH(sd->status.skill) ) { + } else if(!(index = skill->get_index(skill_id)) || index >= ARRAYLENGTH(sd->status.skill) ) { ShowError("pc_checkskill: Invalid skill id %d (char_id=%d).\n", skill_id, sd->status.char_id); return 0; } - if(sd->status.skill[skill_id].id == skill_id) - return (sd->status.skill[skill_id].lv); + if(sd->status.skill[index].id == skill_id) + return (sd->status.skill[index].lv); return 0; } +int pc_checkskill2(struct map_session_data *sd,uint16 index) { + if(sd == NULL) return 0; + if(index >= ARRAYLENGTH(sd->status.skill) ) { + ShowError("pc_checkskill: Invalid skill index %d (char_id=%d).\n", index, sd->status.char_id); + return 0; + } + if( skill_db[index].nameid >= GD_SKILLBASE && skill_db[index].nameid < GD_MAX ) { + struct guild *g; + + if( sd->status.guild_id>0 && (g=sd->guild)!=NULL) + return guild_checkskill(g,skill_db[index].nameid); + return 0; + } + if(sd->status.skill[index].id == skill_db[index].nameid) + return (sd->status.skill[index].lv); + + return 0; +} /*========================================== * Chk if we still have the correct weapon to continue the skill (actually status) @@ -6048,33 +6044,31 @@ int pc_statusup2(struct map_session_data* sd, int type, int val) * Update skill_lv for player sd * Skill point allocation *------------------------------------------*/ -int pc_skillup(struct map_session_data *sd,uint16 skill_id) -{ +int pc_skillup(struct map_session_data *sd,uint16 skill_id) { + uint16 index = 0; nullpo_ret(sd); - if( skill_id >= GD_SKILLBASE && skill_id < GD_SKILLBASE+MAX_GUILDSKILL ) - { + if( skill_id >= GD_SKILLBASE && skill_id < GD_SKILLBASE+MAX_GUILDSKILL ) { guild_skillup(sd, skill_id); return 0; } - if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE+MAX_HOMUNSKILL && sd->hd ) - { + if( skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE+MAX_HOMUNSKILL && sd->hd ) { merc_hom_skillup(sd->hd, skill_id); return 0; } - if(skill_id >= MAX_SKILL ) + if( !(index = skill->get_index(skill_id)) ) return 0; if( sd->status.skill_point > 0 && - sd->status.skill[skill_id].id && - sd->status.skill[skill_id].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex] - sd->status.skill[skill_id].lv < skill->tree_get_max(skill_id, sd->status.class_) ) + sd->status.skill[index].id && + sd->status.skill[index].flag == SKILL_FLAG_PERMANENT && //Don't allow raising while you have granted skills. [Skotlex] + sd->status.skill[index].lv < skill->tree_get_max(skill_id, sd->status.class_) ) { - sd->status.skill[skill_id].lv++; + sd->status.skill[index].lv++; sd->status.skill_point--; - if( !skill->get_inf(skill_id) ) + if( !skill_db[index].inf ) status_calc_pc(sd,0); // Only recalculate for passive skills. else if( sd->status.skill_point == 0 && (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON) ) pc_calc_skilltree(sd); // Required to grant all TK Ranger skills. @@ -6110,25 +6104,25 @@ int pc_allskillup(struct map_session_data *sd) } } - if (pc_has_permission(sd, PC_PERM_ALL_SKILL)) - { //Get ALL skills except npc/guild ones. [Skotlex] + if (pc_has_permission(sd, PC_PERM_ALL_SKILL)) { //Get ALL skills except npc/guild ones. [Skotlex] //and except SG_DEVIL [Komurka] and MO_TRIPLEATTACK and RG_SNATCHER [ultramage] for(i=0;iget_inf2(i)&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) ) - if ( ( sd->status.skill[i].lv = skill->get_max(i) ) )//Nonexistant skills should return a max of 0 anyway. - sd->status.skill[i].id = i; + if( !(skill_db[i].inf2&(INF2_NPC_SKILL|INF2_GUILD_SKILL)) ) + if ( ( sd->status.skill[i].lv = skill_db[i].max ) )//Nonexistant skills should return a max of 0 anyway. + sd->status.skill[i].id = skill_db[i].nameid; } } } else { int inf2; for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[pc_class2idx(sd->status.class_)][i].id)>0;i++){ - inf2 = skill->get_inf2(id); + int idx = skill_tree[pc_class2idx(sd->status.class_)][i].idx; + inf2 = skill_db[idx].inf2; if ( (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) || (inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL)) || @@ -6136,8 +6130,8 @@ int pc_allskillup(struct map_session_data *sd) ) continue; //Cannot be learned normally. - sd->status.skill[id].id = id; - sd->status.skill[id].lv = skill->tree_get_max(id, sd->status.class_); // celest + sd->status.skill[idx].id = id; + sd->status.skill[idx].lv = skill->tree_get_max(id, sd->status.class_); // celest } } status_calc_pc(sd,0); @@ -6351,26 +6345,27 @@ int pc_resetskill(struct map_session_data* sd, int flag) merc_hom_vaporize(sd, 0); } - for( i = 1; i < MAX_SKILL; i++ ) - { + for( i = 1; i < MAX_SKILL; i++ ) { + uint16 skill_id = 0; lv = sd->status.skill[i].lv; if (lv < 1) continue; - inf2 = skill->get_inf2(i); + inf2 = skill_db[i].inf2; if( inf2&(INF2_WEDDING_SKILL|INF2_SPIRIT_SKILL) ) //Avoid reseting wedding/linker skills. continue; - + + skill_id = skill_db[i].nameid; + // Don't reset trick dead if not a novice/baby - if( i == NV_TRICKDEAD && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) - { + if( skill_id == NV_TRICKDEAD && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) { sd->status.skill[i].lv = 0; sd->status.skill[i].flag = 0; continue; } // do not reset basic skill - if( i == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) + if( skill_id == NV_BASIC && (sd->class_&MAPID_UPPERMASK) != MAPID_NOVICE ) continue; if( sd->status.skill[i].flag == SKILL_FLAG_PERM_GRANTED ) @@ -6379,10 +6374,9 @@ int pc_resetskill(struct map_session_data* sd, int flag) if( flag&4 && !skill_ischangesex(i) ) continue; - if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn ) - { //Only handle quest skills in a special way when you can't learn them manually - if( battle_config.quest_skill_reset && !(flag&2) ) - { //Wipe them + if( inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn ) { + //Only handle quest skills in a special way when you can't learn them manually + if( battle_config.quest_skill_reset && !(flag&2) ) { //Wipe them sd->status.skill[i].lv = 0; sd->status.skill[i].flag = 0; } @@ -6394,8 +6388,7 @@ int pc_resetskill(struct map_session_data* sd, int flag) if( sd->status.skill[i].flag == SKILL_FLAG_REPLACED_LV_0 ) skill_point += (sd->status.skill[i].flag - SKILL_FLAG_REPLACED_LV_0); - if( !(flag&2) ) - {// reset + if( !(flag&2) ) {// reset sd->status.skill[i].lv = 0; sd->status.skill[i].flag = 0; } @@ -6405,8 +6398,7 @@ int pc_resetskill(struct map_session_data* sd, int flag) sd->status.skill_point += skill_point; - if( flag&1 ) - { + if( flag&1 ) { clif->updatestatus(sd,SP_SKILLPOINT); clif->skillinfoblock(sd); status_calc_pc(sd,0); @@ -7339,7 +7331,7 @@ static int jobchange_killclone(struct block_list *bl, va_list ap) int pc_jobchange(struct map_session_data *sd,int job, int upper) { int i, fame_flag=0; - int b_class; + int b_class, idx = 0; nullpo_ret(sd); @@ -7379,10 +7371,11 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) } if(sd->cloneskill_id) { - if( sd->status.skill[sd->cloneskill_id].flag == SKILL_FLAG_PLAGIARIZED ) { - sd->status.skill[sd->cloneskill_id].id = 0; - sd->status.skill[sd->cloneskill_id].lv = 0; - sd->status.skill[sd->cloneskill_id].flag = 0; + idx = skill->get_index(sd->cloneskill_id); + if( sd->status.skill[idx].flag == SKILL_FLAG_PLAGIARIZED ) { + sd->status.skill[idx].id = 0; + sd->status.skill[idx].lv = 0; + sd->status.skill[idx].flag = 0; clif->deleteskill(sd,sd->cloneskill_id); } sd->cloneskill_id = 0; @@ -7391,10 +7384,11 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) } if(sd->reproduceskill_id) { - if( sd->status.skill[sd->reproduceskill_id].flag == SKILL_FLAG_PLAGIARIZED ) { - sd->status.skill[sd->reproduceskill_id].id = 0; - sd->status.skill[sd->reproduceskill_id].lv = 0; - sd->status.skill[sd->reproduceskill_id].flag = 0; + idx = skill->get_index(sd->reproduceskill_id); + if( sd->status.skill[idx].flag == SKILL_FLAG_PLAGIARIZED ) { + sd->status.skill[idx].id = 0; + sd->status.skill[idx].lv = 0; + sd->status.skill[idx].flag = 0; clif->deleteskill(sd,sd->reproduceskill_id); } sd->reproduceskill_id = 0; @@ -9464,24 +9458,22 @@ static bool pc_readdb_skilltree(char* fields[], int columns, int current) //This is to avoid adding two lines for the same skill. [Skotlex] ARR_FIND( 0, MAX_SKILL_TREE, skill_idx, skill_tree[idx][skill_idx].id == 0 || skill_tree[idx][skill_idx].id == skill_id ); - if( skill_idx == MAX_SKILL_TREE ) - { + if( skill_idx == MAX_SKILL_TREE ) { ShowWarning("pc_readdb_skilltree: Unable to load skill %hu into job %d's tree. Maximum number of skills per class has been reached.\n", skill_id, class_); return false; - } - else if(skill_tree[idx][skill_idx].id) - { + } else if(skill_tree[idx][skill_idx].id) { ShowNotice("pc_readdb_skilltree: Overwriting skill %hu for job class %d.\n", skill_id, class_); } skill_tree[idx][skill_idx].id = skill_id; + skill_tree[idx][skill_idx].idx = skill->get_index(skill_id); skill_tree[idx][skill_idx].max = skill_lv; skill_tree[idx][skill_idx].joblv = joblv; - for(i = 0; i < MAX_PC_SKILL_REQUIRE; i++) - { - skill_tree[idx][skill_idx].need[i].id = atoi(fields[i*2+offset]); - skill_tree[idx][skill_idx].need[i].lv = atoi(fields[i*2+offset+1]); + for(i = 0; i < MAX_PC_SKILL_REQUIRE; i++) { + skill_tree[idx][skill_idx].need[i].id = atoi(fields[i*2+offset]); + skill_tree[idx][skill_idx].need[i].idx = skill->get_index(atoi(fields[i*2+offset])); + skill_tree[idx][skill_idx].need[i].lv = atoi(fields[i*2+offset+1]); } return true; } -- cgit v1.2.3-60-g2f50