summaryrefslogtreecommitdiff
path: root/src/map/pc.c
diff options
context:
space:
mode:
authorskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-10-24 13:02:00 +0000
committerskotlex <skotlex@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-10-24 13:02:00 +0000
commit339ac6c105cc0548328e15adce1f94d7ecddb0bc (patch)
tree6f58fd8315d917657445a115fc0800c360c873c3 /src/map/pc.c
parent3ecde465534c93315a1f88430129e8400f4d9fe2 (diff)
downloadhercules-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.c86
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);