summaryrefslogtreecommitdiff
path: root/src/map/pc.c
diff options
context:
space:
mode:
authorshennetsind <ind@henn.et>2013-04-27 13:33:10 -0300
committershennetsind <ind@henn.et>2013-04-27 13:33:10 -0300
commit0f4a50d13538c3e5d3ca4d3822f92217c8da0479 (patch)
tree2daf0a99ca0104d6a7fa95637e0377e7a9a0d6ed /src/map/pc.c
parent1f6360f2e157d8eb742a32baed4c5ec7c68c0ef1 (diff)
downloadhercules-0f4a50d13538c3e5d3ca4d3822f92217c8da0479.tar.gz
hercules-0f4a50d13538c3e5d3ca4d3822f92217c8da0479.tar.bz2
hercules-0f4a50d13538c3e5d3ca4d3822f92217c8da0479.tar.xz
hercules-0f4a50d13538c3e5d3ca4d3822f92217c8da0479.zip
Skill ID Processing Overhaul
http://hercules.ws/board/topic/512-skill-id-processing-overhaul/ Signed-off-by: shennetsind <ind@henn.et>
Diffstat (limited to 'src/map/pc.c')
-rw-r--r--src/map/pc.c360
1 files changed, 176 insertions, 184 deletions
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;i<MAX_PC_FEELHATE;i++) //for now - someone need to make reading from txt/sql
- {
+ for(i=0;i<MAX_PC_FEELHATE;i++) { //for now - someone need to make reading from txt/sql
if ((j = pc_readglobalreg(sd,sg_info[i].feel_var))!=0) {
sd->feel_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<MAX_SKILL;i++){
- if( (skill_lv = pc_checkskill(sd,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;i<MAX_SKILL;i++){
- switch( i ) {
+ switch( skill_db[i].nameid ) {
case SG_DEVIL:
case MO_TRIPLEATTACK:
case RG_SNATCHER:
continue;
default:
- if( !(skill->get_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;
}