diff options
author | skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-10-24 13:02:00 +0000 |
---|---|---|
committer | skotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec> | 2007-10-24 13:02:00 +0000 |
commit | 339ac6c105cc0548328e15adce1f94d7ecddb0bc (patch) | |
tree | 6f58fd8315d917657445a115fc0800c360c873c3 /src/map/pc.c | |
parent | 3ecde465534c93315a1f88430129e8400f4d9fe2 (diff) | |
download | hercules-339ac6c105cc0548328e15adce1f94d7ecddb0bc.tar.gz hercules-339ac6c105cc0548328e15adce1f94d7ecddb0bc.tar.bz2 hercules-339ac6c105cc0548328e15adce1f94d7ecddb0bc.tar.xz hercules-339ac6c105cc0548328e15adce1f94d7ecddb0bc.zip |
- added defines JOB_MAX_BASIC and JOB_MAX to mmo.h so the code can know which are the max valid classes.
- @/#jobchange no longer strip your equipment since pc_jobchange removes any unequippables already.
- removed the wasteful define MAX_PC_CLASS and replaced it by the CLASS_COUNT define (which is automatically updated using the previous JOB_MAX* defines) + pc_class2idx function (which converts high class IDs into values that fit in CLASS_COUNT)
- Made status_charge a function rather than a define to get rid of those warnings that have been there since forever.
- Merged the CELL_NOVENDING code (see topic #129209)
- Small check that disables the pet catching process if you try to use another item.
- Added a check to fix a warning and prevent a crash in the npc duplicate check (even though I have no idea what this check is supposed to do, therefore I can't fix it properly other than to avoid the crash)
git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@11572 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/pc.c')
-rw-r--r-- | src/map/pc.c | 86 |
1 files changed, 52 insertions, 34 deletions
diff --git a/src/map/pc.c b/src/map/pc.c index a984796ae..ccd6955a7 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -42,12 +42,12 @@ #define PVP_CALCRANK_INTERVAL 1000 // PVP‡ˆÊŒvŽZ‚ÌŠÔŠu -static unsigned int exp_table[MAX_PC_CLASS][2][MAX_LEVEL]; -static unsigned int max_level[MAX_PC_CLASS][2]; +static unsigned int exp_table[CLASS_COUNT][2][MAX_LEVEL]; +static unsigned int max_level[CLASS_COUNT][2]; static short statp[MAX_LEVEL+1]; // h-files are for declarations, not for implementations... [Shinomori] -struct skill_tree_entry skill_tree[MAX_PC_CLASS][MAX_SKILL_TREE]; +struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE]; // timer for night.day implementation int day_timer_tid; int night_timer_tid; @@ -67,6 +67,15 @@ char motd_text[MOTD_LINE_SIZE][256]; // Message of the day buffer [Valaris] static const char feel_var[3][NAME_LENGTH] = {"PC_FEEL_SUN","PC_FEEL_MOON","PC_FEEL_STAR"}; static const char hate_var[3][NAME_LENGTH] = {"PC_HATE_MOB_SUN","PC_HATE_MOB_MOON","PC_HATE_MOB_STAR"}; +//Converts a class to its array index for CLASS_COUNT defined arrays. +//Note that it does not do a validity check for speed purposes, where parsing +//player input make sure to use a pcdb_checkid first! +int pc_class2idx(int class_) { + if (class_ >= JOB_NOVICE_HIGH) + return class_- JOB_NOVICE_HIGH+JOB_MAX_BASIC; + return class_; +} + int pc_isGM(struct map_session_data* sd) { int i; @@ -934,7 +943,7 @@ int pc_calc_skilltree(struct map_session_data *sd) 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; } - + c = pc_class2idx(c); for(i=0;i<MAX_SKILL;i++){ if (sd->status.skill[i].flag != 13) //Don't touch plagiarized skills sd->status.skill[i].id=0; //First clear skills. @@ -1054,7 +1063,7 @@ static void pc_check_skilltree(struct map_session_data *sd, int skill) ShowError("pc_check_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; } - + c = pc_class2idx(c); do { flag=0; for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[c][i].id)>0;i++){ @@ -3008,7 +3017,7 @@ int pc_isUseitem(struct map_session_data *sd,int n) if(item == NULL) return 0; //Not consumable item - if(item->type != 0 && item->type != 2) + if(item->type != IT_HEALING && item->type != IT_USABLE) return 0; if(!item->script) //if it has no script, you can't really consume it! return 0; @@ -3106,6 +3115,9 @@ int pc_useitem(struct map_session_data *sd,int n) sd->itemid = sd->status.inventory[n].nameid; sd->itemindex = n; + if(sd->catch_target_class != -1) //Abort pet catching. + sd->catch_target_class = -1; + amount = sd->status.inventory[n].amount; script = sd->inventory_data[n]->script; //Check if the item is to be consumed immediately [Skotlex] @@ -4313,12 +4325,12 @@ int pc_gainexp(struct map_session_data *sd, struct block_list *src, unsigned int *------------------------------------------*/ unsigned int pc_maxbaselv(struct map_session_data *sd) { - return max_level[sd->status.class_][0]; + return max_level[pc_class2idx(sd->status.class_)][0]; }; unsigned int pc_maxjoblv(struct map_session_data *sd) { - return max_level[sd->status.class_][1]; + return max_level[pc_class2idx(sd->status.class_)][1]; }; /*========================================== @@ -4331,7 +4343,7 @@ unsigned int pc_nextbaseexp(struct map_session_data *sd) if(sd->status.base_level>=pc_maxbaselv(sd) || sd->status.base_level<=0) return 0; - return exp_table[sd->status.class_][0][sd->status.base_level-1]; + return exp_table[pc_class2idx(sd->status.class_)][0][sd->status.base_level-1]; } /*========================================== @@ -4343,7 +4355,7 @@ unsigned int pc_nextjobexp(struct map_session_data *sd) if(sd->status.job_level>=pc_maxjoblv(sd) || sd->status.job_level<=0) return 0; - return exp_table[sd->status.class_][1][sd->status.job_level-1]; + return exp_table[pc_class2idx(sd->status.class_)][1][sd->status.job_level-1]; } /*========================================== @@ -4584,7 +4596,7 @@ int pc_allskillup(struct map_session_data *sd) else { int inf2; - for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[sd->status.class_][i].id)>0;i++){ + for(i=0;i < MAX_SKILL_TREE && (id=skill_tree[pc_class2idx(sd->status.class_)][i].id)>0;i++){ inf2 = skill_get_inf2(id); if ( (inf2&INF2_QUEST_SKILL && !battle_config.quest_skill_learn) || @@ -7330,7 +7342,7 @@ int pc_readdb(void) } while(fgets(line, sizeof(line), fp)) { - int jobs[MAX_PC_CLASS], job_count, job; + int jobs[CLASS_COUNT], job_count, job, job_id; int type; unsigned int ui,maxlv; char *split[4]; @@ -7339,12 +7351,12 @@ int pc_readdb(void) if (pc_split_str(line,split,4) < 4) continue; - job_count = pc_split_atoi(split[1],jobs,':',MAX_PC_CLASS); + job_count = pc_split_atoi(split[1],jobs,':',CLASS_COUNT); if (job_count < 1) continue; - job = jobs[0]; - if (!pcdb_checkid(job)) { - ShowError("pc_readdb: Invalid job ID %d.\n", job); + job_id = jobs[0]; + if (!pcdb_checkid(job_id)) { + ShowError("pc_readdb: Invalid job ID %d.\n", job_id); continue; } type = atoi(split[2]); @@ -7354,9 +7366,11 @@ int pc_readdb(void) } maxlv = atoi(split[0]); if (maxlv > MAX_LEVEL) { - ShowWarning("pc_readdb: Specified max level %u for job %d is beyond server's limit (%u).\n ", maxlv, job, MAX_LEVEL); + ShowWarning("pc_readdb: Specified max level %u for job %d is beyond server's limit (%u).\n ", maxlv, job_id, MAX_LEVEL); maxlv = MAX_LEVEL; } + + job = jobs[0] = pc_class2idx(job_id); //We send one less and then one more because the last entry in the exp array should hold 0. max_level[job][type] = pc_split_atoui(split[3], exp_table[job][type],',',maxlv-1)+1; //Reverse check in case the array has a bunch of trailing zeros... [Skotlex] @@ -7366,7 +7380,7 @@ int pc_readdb(void) while ((ui = max_level[job][type]) >= 2 && exp_table[job][type][ui-2] <= 0) max_level[job][type]--; if (max_level[job][type] < maxlv) { - ShowWarning("pc_readdb: Specified max %u for job %d, but that job's exp table only goes up to level %u.\n", maxlv, job, max_level[job][type]); + ShowWarning("pc_readdb: Specified max %u for job %d, but that job's exp table only goes up to level %u.\n", maxlv, job_id, max_level[job][type]); ShowInfo("Filling the missing values with the last exp entry.\n"); //Fill the requested values with the last entry. ui = (max_level[job][type] <= 2? 0: max_level[job][type]-2); @@ -7374,26 +7388,28 @@ int pc_readdb(void) exp_table[job][type][ui] = exp_table[job][type][ui-1]; max_level[job][type] = maxlv; } -// ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job, max_level[job][type]); +// ShowDebug("%s - Class %d: %d\n", type?"Job":"Base", job_id, max_level[job][type]); for (i = 1; i < job_count; i++) { - job = jobs[i]; - if (!pcdb_checkid(job)) { - ShowError("pc_readdb: Invalid job ID %d.\n", job); + job_id = jobs[i]; + if (!pcdb_checkid(job_id)) { + ShowError("pc_readdb: Invalid job ID %d.\n", job_id); continue; } + job = pc_class2idx(job_id); memcpy(exp_table[job][type], exp_table[jobs[0]][type], sizeof(exp_table[0][0])); max_level[job][type] = maxlv; -// ShowDebug("%s - Class %d: %u\n", type?"Job":"Base", job, max_level[job][type]); +// ShowDebug("%s - Class %d: %u\n", type?"Job":"Base", job_id, max_level[job][type]); } } fclose(fp); - for (i = 0; i < MAX_PC_CLASS; i++) { + for (i = 0; i < JOB_MAX; i++) { if (!pcdb_checkid(i)) continue; if (i == JOB_WEDDING || i == JOB_XMAS || i == JOB_SUMMER) continue; //Classes that do not need exp tables. - if (!max_level[i][0]) + j = pc_class2idx(i); + if (!max_level[j][0]) ShowWarning("Class %s (%d) does not has a base exp table.\n", job_name(i), i); - if (!max_level[i][1]) + if (!max_level[j][1]) ShowWarning("Class %s (%d) does not has a job exp table.\n", job_name(i), i); } ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n","exp.txt"); @@ -7410,7 +7426,7 @@ int pc_readdb(void) while(fgets(line, sizeof(line), fp)) { char *split[50]; - int f=0, m=3; + int f=0, m=3, idx; if(line[0]=='/' && line[1]=='/') continue; for(j=0,p=line;j<14 && p;j++){ @@ -7425,22 +7441,24 @@ int pc_readdb(void) m++; } // check for bounds [celest] - if (atoi(split[0]) >= MAX_PC_CLASS) + idx = atoi(split[0]); + if(!pcdb_checkid(idx)) continue; + idx = pc_class2idx(idx); k = atoi(split[1]); //This is to avoid adding two lines for the same skill. [Skotlex] - for(j = 0; j < MAX_SKILL_TREE && skill_tree[atoi(split[0])][j].id && skill_tree[atoi(split[0])][j].id != k; j++); + for(j = 0; j < MAX_SKILL_TREE && skill_tree[idx][j].id && skill_tree[idx][j].id != k; j++); if (j == MAX_SKILL_TREE) { ShowWarning("Unable to load skill %d into job %d's tree. Maximum number of skills per class has been reached.\n", k, atoi(split[0])); continue; } - skill_tree[atoi(split[0])][j].id=k; - skill_tree[atoi(split[0])][j].max=atoi(split[2]); - if (f) skill_tree[atoi(split[0])][j].joblv=atoi(split[3]); + skill_tree[idx][j].id=k; + skill_tree[idx][j].max=atoi(split[2]); + if (f) skill_tree[idx][j].joblv=atoi(split[3]); for(k=0;k<5;k++){ - skill_tree[atoi(split[0])][j].need[k].id=atoi(split[k*2+m]); - skill_tree[atoi(split[0])][j].need[k].lv=atoi(split[k*2+m+1]); + skill_tree[idx][j].need[k].id=atoi(split[k*2+m]); + skill_tree[idx][j].need[k].lv=atoi(split[k*2+m+1]); } } fclose(fp); |