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 | |
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
-rw-r--r-- | Changelog-Trunk.txt | 6 | ||||
-rw-r--r-- | src/common/mmo.h | 2 | ||||
-rw-r--r-- | src/map/atcommand.c | 8 | ||||
-rw-r--r-- | src/map/charcommand.c | 8 | ||||
-rw-r--r-- | src/map/map.c | 4 | ||||
-rw-r--r-- | src/map/map.h | 8 | ||||
-rw-r--r-- | src/map/npc.c | 5 | ||||
-rw-r--r-- | src/map/pc.c | 86 | ||||
-rw-r--r-- | src/map/pc.h | 9 | ||||
-rw-r--r-- | src/map/script.c | 2 | ||||
-rw-r--r-- | src/map/status.c | 63 | ||||
-rw-r--r-- | src/map/status.h | 2 | ||||
-rw-r--r-- | src/map/vending.c | 6 |
13 files changed, 127 insertions, 82 deletions
diff --git a/Changelog-Trunk.txt b/Changelog-Trunk.txt index 0890fc636..c0e733aa2 100644 --- a/Changelog-Trunk.txt +++ b/Changelog-Trunk.txt @@ -4,6 +4,12 @@ AS OF SVN REV. 5091, WE ARE NOW USING TRUNK. ALL UNTESTED BUGFIXES/FEATURES GO IF YOU HAVE A WORKING AND TESTED BUGFIX PUT IT INTO STABLE AS WELL AS TRUNK. 2007/10/24 + * @/#jobchange no longer strips your equipment since pc_jobchange removes + any unequippables already. + * Removed the wasteful define MAX_PC_CLASS and replaced it by the + CLASS_COUNT define + pc_class2idx function. This should save a bunch of + memory from the map server. + * Merged the CELL_NOVENDING code (see topic #129209) [Skotlex] * Increased the max. send buffer size to 5M since 1M is not enough * Updated vs7 and vs6 project files * Added upgrade_svn11548.sql to convert the mail table to new format diff --git a/src/common/mmo.h b/src/common/mmo.h index 171c6c3de..e9f3a80a5 100644 --- a/src/common/mmo.h +++ b/src/common/mmo.h @@ -475,6 +475,7 @@ enum { JOB_NINJA, JOB_XMAS, JOB_SUMMER, + JOB_MAX_BASIC, JOB_NOVICE_HIGH = 4001, JOB_SWORDMAN_HIGH, @@ -527,6 +528,7 @@ enum { JOB_STAR_GLADIATOR, JOB_STAR_GLADIATOR2, JOB_SOUL_LINKER, + JOB_MAX, }; // sanity checks... diff --git a/src/map/atcommand.c b/src/map/atcommand.c index 5ed008419..045448888 100644 --- a/src/map/atcommand.c +++ b/src/map/atcommand.c @@ -2175,14 +2175,8 @@ int atcommand_jobchange(const int fd, struct map_session_data* sd, const char* c if (job == 37 ||job == 45) return 0; - if ((job >= 0 && job < MAX_PC_CLASS)) + if (pcdb_checkid(job)) { - int j; - - for (j=0; j < MAX_INVENTORY; j++) { - if(sd->status.inventory[j].nameid>0 && sd->status.inventory[j].equip!=0) - pc_unequipitem(sd, j, 3); - } if (pc_jobchange(sd, job, upper) == 0) clif_displaymessage(fd, msg_txt(12)); // Your job has been changed. else { diff --git a/src/map/charcommand.c b/src/map/charcommand.c index f2747e6e1..c2689b8e8 100644 --- a/src/map/charcommand.c +++ b/src/map/charcommand.c @@ -421,7 +421,7 @@ int charcommand_jobchange(const int fd, struct map_session_data* sd, const char* { char character[100]; struct map_session_data* pl_sd; - int job = 0, upper = -1, j = 0; + int job = 0, upper = -1; memset(character, '\0', sizeof(character)); @@ -462,15 +462,11 @@ int charcommand_jobchange(const int fd, struct map_session_data* sd, const char* return -1; } - if (job < 0 || job > MAX_PC_CLASS) { + if (!pcdb_checkid(job)) { clif_displaymessage(fd, msg_txt(49)); // Invalid job ID. return -1; } - for (j=0; j < MAX_INVENTORY; j++) { - if(pl_sd->status.inventory[j].nameid>0 && pl_sd->status.inventory[j].equip!=0) - pc_unequipitem(pl_sd, j, 3); - } if (pc_jobchange(pl_sd, job, upper) != 0) { clif_displaymessage(fd, msg_txt(192)); // Impossible to change the character's job. return -1; diff --git a/src/map/map.c b/src/map/map.c index 929ee7c36..43a05810c 100644 --- a/src/map/map.c +++ b/src/map/map.c @@ -2307,6 +2307,8 @@ int map_getcellp(struct map_data* m,int x,int y,cell_t cellchk) return (type2&CELL_REGEN); case CELL_CHKICEWALL: return (type2&CELL_ICEWALL); + case CELL_CHKNOVENDING: + return (type2&CELL_NOVENDING); default: return 0; } @@ -2336,6 +2338,8 @@ void map_setcell(int m,int x,int y,int cell) case CELL_SETLANDPROTECTOR: map[m].cell[j] |= CELL_LANDPROTECTOR; break; case CELL_CLRLANDPROTECTOR: map[m].cell[j] &= ~CELL_LANDPROTECTOR; break; case CELL_SETREGEN: map[m].cell[j] |= CELL_REGEN; break; + case CELL_SETNOVENDING: map[m].cell[j] |= CELL_NOVENDING; break; + case CELL_CLRNOVENDING: map[m].cell[j] &= ~CELL_NOVENDING; break; default: map[m].gat[j] = cell; break; diff --git a/src/map/map.h b/src/map/map.h index b0f823d8e..896af5507 100644 --- a/src/map/map.h +++ b/src/map/map.h @@ -28,10 +28,6 @@ // but is not the official behaviour. //#define CIRCULAR_AREA -#define MAX_PC_CLASS 4050 -#define PC_CLASS_BASE 0 -#define PC_CLASS_BASE2 (PC_CLASS_BASE + 4001) -#define PC_CLASS_BASE3 (PC_CLASS_BASE2 + 22) #define MAX_NPC_PER_MAP 512 #define BLOCK_SIZE 8 #define AREA_SIZE battle_config.area_size @@ -1219,6 +1215,7 @@ enum _look { #define CELL_SAFETYWALL 0x8 #define CELL_LANDPROTECTOR 0x10 #define CELL_BASILICA 0x20 +#define CELL_NOVENDING 0x40 #define CELL_ICEWALL 0x80 /* * map_getcell()で使用されるフラグ @@ -1241,6 +1238,7 @@ typedef enum { CELL_CHKLANDPROTECTOR, CELL_CHKICEWALL, CELL_CHKSTACK, + CELL_CHKNOVENDING, } cell_t; // map_setcell()で使用されるフラグ enum { @@ -1257,6 +1255,8 @@ enum { CELL_CLRSAFETYWALL, CELL_SETICEWALL, CELL_CLRICEWALL, + CELL_SETNOVENDING, + CELL_CLRNOVENDING, }; extern struct map_data map[]; diff --git a/src/map/npc.c b/src/map/npc.c index 87ceb8afb..bbd0363e1 100644 --- a/src/map/npc.c +++ b/src/map/npc.c @@ -1463,6 +1463,11 @@ static void npc_parsename(struct npc_data* nd, const char* name, const char* sta char this_mapname[32]; char other_mapname[32]; int i = 0; + + //TODO: the debug message is broken, if nd->exname == NULL + //dnd is left uninitialized, and then is printed as that! + if (*nd->exname == '\0') + dnd = nd; //Dumb anti-crash measure since I am not sure what this piece of code is supposed to do. do { ++i; 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順位計算の間隔 -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); diff --git a/src/map/pc.h b/src/map/pc.h index 442c9e188..05368d6d5 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -7,12 +7,14 @@ #include "../common/mmo.h" // JOB_*, MAX_FAME_LIST, struct fame_list, struct mmo_charstatus #include "../common/timer.h" // INVALID_TIMER #include "battle.h" // battle_config -#include "map.h" // MAX_PC_CLASS, struct map_session_data +#include "map.h" // struct map_session_data #include "status.h" // OPTION_* #include "unit.h" // unit_stop_attack(), unit_stop_walking() //Update this max as necessary. 54 is the value needed for Super Baby currently #define MAX_SKILL_TREE 54 +//Total number of classes (for data storage) +#define CLASS_COUNT (JOB_MAX - JOB_NOVICE_HIGH + JOB_MAX_BASIC) enum { W_FIST, //Bare hands @@ -115,8 +117,9 @@ enum { #define pc_check_weapontype(sd, type) ((type)&((sd)->status.weapon < MAX_WEAPON_TYPE? \ 1<<(sd)->status.weapon:(1<<(sd)->weapontype1)|(1<<(sd)->weapontype2))) //Checks if the given class value corresponds to a player class. [Skotlex] -#define pcdb_checkid(class_) (class_ <= JOB_SUMMER || (class_ >= JOB_NOVICE_HIGH && class_ <= JOB_SOUL_LINKER)) +#define pcdb_checkid(class_) (class_ < JOB_MAX_BASIC || (class_ >= JOB_NOVICE_HIGH && class_ < JOB_MAX)) +int pc_class2idx(int class_); int pc_isGM(struct map_session_data *sd); int pc_getrefinebonus(int lv,int type); int pc_can_give_items(int level); //[Lupus] @@ -289,7 +292,7 @@ struct skill_tree_entry { unsigned char lv; } need[5]; }; // Celest -extern struct skill_tree_entry skill_tree[MAX_PC_CLASS][MAX_SKILL_TREE]; +extern struct skill_tree_entry skill_tree[CLASS_COUNT][MAX_SKILL_TREE]; int pc_read_gm_account(int fd); void pc_setinvincibletimer(struct map_session_data* sd, int val); diff --git a/src/map/script.c b/src/map/script.c index 0e4144605..d00d5f700 100644 --- a/src/map/script.c +++ b/src/map/script.c @@ -5331,7 +5331,7 @@ BUILDIN_FUNC(jobchange) if( script_hasdata(st,3) ) upper=script_getnum(st,3); - if ((job >= 0 && job < MAX_PC_CLASS)) + if (pcdb_checkid(job)) { pc_jobchange(script_rid2sd(st),job, upper); if(use_irc && irc_announce_jobchange_flag) diff --git a/src/map/status.c b/src/map/status.c index 02c2bf7b3..ce0403885 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -45,16 +45,16 @@ int StatusIconChangeTable[SC_MAX]; //Stores the icon that should be associated t int StatusSkillChangeTable[SC_MAX]; //Stores the skill that should be considered associated to this status change. unsigned long StatusChangeFlagTable[SC_MAX]; //Stores the flag specifying what this SC changes. -static int max_weight_base[MAX_PC_CLASS]; -static int hp_coefficient[MAX_PC_CLASS]; -static int hp_coefficient2[MAX_PC_CLASS]; -static int hp_sigma_val[MAX_PC_CLASS][MAX_LEVEL+1]; -static int sp_coefficient[MAX_PC_CLASS]; -static int aspd_base[MAX_PC_CLASS][MAX_WEAPON_TYPE]; //[blackhole89] +static int max_weight_base[CLASS_COUNT]; +static int hp_coefficient[CLASS_COUNT]; +static int hp_coefficient2[CLASS_COUNT]; +static int hp_sigma_val[CLASS_COUNT][MAX_LEVEL+1]; +static int sp_coefficient[CLASS_COUNT]; +static int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE]; //[blackhole89] static int refinebonus[MAX_REFINE_BONUS][3]; // 精錬ボーナステーブル(refine_db.txt) int percentrefinery[5][MAX_REFINE+1]; // 精錬成功率(refine_db.txt) static int atkmods[3][MAX_WEAPON_TYPE]; // 武器ATKサイズ修正(size_fix.txt) -static char job_bonus[MAX_PC_CLASS][MAX_LEVEL]; +static char job_bonus[CLASS_COUNT][MAX_LEVEL]; static struct status_data dummy_status; int current_equip_item_index; //Contains inventory index of an equipped item. To pass it into the EQUP_SCRIPT [Lupus] @@ -584,6 +584,13 @@ int status_set_sp(struct block_list *bl, unsigned int sp, int flag) return status_zap(bl, 0, status->sp - sp); } +int status_charge(struct block_list* bl, int hp, int sp) +{ + if(!((bl)->type&BL_CONSUME)) + return hp+sp; //Assume all was charged so there are no 'not enough' fails. + return status_damage(NULL, bl, hp, sp, 0, 3); +} + //Inflicts damage on the target with the according walkdelay. //If flag&1, damage is passive and does not triggers cancelling status changes. //If flag&2, fail if target does not has enough to substract. @@ -1189,8 +1196,8 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat // base weapon delay amotion = (sd->status.weapon < MAX_WEAPON_TYPE) - ? (aspd_base[sd->status.class_][sd->status.weapon]) // single weapon - : (aspd_base[sd->status.class_][sd->weapontype1] + aspd_base[sd->status.class_][sd->weapontype2])*7/10; // dual-wield + ? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon + : (aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1] + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2])*7/10; // dual-wield // percentual delay reduction from stats amotion-= amotion * (4*status->agi + status->dex)/1000; @@ -1517,7 +1524,7 @@ static void status_calc_sigma(void) { int i,j; - for(i = 0; i < MAX_PC_CLASS; i++) + for(i = 0; i < CLASS_COUNT; i++) { unsigned int k = 0; hp_sigma_val[i][0] = hp_sigma_val[i][1] = 0; @@ -1540,8 +1547,8 @@ static void status_calc_sigma(void) /// f(x) = 35 + x*(A + B*C/D) + sum(i=2..x){ i*C/D } static unsigned int status_base_pc_maxhp(struct map_session_data* sd, struct status_data* status) { - unsigned int val; - val = 35 + sd->status.base_level*hp_coefficient2[sd->status.class_]/100 + hp_sigma_val[sd->status.class_][sd->status.base_level]; + unsigned int val = pc_class2idx(sd->status.class_); + val = 35 + sd->status.base_level*hp_coefficient2[val]/100 + hp_sigma_val[val][sd->status.base_level]; if((sd->class_&MAPID_UPPERMASK) == MAPID_NINJA || (sd->class_&MAPID_UPPERMASK) == MAPID_GUNSLINGER) val += 100; //Since their HP can't be approximated well enough without this. @@ -1563,7 +1570,7 @@ static unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct sta { unsigned int val; - val = 10 + sd->status.base_level*sp_coefficient[sd->status.class_]/100; + val = 10 + sd->status.base_level*sp_coefficient[pc_class2idx(sd->status.class_)]/100; val += val * status->int_/100; if (sd->class_&JOBL_UPPER) @@ -1606,7 +1613,7 @@ int status_calc_pc(struct map_session_data* sd,int first) pc_calc_skilltree(sd); // スキルツリ?の計算 - sd->max_weight = max_weight_base[sd->status.class_]+sd->status.str*300; + sd->max_weight = max_weight_base[pc_class2idx(sd->status.class_)]+sd->status.str*300; if(first&1) { //Load Hp/SP from char-received data. @@ -1959,10 +1966,11 @@ int status_calc_pc(struct map_session_data* sd,int first) // ----- STATS CALCULATION ----- // Job bonuses + index = pc_class2idx(sd->status.class_); for(i=0;i<(int)sd->status.job_level && i<MAX_LEVEL;i++){ - if(!job_bonus[sd->status.class_][i]) + if(!job_bonus[index][i]) continue; - switch(job_bonus[sd->status.class_][i]) { + switch(job_bonus[index][i]) { case 1: status->str++; break; case 2: status->agi++; break; case 3: status->vit++; break; @@ -7296,7 +7304,7 @@ static int status_natural_heal_timer(int tid,unsigned int tick,int id,int data) int status_readdb(void) { - int i,j; + int i,j,class_; FILE *fp; char line[1024], path[1024],*p; @@ -7323,15 +7331,16 @@ int status_readdb(void) ShowDebug("%s: Not enough columns at line %d\n", path, i); continue; } - if(atoi(split[0])>=MAX_PC_CLASS) + class_ = atoi(split[0]); + if(!pcdb_checkid(class_)) continue; - - max_weight_base[atoi(split[0])]=atoi(split[1]); - hp_coefficient[atoi(split[0])]=atoi(split[2]); - hp_coefficient2[atoi(split[0])]=atoi(split[3]); - sp_coefficient[atoi(split[0])]=atoi(split[4]); + class_ = pc_class2idx(class_); + max_weight_base[class_]=atoi(split[1]); + hp_coefficient[class_]=atoi(split[2]); + hp_coefficient2[class_]=atoi(split[3]); + sp_coefficient[class_]=atoi(split[4]); for(j=0;j<MAX_WEAPON_TYPE;j++) - aspd_base[atoi(split[0])][j]=atoi(split[j+5]); + aspd_base[class_][j]=atoi(split[j+5]); } fclose(fp); ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",path); @@ -7353,10 +7362,12 @@ int status_readdb(void) p=strchr(p,','); if(p) *p++=0; } - if(atoi(split[0])>=MAX_PC_CLASS) + class_ = atoi(split[0]); + if(!pcdb_checkid(class_)) continue; + class_ = pc_class2idx(class_); for(i=1;i<j && split[i];i++) - job_bonus[atoi(split[0])][i-1]=atoi(split[i]); + job_bonus[class_][i-1]=atoi(split[i]); } fclose(fp); ShowStatus("Done reading '"CL_WHITE"%s"CL_RESET"'.\n",path); diff --git a/src/map/status.h b/src/map/status.h index 50ed1eb44..a3c03557d 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -579,7 +579,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp,int sp //Define for standard HP/SP damage triggers. #define status_zap(bl, hp, sp) status_damage(NULL, bl, hp, sp, 0, 1) //Define for standard HP/SP skill-related cost triggers (mobs require no HP/SP to use skills) -#define status_charge(bl, hp, sp) (!((bl)->type&BL_CONSUME) || status_damage(NULL, bl, hp, sp, 0, 3)) +int status_charge(struct block_list* bl, int hp, int sp); int status_percent_change(struct block_list *src,struct block_list *target,signed char hp_rate, signed char sp_rate, int flag); //Easier handling of status_percent_change #define status_percent_heal(bl, hp_rate, sp_rate) status_percent_change(NULL, bl, -(hp_rate), -(sp_rate), 1) diff --git a/src/map/vending.c b/src/map/vending.c index 7c0024eb3..45ec08edf 100644 --- a/src/map/vending.c +++ b/src/map/vending.c @@ -236,6 +236,12 @@ void vending_openvending(struct map_session_data* sd, const char* message, bool clif_skill_fail(sd, MC_VENDING, 0, 0); return; } + + if ( map_getcell(sd->bl.m,sd->bl.x,sd->bl.y,CELL_CHKNOVENDING) ) + { + clif_displaymessage (sd->fd, msg_txt(276)); + return; //Can't vend in novending mapflag maps. + } // check number of items in shop if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) |