From 1531c96f8140ffa5c86add64482f3060a650853b Mon Sep 17 00:00:00 2001 From: skotlex Date: Wed, 8 Mar 2006 19:16:56 +0000 Subject: -pc_jobid2mapid and pc_mapid2jobid now return int, and will return -1 when the class couldn't be deciphered. - pc_authok will change you to notice if your current class is invalid. - rewrote pc_jobchange to be much more simple and less of a hassle by using pc_jobid2mapid and pc_mapid2jobid as necessary. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@5520 54d463be-8e91-2dee-dedb-b68131a5f0ec --- Changelog-Trunk.txt | 5 ++ src/map/pc.c | 134 ++++++++++++++++++++++++++++------------------------ src/map/pc.h | 4 +- 3 files changed, 79 insertions(+), 64 deletions(-) diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index d17914f97..8e6348e4e 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -5,6 +5,11 @@ IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. EV GOES INTO TRUNK AND WILL BE MERGED INTO STABLE BY VALARIS AND WIZPUTER. -- VALARIS 2006/03/08 + * Rewrote pc_jobchange to be sane by using the map internal codes instead + of a mesh of complicated nested comparisons. [Skotlex] + * pc_authok will now change you to a novice if your class isn't identified + as a valid one. BACK UP before updating, because.. well, just in case you + start seeing novices filling up your city. [Skotlex] * Mobs will now chase you even if you hit them from outside their range of view. [Skotlex] * Fixed item disappearing from the floor when you attempted to pick it up diff --git a/src/map/pc.c b/src/map/pc.c index 86e1e0e62..c65f9c7af 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -672,8 +672,14 @@ int pc_authok(struct map_session_data *sd, int login_id2, time_t connect_until_t } //Set the map-server used job id. [Skotlex] - sd->class_ = pc_jobid2mapid((unsigned short) sd->status.class_); - + i = pc_jobid2mapid(sd->status.class_); + if (i == -1) { //Invalid class? + if (battle_config.error_log) + ShowError("pc_authok: Invalid class %d for player %s (%d:%d). Class was changed to novice.\n", sd->status.class_, sd->status.name, sd->status.account_id, sd->status.char_id); + sd->status.class_ = JOB_NOVICE; + sd->class_ = MAPID_NOVICE; + } else + sd->class_ = i; //Initializations to null/0 unneeded since map_session_data was filled with 0 upon allocation. // 基本的な初期化 sd->state.connect_new = 1; @@ -976,9 +982,14 @@ int pc_calc_skilltree(struct map_session_data *sd) int c=0; nullpo_retr(0, sd); - - c = pc_mapid2jobid(pc_calc_skilltree_normalize_job(sd), sd->status.sex); - + i = pc_calc_skilltree_normalize_job(sd); + c = pc_mapid2jobid(i, sd->status.sex); + if (c == -1) { //Unable to normalize job?? + if (battle_config.error_log) + ShowError("pc_calc_skilltree: Unable to normalize job %d for character %s (%d:%d)\n", i, sd->status.name, sd->status.account_id, sd->status.char_id); + return 1; + } + for(i=0;istatus.skill[i].flag != 13) //Don't touch plagiarized skills sd->status.skill[i].id=0; //First clear skills. @@ -3900,7 +3911,7 @@ int pc_calc_base_job2 (int b_class) * to the map server's 'makes sense' system. [Skotlex] *------------------------------------------ */ -unsigned short pc_jobid2mapid(unsigned short b_class) +int pc_jobid2mapid(unsigned short b_class) { int class_ = 0; if (b_class >= JOB_BABY && b_class <= JOB_SUPER_BABY) @@ -3986,13 +3997,13 @@ unsigned short pc_jobid2mapid(unsigned short b_class) break; default: ShowError("pc_jobid2mapid: Unrecognized job %d!\n", b_class); - return 0; + return -1; } return class_; } //Reverts the map-style class id to the client-style one. -unsigned short pc_mapid2jobid(unsigned short class_, int sex) { +int pc_mapid2jobid(unsigned short class_, int sex) { switch(class_) { case MAPID_NOVICE: return JOB_NOVICE; @@ -4136,7 +4147,7 @@ unsigned short pc_mapid2jobid(unsigned short class_, int sex) { return JOB_BABY_ROGUE; default: ShowError("pc_mapid2jobid: Unrecognized job %d!\n", class_); - return 0; + return -1; } } @@ -6022,61 +6033,47 @@ int pc_percentheal(struct map_session_data *sd,int hp,int sp) */ int pc_jobchange(struct map_session_data *sd,int job, int upper) { - int i; - int b_class = 0; - //?生や養子の場合の元の職業を算出する - struct pc_base_job s_class = pc_calc_base_job(sd->status.class_); + int i, fame_flag=0; + int b_class; nullpo_retr(0, sd); if (job < 0) return 1; - if (upper < 0 || upper > 2) //現在?生かどうかを判?する - upper = s_class.upper; - - b_class = job; //通常職ならjobそのまんま - if (job < JOB_SUPER_NOVICE) { - if (upper == 1) - b_class += JOB_NOVICE_HIGH; - else if (upper == 2) //養子に結婚はないけどどうせ次で蹴られるからいいや - b_class += JOB_BABY; - } else if (job == JOB_SUPER_NOVICE) { - if (upper == 1) //?生にスパノビは存在しないのでお?り - return 1; - else if (upper == 2) - b_class = JOB_SUPER_BABY; - } else if (job == JOB_GUNSLINGER || job == JOB_NINJA) { - if (upper > 0) - return 1; - } else if (job < JOB_SUPER_BABY-JOB_NOVICE_HIGH+JOB_SUPER_NOVICE+2) { - // Min is SuperNovice +1 -> Becomes Novice High [Skotlex] - // Max is SuperBaby-NoviceHigh+1 -> Becomes Super Baby - b_class += JOB_NOVICE_HIGH - JOB_SUPER_NOVICE -1; - } else if (job >= JOB_TAEKWON && job <= JOB_SOUL_LINKER) { - if (upper > 0) - return 1; - } else if (job < JOB_NOVICE_HIGH || job > JOB_SOUL_LINKER) //Invalid value - return 1; - - job = pc_calc_base_job2 (b_class); // check base class [celest] - if((sd->status.sex == 0 && job == JOB_BARD) || (sd->status.sex == 1 && job == JOB_DANCER)) + //Normalize job. + b_class = pc_jobid2mapid(job); + if (b_class == -1) return 1; - + switch (upper) { + case 1: + b_class|= JOBL_UPPER; + break; + case 2: + b_class|= JOBL_BABY; + break; + } + //This will automatically adjust bard/dancer classes to the correct gender + //That is, if you try to jobchange into dancer, it will turn you to bard. + job = pc_mapid2jobid(b_class, sd->status.sex); + if (job == -1) + return 1; + + if ((unsigned short)b_class == sd->class_) + return 1; //Nothing to change. // check if we are changing from 1st to 2nd job - if ((job >= JOB_KNIGHT && job <= JOB_CRUSADER2) || (job >= JOB_STAR_GLADIATOR && job <= JOB_SOUL_LINKER)) { - if ((s_class.job > JOB_NOVICE && s_class.job < JOB_KNIGHT) || s_class.job == JOB_TAEKWON) + if (b_class&JOBL_2) { + if (!(sd->class_&JOBL_2)) sd->change_level = sd->status.job_level; - else - sd->change_level = 40; + else if (!sd->change_level) + sd->change_level = 40; //Assume 40? } - else - sd->change_level = 0; pc_setglobalreg (sd, "jobchange_level", sd->change_level); - sd->status.class_ = sd->view_class = b_class; - sd->class_ = pc_jobid2mapid(sd->status.class_); + sd->status.class_ = sd->view_class = job; + fame_flag = pc_istop10fame(sd->status.char_id,sd->class_&MAPID_UPPERMASK); + sd->class_ = (unsigned short)b_class; sd->status.job_level=1; sd->status.job_exp=0; clif_updatestatus(sd,SP_JOBLEVEL); @@ -6093,25 +6090,38 @@ int pc_jobchange(struct map_session_data *sd,int job, int upper) if(battle_config.save_clothcolor && sd->status.clothes_color > 0 && - ((sd->view_class != JOB_WEDDING && sd->view_class !=JOB_XMAS) || (sd->view_class==JOB_WEDDING && !battle_config.wedding_ignorepalette) || - (sd->view_class==JOB_XMAS && !battle_config.xmas_ignorepalette))) + ((sd->view_class != JOB_WEDDING && sd->view_class !=JOB_XMAS) || + (sd->view_class==JOB_WEDDING && !battle_config.wedding_ignorepalette) || + (sd->view_class==JOB_XMAS && !battle_config.xmas_ignorepalette))) clif_changelook(&sd->bl,LOOK_CLOTHES_COLOR,sd->status.clothes_color); - if(battle_config.muting_players && sd->status.manner < 0 && battle_config.manner_system) + + if(battle_config.muting_players && sd->status.manner < 0 && battle_config.manner_system) clif_changestatus(&sd->bl,SP_MANNER,sd->status.manner); - if(pc_isriding(sd)) { // remove peco status if changing into invalid class [Valaris] - if(!(pc_checkskill(sd,KN_RIDING))) - pc_setoption(sd,sd->sc.option&~OPTION_RIDING); - else - pc_setriding(sd); - } + + if(pc_isriding(sd)) //Remove Peco Status to prevent display <> class problems. + pc_setoption(sd,sd->sc.option&~OPTION_RIDING); status_calc_pc(sd,0); pc_checkallowskill(sd); pc_equiplookall(sd); clif_equiplist(sd); - chrif_save(sd,0); //Why are we saving it? - chrif_reqfamelist(); + + //if you were previously famous, not anymore. + if (fame_flag) { + chrif_save(sd,0); + chrif_reqfamelist(); + } else if (sd->status.fame > 0) { + //It may be that now they are famous? + switch (sd->class_&MAPID_UPPERMASK) { + case MAPID_BLACKSMITH: + case MAPID_ALCHEMIST: + case MAPID_TAEKWON: + chrif_save(sd,0); + chrif_reqfamelist(); + break; + } + } return 0; } diff --git a/src/map/pc.h b/src/map/pc.h index 78830b6d9..a1b82dd15 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -198,8 +198,8 @@ struct pc_base_job{ struct pc_base_job pc_calc_base_job(int b_class);//転生や養子職の元の職業を返す int pc_calc_base_job2(int b_class); // Celest -unsigned short pc_jobid2mapid(unsigned short b_class); // Skotlex -unsigned short pc_mapid2jobid(unsigned short class_, int sex); // Skotlex +int pc_jobid2mapid(unsigned short b_class); // Skotlex +int pc_mapid2jobid(unsigned short class_, int sex); // Skotlex char * job_name(int class_); -- cgit v1.2.3-70-g09d2