From fb88a56b9519adedfca06085de6c2ccc5da72582 Mon Sep 17 00:00:00 2001 From: malufett Date: Fri, 27 Mar 2015 11:07:54 +0800 Subject: Hercules 'job_db1.txt' Redesign -Initial and for review Signed-off-by: malufett --- src/map/pc.c | 310 +++++++++++++++++++++--------------------- src/map/pc.h | 2 + src/map/skill.c | 4 +- src/map/status.c | 405 +++++++++++++++++++++++++++++++++++-------------------- src/map/status.h | 13 +- src/map/unit.c | 9 +- 6 files changed, 431 insertions(+), 312 deletions(-) (limited to 'src/map') diff --git a/src/map/pc.c b/src/map/pc.c index f28a4cfdd..dcb02d5b4 100644 --- a/src/map/pc.c +++ b/src/map/pc.c @@ -5868,6 +5868,138 @@ const char* job_name(int class_) } } +int pc_check_job_name(const char *name) { + int i, len; + struct { + const char *name; + int id; + } names[] = { + { "Novice", JOB_NOVICE }, + { "Swordsman", JOB_SWORDMAN }, + { "Magician", JOB_MAGE }, + { "Archer", JOB_ARCHER }, + { "Acolyte", JOB_ACOLYTE }, + { "Merchant", JOB_MERCHANT }, + { "Thief", JOB_THIEF }, + { "Knight", JOB_KNIGHT }, + { "Priest", JOB_PRIEST }, + { "Wizard", JOB_WIZARD }, + { "Blacksmith", JOB_BLACKSMITH }, + { "Hunter", JOB_HUNTER }, + { "Assassin", JOB_ASSASSIN }, + { "Crusader", JOB_CRUSADER }, + { "Monk", JOB_MONK }, + { "Sage", JOB_SAGE }, + { "Rogue", JOB_ROGUE }, + { "Alchemist", JOB_ALCHEMIST }, + { "Bard", JOB_BARD }, + { "Dancer", JOB_DANCER }, + { "Super_Novice", JOB_SUPER_NOVICE }, + { "Gunslinger", JOB_GUNSLINGER }, + { "Ninja", JOB_NINJA }, + { "Novice_High", JOB_NOVICE_HIGH }, + { "Swordsman_High", JOB_SWORDMAN_HIGH }, + { "Magician_High", JOB_MAGE_HIGH }, + { "Archer_High", JOB_ARCHER_HIGH }, + { "Acolyte_High", JOB_ACOLYTE_HIGH }, + { "Merchant_High", JOB_MERCHANT_HIGH }, + { "Thief_High", JOB_THIEF_HIGH }, + { "Lord_Knight", JOB_LORD_KNIGHT }, + { "High_Priest", JOB_HIGH_PRIEST }, + { "High_Wizard", JOB_HIGH_WIZARD }, + { "Whitesmith", JOB_WHITESMITH }, + { "Sniper", JOB_SNIPER }, + { "Assassin_Cross", JOB_ASSASSIN_CROSS }, + { "Paladin", JOB_PALADIN }, + { "Champion", JOB_CHAMPION }, + { "Professor", JOB_PROFESSOR }, + { "Stalker", JOB_STALKER }, + { "Creator", JOB_CREATOR }, + { "Clown", JOB_CLOWN }, + { "Gypsy", JOB_GYPSY }, + { "Baby_Novice", JOB_BABY }, + { "Baby_Swordsman", JOB_BABY_SWORDMAN }, + { "Baby_Magician", JOB_BABY_MAGE }, + { "Baby_Archer", JOB_BABY_ARCHER }, + { "Baby_Acolyte", JOB_BABY_ACOLYTE }, + { "Baby_Merchant", JOB_BABY_MERCHANT }, + { "Baby_Thief", JOB_BABY_THIEF }, + { "Baby_Knight", JOB_BABY_KNIGHT }, + { "Baby_Priest", JOB_BABY_PRIEST }, + { "Baby_Wizard", JOB_BABY_WIZARD }, + { "Baby_Blacksmith", JOB_BABY_BLACKSMITH }, + { "Baby_Hunter", JOB_BABY_HUNTER }, + { "Baby_Assassin", JOB_BABY_ASSASSIN }, + { "Baby_Crusader", JOB_BABY_CRUSADER }, + { "Baby_Monk", JOB_BABY_MONK }, + { "Baby_Sage", JOB_BABY_SAGE }, + { "Baby_Rogue", JOB_BABY_ROGUE }, + { "Baby_Alchemist", JOB_BABY_ALCHEMIST }, + { "Baby_Bard", JOB_BABY_BARD }, + { "Baby_Dancer", JOB_BABY_DANCER }, + { "Super_Baby", JOB_SUPER_BABY }, + { "Taekwon", JOB_TAEKWON }, + { "Star_Gladiator", JOB_STAR_GLADIATOR }, + { "Soul_Linker", JOB_SOUL_LINKER }, + { "Gangsi", JOB_GANGSI }, + { "Death_Knight", JOB_DEATH_KNIGHT }, + { "Dark_Collector", JOB_DARK_COLLECTOR }, + { "Rune_Knight", JOB_RUNE_KNIGHT }, + { "Warlock", JOB_WARLOCK }, + { "Ranger", JOB_RANGER }, + { "Arch_Bishop", JOB_ARCH_BISHOP }, + { "Mechanic", JOB_MECHANIC }, + { "Guillotine_Cross", JOB_GUILLOTINE_CROSS }, + { "Rune_Knight_Trans", JOB_RUNE_KNIGHT_T }, + { "Warlock_Trans", JOB_WARLOCK_T }, + { "Ranger_Trans", JOB_RANGER_T }, + { "Arch_Bishop_Trans", JOB_ARCH_BISHOP_T }, + { "Mechanic_Trans", JOB_MECHANIC_T }, + { "Guillotine_Cross_Trans", JOB_GUILLOTINE_CROSS_T }, + { "Royal_Guard", JOB_ROYAL_GUARD }, + { "Sorcerer", JOB_SORCERER }, + { "Minstrel", JOB_MINSTREL }, + { "Wanderer", JOB_WANDERER }, + { "Sura", JOB_SURA }, + { "Genetic", JOB_GENETIC }, + { "Shadow_Chaser", JOB_SHADOW_CHASER }, + { "Royal_Guard_Trans", JOB_ROYAL_GUARD_T }, + { "Sorcerer_Trans", JOB_SORCERER_T }, + { "Minstrel_Trans", JOB_MINSTREL_T }, + { "Wanderer_Trans", JOB_WANDERER_T }, + { "Sura_Trans", JOB_SURA_T }, + { "Genetic_Trans", JOB_GENETIC_T }, + { "Shadow_Chaser_Trans", JOB_SHADOW_CHASER_T }, + { "Baby_Rune_Knight", JOB_BABY_RUNE }, + { "Baby_Warlock", JOB_BABY_WARLOCK }, + { "Baby_Ranger", JOB_BABY_RANGER }, + { "Baby_Arch_Bishop", JOB_BABY_BISHOP }, + { "Baby_Mechanic", JOB_BABY_MECHANIC }, + { "Baby_Guillotine_Cross", JOB_BABY_CROSS }, + { "Baby_Royal_Guard", JOB_BABY_GUARD }, + { "Baby_Sorcerer", JOB_BABY_SORCERER }, + { "Baby_Minstrel", JOB_BABY_MINSTREL }, + { "Baby_Wanderer", JOB_BABY_WANDERER }, + { "Baby_Sura", JOB_BABY_SURA }, + { "Baby_Genetic", JOB_BABY_GENETIC }, + { "Baby_Shadow_Chaser", JOB_BABY_CHASER }, + { "Expanded_Super_Novice", JOB_SUPER_NOVICE_E }, + { "Expanded_Super_Baby", JOB_SUPER_BABY_E }, + { "Kagerou", JOB_KAGEROU }, + { "Oboro", JOB_OBORO }, + { "Rebellion", JOB_REBELLION }, + }; + + len = ARRAYLENGTH(names); + + ARR_FIND(0, len, i, strcmpi(names[i].name, name) == 0); + + if ( i == len ) + return -1; + + return names[i].id; +} + int pc_follow_timer(int tid, int64 tick, int id, intptr_t data) { struct map_session_data *sd; struct block_list *tbl; @@ -10044,148 +10176,24 @@ void pc_read_skill_tree(void) { int i = 0, jnamelen = 0; struct s_mapiterator *iter; struct map_session_data *sd; - struct { - const char *name; - int id; - } jnames[] = { - { "Novice", JOB_NOVICE }, - { "Swordsman", JOB_SWORDMAN }, - { "Magician", JOB_MAGE }, - { "Archer", JOB_ARCHER }, - { "Acolyte", JOB_ACOLYTE }, - { "Merchant", JOB_MERCHANT }, - { "Thief", JOB_THIEF }, - { "Knight", JOB_KNIGHT }, - { "Priest", JOB_PRIEST }, - { "Wizard", JOB_WIZARD }, - { "Blacksmith", JOB_BLACKSMITH }, - { "Hunter", JOB_HUNTER }, - { "Assassin", JOB_ASSASSIN }, - { "Crusader", JOB_CRUSADER }, - { "Monk", JOB_MONK }, - { "Sage", JOB_SAGE }, - { "Rogue", JOB_ROGUE }, - { "Alchemist", JOB_ALCHEMIST }, - { "Bard", JOB_BARD }, - { "Dancer", JOB_DANCER }, - { "Super_Novice", JOB_SUPER_NOVICE }, - { "Gunslinger", JOB_GUNSLINGER }, - { "Ninja", JOB_NINJA }, - { "Novice_High", JOB_NOVICE_HIGH }, - { "Swordsman_High", JOB_SWORDMAN_HIGH }, - { "Magician_High", JOB_MAGE_HIGH }, - { "Archer_High", JOB_ARCHER_HIGH }, - { "Acolyte_High", JOB_ACOLYTE_HIGH }, - { "Merchant_High", JOB_MERCHANT_HIGH }, - { "Thief_High", JOB_THIEF_HIGH }, - { "Lord_Knight", JOB_LORD_KNIGHT }, - { "High_Priest", JOB_HIGH_PRIEST }, - { "High_Wizard", JOB_HIGH_WIZARD }, - { "Whitesmith", JOB_WHITESMITH }, - { "Sniper", JOB_SNIPER }, - { "Assassin_Cross", JOB_ASSASSIN_CROSS }, - { "Paladin", JOB_PALADIN }, - { "Champion", JOB_CHAMPION }, - { "Professor", JOB_PROFESSOR }, - { "Stalker", JOB_STALKER }, - { "Creator", JOB_CREATOR }, - { "Clown", JOB_CLOWN }, - { "Gypsy", JOB_GYPSY }, - { "Baby_Novice", JOB_BABY }, - { "Baby_Swordsman", JOB_BABY_SWORDMAN }, - { "Baby_Magician", JOB_BABY_MAGE }, - { "Baby_Archer", JOB_BABY_ARCHER }, - { "Baby_Acolyte", JOB_BABY_ACOLYTE }, - { "Baby_Merchant", JOB_BABY_MERCHANT }, - { "Baby_Thief", JOB_BABY_THIEF }, - { "Baby_Knight", JOB_BABY_KNIGHT }, - { "Baby_Priest", JOB_BABY_PRIEST }, - { "Baby_Wizard", JOB_BABY_WIZARD }, - { "Baby_Blacksmith", JOB_BABY_BLACKSMITH }, - { "Baby_Hunter", JOB_BABY_HUNTER }, - { "Baby_Assassin", JOB_BABY_ASSASSIN }, - { "Baby_Crusader", JOB_BABY_CRUSADER }, - { "Baby_Monk", JOB_BABY_MONK }, - { "Baby_Sage", JOB_BABY_SAGE }, - { "Baby_Rogue", JOB_BABY_ROGUE }, - { "Baby_Alchemist", JOB_BABY_ALCHEMIST }, - { "Baby_Bard", JOB_BABY_BARD }, - { "Baby_Dancer", JOB_BABY_DANCER }, - { "Super_Baby", JOB_SUPER_BABY }, - { "Taekwon", JOB_TAEKWON }, - { "Star_Gladiator", JOB_STAR_GLADIATOR }, - { "Soul_Linker", JOB_SOUL_LINKER }, - { "Gangsi", JOB_GANGSI }, - { "Death_Knight", JOB_DEATH_KNIGHT }, - { "Dark_Collector", JOB_DARK_COLLECTOR }, - { "Rune_Knight", JOB_RUNE_KNIGHT }, - { "Warlock", JOB_WARLOCK }, - { "Ranger", JOB_RANGER }, - { "Arch_Bishop", JOB_ARCH_BISHOP }, - { "Mechanic", JOB_MECHANIC }, - { "Guillotine_Cross", JOB_GUILLOTINE_CROSS }, - { "Rune_Knight_Trans", JOB_RUNE_KNIGHT_T }, - { "Warlock_Trans", JOB_WARLOCK_T }, - { "Ranger_Trans", JOB_RANGER_T }, - { "Arch_Bishop_Trans", JOB_ARCH_BISHOP_T }, - { "Mechanic_Trans", JOB_MECHANIC_T }, - { "Guillotine_Cross_Trans", JOB_GUILLOTINE_CROSS_T }, - { "Royal_Guard", JOB_ROYAL_GUARD }, - { "Sorcerer", JOB_SORCERER }, - { "Minstrel", JOB_MINSTREL }, - { "Wanderer", JOB_WANDERER }, - { "Sura", JOB_SURA }, - { "Genetic", JOB_GENETIC }, - { "Shadow_Chaser", JOB_SHADOW_CHASER }, - { "Royal_Guard_Trans", JOB_ROYAL_GUARD_T }, - { "Sorcerer_Trans", JOB_SORCERER_T }, - { "Minstrel_Trans", JOB_MINSTREL_T }, - { "Wanderer_Trans", JOB_WANDERER_T }, - { "Sura_Trans", JOB_SURA_T }, - { "Genetic_Trans", JOB_GENETIC_T }, - { "Shadow_Chaser_Trans", JOB_SHADOW_CHASER_T }, - { "Baby_Rune_Knight", JOB_BABY_RUNE }, - { "Baby_Warlock", JOB_BABY_WARLOCK }, - { "Baby_Ranger", JOB_BABY_RANGER }, - { "Baby_Arch_Bishop", JOB_BABY_BISHOP }, - { "Baby_Mechanic", JOB_BABY_MECHANIC }, - { "Baby_Guillotine_Cross", JOB_BABY_CROSS }, - { "Baby_Royal_Guard", JOB_BABY_GUARD }, - { "Baby_Sorcerer", JOB_BABY_SORCERER }, - { "Baby_Minstrel", JOB_BABY_MINSTREL }, - { "Baby_Wanderer", JOB_BABY_WANDERER }, - { "Baby_Sura", JOB_BABY_SURA }, - { "Baby_Genetic", JOB_BABY_GENETIC }, - { "Baby_Shadow_Chaser", JOB_BABY_CHASER }, - { "Expanded_Super_Novice", JOB_SUPER_NOVICE_E }, - { "Expanded_Super_Baby", JOB_SUPER_BABY_E }, - { "Kagerou", JOB_KAGEROU }, - { "Oboro", JOB_OBORO }, - { "Rebellion", JOB_REBELLION }, - }; if (libconfig->read_file(&skill_tree_conf, config_filename)) { ShowError("can't read %s\n", config_filename); return; } - - jnamelen = ARRAYLENGTH(jnames); - + while ((skt = libconfig->setting_get_elem(skill_tree_conf.root,i++))) { int k; const char *name = config_setting_name(skt); - ARR_FIND(0, jnamelen, k, strcmpi(jnames[k].name,name) == 0 ); - - if( k == jnamelen ) { - ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n",name); + if ( (k = pc->check_job_name(name)) == -1 ) { + ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n", name); continue; } - - + if( ( skills = libconfig->setting_get_member(skt,"skills") ) ) { int c = 0; - int idx = pc->class2idx(jnames[k].id); + int idx = pc->class2idx(k); while ((sk = libconfig->setting_get_elem(skills,c++))) { const char *sk_name = config_setting_name(sk); @@ -10199,7 +10207,7 @@ void pc_read_skill_tree(void) { ShowWarning("pc_read_skill_tree: Unable to load skill %d (%s) into '%s's tree. Maximum number of skills per class has been reached.\n", skill_id, sk_name, name); continue; } else if (pc->skill_tree[idx][skidx].id) { - ShowNotice("pc_read_skill_tree: Overwriting %d for '%s' (%d)\n", skill_id, name, jnames[k].id); + ShowNotice("pc_read_skill_tree: Overwriting %d for '%s' (%d)\n", skill_id, name, k); } pc->skill_tree[idx][skidx].id = skill_id; @@ -10243,46 +10251,42 @@ void pc_read_skill_tree(void) { while( (skt = libconfig->setting_get_elem(skill_tree_conf.root,i++)) ) { int k, idx; const char *name = config_setting_name(skt); - - - ARR_FIND(0, jnamelen, k, strcmpi(jnames[k].name,name) == 0 ); - if( k == jnamelen ) { - ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n",name); + if ( (k = pc->check_job_name(name)) == -1 ) { + ShowWarning("pc_read_skill_tree: '%s' unknown job name!\n", name); continue; } - idx = pc->class2idx(jnames[k].id); + + idx = pc->class2idx(k); if( ( inherit = libconfig->setting_get_member(skt,"inherit") ) ) { const char *iname; int v = 0; - while ((iname = libconfig->setting_get_string_elem(inherit, v++))) { + while ( (iname = libconfig->setting_get_string_elem(inherit, v++)) ) { int b = 0, a, d, f, fidx; - ARR_FIND(0, jnamelen, b, strcmpi(jnames[b].name,iname) == 0 ); - - if( b == jnamelen ) { - ShowWarning("pc_read_skill_tree: '%s' trying to inherit unknown '%s'!\n",name,iname); + if ( (b = pc->check_job_name(iname)) == -1 ) { + ShowWarning("pc_read_skill_tree: '%s' trying to inherit unknown '%s'!\n", name, iname); continue; } - - fidx = pc->class2idx(jnames[b].id); - - ARR_FIND( 0, MAX_SKILL_TREE, d, pc->skill_tree[fidx][d].id == 0 ); - for( f = 0; f < d; f++ ) { - - ARR_FIND( 0, MAX_SKILL_TREE, a, pc->skill_tree[idx][a].id == 0 || pc->skill_tree[idx][a].id == pc->skill_tree[fidx][f].id ); + fidx = pc->class2idx(b); + + ARR_FIND(0, MAX_SKILL_TREE, d, pc->skill_tree[fidx][d].id == 0); + + for ( f = 0; f < d; f++ ) { - if( a == MAX_SKILL_TREE ) { - ShowWarning("pc_read_skill_tree: '%s' can't inherit '%s', skill tree is full!\n", name,iname); + ARR_FIND(0, MAX_SKILL_TREE, a, pc->skill_tree[idx][a].id == 0 || pc->skill_tree[idx][a].id == pc->skill_tree[fidx][f].id); + + if ( a == MAX_SKILL_TREE ) { + ShowWarning("pc_read_skill_tree: '%s' can't inherit '%s', skill tree is full!\n", name, iname); break; - } else if ( pc->skill_tree[idx][a].id || ( pc->skill_tree[idx][a].id == NV_TRICKDEAD && ((pc->jobid2mapid(jnames[k].id)&(MAPID_BASEMASK|JOBL_2))!=MAPID_NOVICE) ) ) /* we skip trickdead for non-novices */ + } else if ( pc->skill_tree[idx][a].id || (pc->skill_tree[idx][a].id == NV_TRICKDEAD && ((pc->jobid2mapid(k)&(MAPID_BASEMASK | JOBL_2)) != MAPID_NOVICE)) ) /* we skip trickdead for non-novices */ continue;/* skip */ memcpy(&pc->skill_tree[idx][a], &pc->skill_tree[fidx][f], sizeof(pc->skill_tree[fidx][f])); pc->skill_tree[idx][a].inherited = 1; } - + } } @@ -11287,4 +11291,6 @@ void pc_defaults(void) { pc->autotrade_start = pc_autotrade_start; pc->autotrade_prepare = pc_autotrade_prepare; pc->autotrade_populate = pc_autotrade_populate; + + pc->check_job_name = pc_check_job_name; } diff --git a/src/map/pc.h b/src/map/pc.h index 9e9aa4673..39b705b8f 100644 --- a/src/map/pc.h +++ b/src/map/pc.h @@ -1035,6 +1035,8 @@ struct pc_interface { void (*autotrade_start) (struct map_session_data *sd); void (*autotrade_prepare) (struct map_session_data *sd); void (*autotrade_populate) (struct map_session_data *sd); + + int (*check_job_name) (const char *name); }; struct pc_interface *pc; diff --git a/src/map/skill.c b/src/map/skill.c index 1c910f037..793b2f060 100644 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -4858,7 +4858,7 @@ int skill_castend_id(int tid, int64 tick, int id, intptr_t data) { if( sd && ud->skilltimer != INVALID_TIMER && (pc->checkskill(sd,SA_FREECAST) > 0 || ud->skill_id == LG_EXEEDBREAK) ) {// restore original walk speed ud->skilltimer = INVALID_TIMER; - status_calc_bl(&sd->bl, SCB_SPEED); + status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD); } ud->skilltimer = INVALID_TIMER; @@ -9897,7 +9897,7 @@ int skill_castend_pos(int tid, int64 tick, int id, intptr_t data) if( sd && ud->skilltimer != INVALID_TIMER && ( pc->checkskill(sd,SA_FREECAST) > 0 || ud->skill_id == LG_EXEEDBREAK ) ) {// restore original walk speed ud->skilltimer = INVALID_TIMER; - status_calc_bl(&sd->bl, SCB_SPEED); + status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD); } ud->skilltimer = INVALID_TIMER; diff --git a/src/map/status.c b/src/map/status.c index 3a4db3752..0f9fc4a55 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2082,64 +2082,40 @@ int status_calc_pet_(struct pet_data *pd, enum e_status_calc_opt opt) return 1; } -/// Helper function for status_base_pc_maxhp(), used to pre-calculate the hp_sigma_val[] array -void status_calc_sigma(void) -{ - int i,j; - - for(i = 0; i < CLASS_COUNT; i++) - { - unsigned int k = 0; - status->hp_sigma_val[i][0] = status->hp_sigma_val[i][1] = 0; - for(j = 2; j <= MAX_LEVEL; j++) - { - k += (status->hp_coefficient[i]*j + 50) / 100; - status->hp_sigma_val[i][j] = k; - if (k >= INT_MAX) - break; //Overflow protection. [Skotlex] - } - for(; j <= MAX_LEVEL; j++) - status->hp_sigma_val[i][j] = INT_MAX; - } -} - -/// Calculates base MaxHP value according to class and base level -/// The recursive equation used to calculate level bonus is (using integer operations) -/// f(0) = 35 | f(x+1) = f(x) + A + (x + B)*C/D -/// which reduces to something close to -/// f(x) = 35 + x*(A + B*C/D) + sum(i=2..x){ i*C/D } -unsigned int status_base_pc_maxhp(struct map_session_data *sd, struct status_data *st) { +unsigned int status_get_base_maxsp(struct map_session_data* sd, struct status_data *st) { uint64 val = pc->class2idx(sd->status.class_); - val = 35 + sd->status.base_level*(int64)status->hp_coefficient2[val]/100 + status->hp_sigma_val[val][sd->status.base_level]; - if((sd->class_&MAPID_UPPERMASK) == MAPID_NINJA || (sd->class_&MAPID_UPPERMASK) == MAPID_GUNSLINGER || (sd->class_&MAPID_UPPERMASK) == MAPID_REBELLION) - val += 100; //Since their HP can't be approximated well enough without this. - if((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON)) - val *= 3; //Triple max HP for top ranking Taekwons over level 90. - if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99) - val += 2000; //Supernovice lvl99 hp bonus. + val = status->SP_table[val][sd->status.base_level]; - val += val * st->vit/100; // +1% per each point of VIT + if ( sd->class_&JOBL_UPPER ) + val += val * 25 / 100; + else if ( sd->class_&JOBL_BABY ) + val = val * 70 / 100; + if ( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) ) + val *= 3; //Triple max SP for top ranking Taekwons over level 90. - if (sd->class_&JOBL_UPPER) - val += val * 25/100; //Trans classes get a 25% hp bonus - else if (sd->class_&JOBL_BABY) - val -= val * 30/100; //Baby classes get a 30% hp penalty - return (unsigned int)cap_value(val,0,UINT_MAX); + val += val * st->int_ / 100; + + return (unsigned int)cap_value(val, 0, UINT_MAX); } -unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct status_data *st) { - uint64 val; +unsigned int status_get_base_maxhp(struct map_session_data *sd, struct status_data *st) { + uint64 val = pc->class2idx(sd->status.class_); - val = 10 + sd->status.base_level*(int64)status->sp_coefficient[pc->class2idx(sd->status.class_)]/100; - val += val * st->int_/100; + val = status->HP_table[val][sd->status.base_level]; - if (sd->class_&JOBL_UPPER) - val += val * 25/100; - else if (sd->class_&JOBL_BABY) - val -= val * 30/100; - if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON)) - val *= 3; //Triple max SP for top ranking Taekwons over level 90. + if ( (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99 ) + val += 2000; //Supernovice lvl99 hp bonus. + + if ( sd->class_&JOBL_UPPER ) + val += val * 25 / 100; //Trans classes get a 25% hp bonus + else if ( sd->class_&JOBL_BABY ) + val = val * 70 / 100; //Baby classes get a 30% hp penalty + + if ( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) ) + val *= 3; //Triple max HP for top ranking Taekwons over level 90. + + val += val * st->vit / 100; // +1% per each point of VIT return (unsigned int)cap_value(val,0,UINT_MAX); } @@ -2631,7 +2607,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { // Basic MaxHP value //We hold the standard Max HP here to make it faster to recalculate on vit changes. - sd->status.max_hp = status->base_pc_maxhp(sd,bstatus); + sd->status.max_hp = status->get_base_maxhp(sd,bstatus); //This is done to handle underflows from negative Max HP bonuses i64 = sd->status.max_hp + (int)bstatus->max_hp; bstatus->max_hp = (unsigned int)cap_value(i64, 0, INT_MAX); @@ -2656,7 +2632,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { // ----- SP MAX CALCULATION ----- // Basic MaxSP value - sd->status.max_sp = status->base_pc_maxsp(sd,bstatus); + sd->status.max_sp = status->get_base_maxsp(sd,bstatus); //This is done to handle underflows from negative Max SP bonuses i64 = sd->status.max_sp + (int)bstatus->max_sp; bstatus->max_sp = (unsigned int)cap_value(i64, 0, INT_MAX); @@ -2843,17 +2819,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) { else if (pc_isridingdragon(sd)) bstatus->aspd_rate += 250-50*pc->checkskill(sd,RK_DRAGONTRAINING); #else // needs more info - if((skill_lv=pc->checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK) - bstatus->aspd_rate += 5*skill_lv; - if((skill_lv = pc->checkskill(sd,SG_DEVIL)) > 0 && !pc->nextjobexp(sd)) - bstatus->aspd_rate += 30*skill_lv; - if((skill_lv=pc->checkskill(sd,GS_SINGLEACTION))>0 && - (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE)) - bstatus->aspd_rate += ((skill_lv+1)/2) * 10; - if (pc_isridingpeco(sd)) - bstatus->aspd_rate -= 500-100*pc->checkskill(sd,KN_CAVALIERMASTERY); - else if (pc_isridingdragon(sd)) - bstatus->aspd_rate -= 250-50*pc->checkskill(sd,RK_DRAGONTRAINING); + if ( (skill_lv = pc->checkskill(sd, SG_DEVIL)) > 0 && !pc->nextjobexp(sd) ) + bstatus->aspd_rate += 30 * skill_lv; + if ( pc_isridingpeco(sd) ) + bstatus->aspd_rate -= 500 - 100 * pc->checkskill(sd, KN_CAVALIERMASTERY); + else if ( pc_isridingdragon(sd) ) + bstatus->aspd_rate -= 250 - 50 * pc->checkskill(sd, RK_DRAGONTRAINING); #endif bstatus->adelay = 2*bstatus->amotion; @@ -3657,7 +3628,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { if(flag&SCB_MAXHP) { if( bl->type&BL_PC ) { - st->max_hp = status->base_pc_maxhp(sd,st); + st->max_hp = status->get_base_maxhp(sd,st); if (sd) st->max_hp += bst->max_hp - sd->status.max_hp; @@ -3678,7 +3649,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { if(flag&SCB_MAXSP) { if( bl->type&BL_PC ) { - st->max_sp = status->base_pc_maxsp(sd,st); + st->max_sp = status->get_base_maxsp(sd,st); if (sd) st->max_sp += bst->max_sp - sd->status.max_sp; @@ -3745,19 +3716,14 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) { amotion = status->base_amotion_pc(sd, st); #ifndef RENEWAL_ASPD st->aspd_rate = status->calc_aspd_rate(bl, sc, bst->aspd_rate); - - if(st->aspd_rate != 1000) - amotion = amotion*st->aspd_rate/1000; -#else - // aspd = baseaspd + floor(sqrt((agi^2/2) + (dex^2/5))/4 + (potskillbonus*agi/200)) - amotion -= (int)(sqrt((pow(st->agi, 2) / 2) + (pow(st->dex, 2) / 5)) / 4 + ((float)status->calc_aspd(bl, sc, 1) * st->agi / 200)) * 10; - - if ( (status->calc_aspd(bl, sc, 2) + st->aspd_rate2) != 0 ) // RE ASPD percertage modifier - amotion -= ((amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd)) - * (status->calc_aspd(bl, sc, 2) + st->aspd_rate2) / 10 + 5) / 10; - +#endif if ( st->aspd_rate != 1000 ) // absolute percentage modifier - amotion = (200 - (200 - amotion / 10) * st->aspd_rate / 1000) * 10; + amotion = amotion * st->aspd_rate / 1000; + if ( sd && sd->ud.skilltimer != INVALID_TIMER && pc->checkskill(sd, SA_FREECAST) > 0 ) + amotion = amotion * 5 * (pc->checkskill(sd, SA_FREECAST) + 10) / 100; +#ifdef RENEWAL_ASPD + amotion += (max(0xc3 - amotion, 2) * (st->aspd_rate2 + status->calc_aspd(bl, sc, 2))) / 100; + amotion = 10 * (200 - amotion) + sd->bonus.aspd_add; #endif amotion = status->calc_fix_aspd(bl, sc, amotion); st->amotion = cap_value(amotion, ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd), 2000); @@ -4012,31 +3978,30 @@ int status_check_visibility(struct block_list *src, struct block_list *target) { // Basic ASPD value int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) { int amotion; -#ifdef RENEWAL_ASPD - short mod = -1; - - switch ( sd->weapontype2 ) { // adjustment for dual wielding - case W_DAGGER: - mod = 0; - break; // 0, 1, 1 - case W_1HSWORD: - case W_1HAXE: - mod = 1; - if ( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3 - mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2; - } - - amotion = (sd->status.weapon < MAX_WEAPON_TYPE && mod < 0) - ? (status->aspd_base[pc->class2idx(sd->status.class_)][sd->status.weapon]) // single weapon - : ((status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] // dual-wield - + status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]) * 6 / 10 + 10 * mod - - status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] - + status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1]); - +#ifdef RENEWAL_ASPD /* [malufett/Hercules] */ + float temp; + int skill_lv, val = 0; + amotion = status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1]; + if ( sd->status.weapon > MAX_WEAPON_TYPE ) + amotion += status->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] / 4; if ( sd->status.shield ) - amotion += (2000 - status->aspd_base[pc->class2idx(sd->status.class_)][W_FIST]) + - (status->aspd_base[pc->class2idx(sd->status.class_)][MAX_WEAPON_TYPE] - 2000); - + amotion += status->aspd_base[pc->class2idx(sd->status.class_)][MAX_WEAPON_TYPE]; + switch ( sd->status.weapon ) { + case W_BOW: case W_MUSICAL: + case W_WHIP: case W_REVOLVER: + case W_RIFLE: case W_GATLING: + case W_SHOTGUN: case W_GRENADE: + temp = st->dex * st->dex / 7.0f + st->agi * st->agi * 0.5f; + break; + default: + temp = st->dex * st->dex / 5.0f + st->agi * st->agi * 0.5f; + } + temp = (float)(sqrt(temp) * 0.25f) + 0xc4; + if ( (skill_lv = pc->checkskill(sd, SA_ADVANCEDBOOK)) > 0 && sd->status.weapon == W_BOOK ) + val += (skill_lv - 1) / 2 + 1; + if ( (skill_lv = pc->checkskill(sd, GS_SINGLEACTION)) > 0 ) + val += ((skill_lv + 1) / 2); + amotion = ((int)(temp + ((float)(status->calc_aspd(&sd->bl, &sd->sc, 1) + val) * st->agi / 200)) - min(amotion, 200)); #else // base weapon delay amotion = (sd->status.weapon < MAX_WEAPON_TYPE) @@ -4045,9 +4010,10 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) // percentual delay reduction from stats amotion -= amotion * (4 * st->agi + st->dex) / 1000; -#endif + // raw delay adjustment from bAspd bonus amotion += sd->bonus.aspd_add; +#endif /* angra manyu disregards aspd_base and similar */ if ( sd->equip_index[EQI_HAND_R] >= 0 && sd->status.inventory[sd->equip_index[EQI_HAND_R]].nameid == ITEMID_ANGRA_MANYU ) @@ -12087,33 +12053,184 @@ int status_get_sc_type(sc_type type) { * size_fix.txt - size adjustment table for weapons * refine_db.txt - refining data table *------------------------------------------*/ -bool status_readdb_job1(char* fields[], int columns, int current) -{// Job-specific values (weight, HP, SP, ASPD) - int idx, class_; - unsigned int i; - - class_ = atoi(fields[0]); +void status_read_job_db(void) { /* [malufett/Hercules] */ + int i = 0; + config_t job_db_conf; + config_setting_t *jdb = NULL; + const char *config_filename = "db/"DBPATH"job_db.conf"; + struct { + const char *name; + int id; + } wnames[] = { + { "Fist", W_FIST }, + { "Dagger", W_DAGGER }, + { "Sword", W_1HSWORD }, + { "TwoHandSword", W_2HSWORD }, + { "Spear", W_1HSPEAR }, + { "TwoHandSpear", W_2HSPEAR }, + { "Axe", W_1HAXE }, + { "TwoHandAxe", W_2HAXE }, + { "Mace", W_MACE }, + { "TwoHandMace", W_2HMACE }, + { "Rod", W_STAFF }, + { "Bow", W_BOW }, + { "Knuckle", W_KNUCKLE }, + { "Instrument", W_MUSICAL }, + { "Whip", W_WHIP }, + { "Book", W_BOOK }, + { "Katar", W_KATAR }, + { "Revolver", W_REVOLVER }, + { "Rifle", W_RIFLE }, + { "GatlingGun", W_GATLING }, + { "Shotgun", W_SHOTGUN }, + { "GrenadeLauncher", W_GRENADE }, + { "FuumaShuriken", W_HUUMA }, + { "TwoHandRod", W_2HSTAFF }, +#ifdef RENEWAL_ASPD + { "Shield", MAX_WEAPON_TYPE } +#endif + }; - if(!pc->db_checkid(class_)) - { - ShowWarning("status_readdb_job1: Invalid job class %d specified.\n", class_); - return false; + if ( libconfig->read_file(&job_db_conf, config_filename) ) { + ShowError("can't read %s\n", config_filename); + return; } - idx = pc->class2idx(class_); + while ( (jdb = libconfig->setting_get_elem(job_db_conf.root, i++)) ) { + int class_, idx, i32 = 0; + config_setting_t *temp = NULL; + const char *name = config_setting_name(jdb); - status->max_weight_base[idx] = atoi(fields[1]); - status->hp_coefficient[idx] = atoi(fields[2]); - status->hp_coefficient2[idx] = atoi(fields[3]); - status->sp_coefficient[idx] = atoi(fields[4]); -#ifdef RENEWAL_ASPD - for(i = 0; i <= MAX_WEAPON_TYPE; i++) -#else - for(i = 0; i < MAX_WEAPON_TYPE; i++) -#endif - { - status->aspd_base[idx][i] = atoi(fields[i+5]); + if ( (class_ = pc->check_job_name(name)) == -1 ) { + ShowWarning("pc_read_job_db: '%s' unknown job name!\n", name); + continue; + } + + idx = pc->class2idx(class_); + if ( (temp = libconfig->setting_get_member(jdb, "Inherit")) ) { + int nidx = 0, iidx, w; + const char *iname; + while ( (iname = libconfig->setting_get_string_elem(temp, nidx++)) ) { + int iclass, ave, ave2, total = 0, total2 = 0; + if ( (iclass = pc->check_job_name(iname)) == -1 ) { + ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s'!\n", name, iname); + continue; + } + iidx = pc->class2idx(iclass); + status->max_weight_base[idx] = status->max_weight_base[iidx]; + memcpy(&status->aspd_base[idx], &status->aspd_base[iidx], sizeof(status->aspd_base[iidx])); + for ( w = 1; w <= pc->max_level[iidx][0]; w++ ) { + status->HP_table[idx][w] = status->HP_table[iidx][w]; + status->SP_table[idx][w] = status->SP_table[iidx][w]; + if ( pc->max_level[iidx][0] < pc->max_level[idx][0] ) { + total += status->HP_table[iidx][w] - status->HP_table[iidx][w - 1]; + total2 += status->SP_table[iidx][w] - status->SP_table[iidx][w - 1]; + } + } + if ( pc->max_level[iidx][0] < pc->max_level[idx][0] ) { + ave = total / pc->max_level[iidx][0]; + ave2 = total2 / pc->max_level[iidx][0]; + for ( w = pc->max_level[iidx][0] + 1; w <= pc->max_level[idx][0]; w++ ) { + if ( !status->HP_table[iidx][w] ) + status->HP_table[idx][w] = min(ave * w, battle_config.max_hp); + if ( !status->SP_table[iidx][w] ) + status->SP_table[idx][w] = min(ave2 * w, battle_config.max_sp); + } + } + } + } + if ( (temp = libconfig->setting_get_member(jdb, "InheritHP")) ) { + int nidx = 0, iidx; + const char *iname; + while ( (iname = libconfig->setting_get_string_elem(temp, nidx++)) ) { + int iclass, w, ave, total = 0; + if ( (iclass = pc->check_job_name(iname)) == -1 ) { + ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s' HP!\n", name, iname); + continue; + } + iidx = pc->class2idx(iclass); + for ( w = 1; w <= pc->max_level[idx][0]; w++ ) { + if ( status->HP_table[iidx][w] > 0 ) { + status->HP_table[idx][w] = status->HP_table[iidx][w]; + if ( w <= pc->max_level[iidx][0] ) + total += status->HP_table[iidx][w] - status->HP_table[iidx][w - 1]; + } else { + ave = total / pc->max_level[iidx][0]; + status->HP_table[idx][w] = min(ave * w, battle_config.max_hp); + } + } + } + } + if ( (temp = libconfig->setting_get_member(jdb, "InheritSP")) ) { + int nidx = 0, iidx; + const char *iname; + while ( (iname = libconfig->setting_get_string_elem(temp, nidx++)) ) { + int iclass, w, ave, total = 0; + if ( (iclass = pc->check_job_name(iname)) == -1 ) { + ShowWarning("status_read_job_db: '%s' trying to inherit unknown '%s' SP!\n", name, iname); + continue; + } + iidx = pc->class2idx(iclass); + for ( w = 1; w <= pc->max_level[idx][0]; w++ ) { + if ( status->SP_table[iidx][w] > 0 ) { + status->SP_table[idx][w] = status->SP_table[iidx][w]; + if ( w <= pc->max_level[iidx][0] ) + total += status->SP_table[iidx][w] - status->SP_table[iidx][w - 1]; + } else { + ave = total / pc->max_level[iidx][0]; + status->SP_table[idx][w] = min(ave * w, battle_config.max_sp); + } + } + } + } + + if ( libconfig->setting_lookup_int(jdb, "Weight", &i32) ) + status->max_weight_base[idx] = i32; + else if ( !status->max_weight_base[idx] ) + status->max_weight_base[idx] = 20000; + + if ( (temp = libconfig->setting_get_member(jdb, "BaseASPD")) ) { + int widx = 0; + config_setting_t *wpn = NULL; + while ( (wpn = libconfig->setting_get_elem(temp, widx++)) ) { + int w, wlen = ARRAYLENGTH(wnames); + const char *wname = config_setting_name(wpn); + + ARR_FIND(0, wlen, w, strcmp(wnames[w].name, wname) == 0); + if ( w != wlen ) { + status->aspd_base[idx][wnames[w].id] = libconfig->setting_get_int(wpn); + } else { + ShowWarning("status_read_job_db: unknown weapon type '%s'!\n", wname); + } + } + } + + if ( (temp = libconfig->setting_get_member(jdb, "HPTable")) ) { + int level = 0, ave, total = 0; + config_setting_t *hp = NULL; + while ( (hp = libconfig->setting_get_elem(temp, level++)) ) { + status->HP_table[idx][level] = i32 = min(libconfig->setting_get_int(hp), battle_config.max_hp); + total += i32 - status->HP_table[idx][level - 1]; + } + ave = total / (level - 1); + for ( ; level <= pc->max_level[idx][0]; level++ ) { /* limit only to possible maximum level of the given class */ + status->HP_table[idx][level] = min(ave * level, battle_config.max_hp); /* some are still empty? then let's use the average increase */ + } + } + + if ( (temp = libconfig->setting_get_member(jdb, "SPTable")) ) { + int level = 0, ave, total = 0; + config_setting_t *sp = NULL; + while ( (sp = libconfig->setting_get_elem(temp, level++)) ) { + status->SP_table[idx][level] = i32 = min(libconfig->setting_get_int(sp), battle_config.max_sp); + total += i32 - status->SP_table[idx][level - 1]; + } + ave = total / (level - 1); + for ( ; level <= pc->max_level[idx][0]; level++ ) { + status->SP_table[idx][level] = min(ave * level, battle_config.max_sp); + } + } } - return true; + libconfig->destroy(&job_db_conf); } bool status_readdb_job2(char* fields[], int columns, int current) @@ -12208,15 +12325,21 @@ int status_readdb(void) // initialize databases to default // if( runflag == MAPSERVER_ST_RUNNING ) {//not necessary during boot - // reset job_db1.txt data + // reset job_db.conf data memset(status->max_weight_base, 0, sizeof(status->max_weight_base)); - memset(status->hp_coefficient, 0, sizeof(status->hp_coefficient)); - memset(status->hp_coefficient2, 0, sizeof(status->hp_coefficient2)); - memset(status->sp_coefficient, 0, sizeof(status->sp_coefficient)); - memset(status->aspd_base, 0, sizeof(status->aspd_base)); + memset(status->HP_table, 0, sizeof(status->HP_table)); + memset(status->SP_table, 0, sizeof(status->SP_table)); // reset job_db2.txt data memset(status->job_bonus,0,sizeof(status->job_bonus)); // Job-specific stats bonus } + for ( i = 0; i < CLASS_COUNT; i++ ) { + for ( j = 0; j < MAX_WEAPON_TYPE; j++ ) + status->aspd_base[i][j] = 2000; +#ifdef RENEWAL_ASPD + status->aspd_base[i][MAX_WEAPON_TYPE] = 0; +#endif + } + // size_fix.txt for(i = 0; i < ARRAYLENGTH(status->atkmods); i++) for(j = 0; j < MAX_WEAPON_TYPE; j++) @@ -12233,17 +12356,11 @@ int status_readdb(void) // read databases // - - -#ifdef RENEWAL_ASPD - sv->readdb(map->db_path, "re/job_db1.txt", ',', 6+MAX_WEAPON_TYPE, 6+MAX_WEAPON_TYPE, -1, status->readdb_job1); -#else - sv->readdb(map->db_path, "pre-re/job_db1.txt", ',', 5+MAX_WEAPON_TYPE, 5+MAX_WEAPON_TYPE, -1, status->readdb_job1); -#endif sv->readdb(map->db_path, "job_db2.txt", ',', 1, 1+MAX_LEVEL, -1, status->readdb_job2); sv->readdb(map->db_path, DBPATH"size_fix.txt", ',', MAX_WEAPON_TYPE, MAX_WEAPON_TYPE, ARRAYLENGTH(status->atkmods), status->readdb_sizefix); sv->readdb(map->db_path, DBPATH"refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(status->refine_info), status->readdb_refine); sv->readdb(map->db_path, "sc_config.txt", ',', 2, 2, SC_MAX, status->readdb_scconfig); + status->read_job_db(); return 0; } @@ -12261,7 +12378,6 @@ int do_init_status(bool minimal) { status->initChangeTables(); status->initDummyData(); status->readdb(); - status->calc_sigma(); status->natural_heal_prev_tick = timer->gettick(); status->data_ers = ers_new(sizeof(struct status_change_entry),"status.c::data_ers",ERS_OPT_NONE); timer->add_interval(status->natural_heal_prev_tick + NATURAL_HEAL_INTERVAL, status->natural_heal_timer, 0, 0, NATURAL_HEAL_INTERVAL); @@ -12286,10 +12402,8 @@ void status_defaults(void) { status->current_equip_card_id = 0; //To prevent card-stacking (from jA) [Skotlex] memset(status->max_weight_base,0,sizeof(status->max_weight_base) - + sizeof(status->hp_coefficient) - + sizeof(status->hp_coefficient2) - + sizeof(status->hp_sigma_val) - + sizeof(status->sp_coefficient) + + sizeof(status->HP_table) + + sizeof(status->SP_table) + sizeof(status->aspd_base) + sizeof(status->Skill2SCTable) + sizeof(status->IconChangeTable) @@ -12397,9 +12511,8 @@ void status_defaults(void) { status->initDummyData = initDummyData; status->base_amotion_pc = status_base_amotion_pc; status->base_atk = status_base_atk; - status->calc_sigma = status_calc_sigma; - status->base_pc_maxhp = status_base_pc_maxhp; - status->base_pc_maxsp = status_base_pc_maxsp; + status->get_base_maxhp = status_get_base_maxhp; + status->get_base_maxsp = status_get_base_maxsp; status->calc_npc_ = status_calc_npc_; status->calc_str = status_calc_str; status->calc_agi = status_calc_agi; @@ -12429,9 +12542,9 @@ void status_defaults(void) { status->display_remove = status_display_remove; status->natural_heal = status_natural_heal; status->natural_heal_timer = status_natural_heal_timer; - status->readdb_job1 = status_readdb_job1; status->readdb_job2 = status_readdb_job2; status->readdb_sizefix = status_readdb_sizefix; status->readdb_refine = status_readdb_refine; status->readdb_scconfig = status_readdb_scconfig; + status->read_job_db = status_read_job_db; } diff --git a/src/map/status.h b/src/map/status.h index f0624587e..98d5d415c 100644 --- a/src/map/status.h +++ b/src/map/status.h @@ -1982,10 +1982,8 @@ struct status_interface { int current_equip_card_id; /* */ int max_weight_base[CLASS_COUNT]; - int hp_coefficient[CLASS_COUNT]; - int hp_coefficient2[CLASS_COUNT]; - int hp_sigma_val[CLASS_COUNT][MAX_LEVEL+1]; - int sp_coefficient[CLASS_COUNT]; + int HP_table[CLASS_COUNT][MAX_LEVEL + 1]; + int SP_table[CLASS_COUNT][MAX_LEVEL + 1]; int aspd_base[CLASS_COUNT][MAX_WEAPON_TYPE+1]; // +1 for RENEWAL_ASPD sc_type Skill2SCTable[MAX_SKILL]; // skill -> status int IconChangeTable[SC_MAX]; // status -> "icon" (icon is a bit of a misnomer, since there exist values with no icon associated) @@ -2082,9 +2080,8 @@ struct status_interface { void (*initDummyData) (void); int (*base_amotion_pc) (struct map_session_data *sd, struct status_data *st); unsigned short (*base_atk) (const struct block_list *bl, const struct status_data *st); - void (*calc_sigma) (void); - unsigned int (*base_pc_maxhp) (struct map_session_data *sd, struct status_data *st); - unsigned int (*base_pc_maxsp) (struct map_session_data *sd, struct status_data *st); + unsigned int (*get_base_maxhp) (struct map_session_data *sd, struct status_data *st); + unsigned int (*get_base_maxsp) (struct map_session_data *sd, struct status_data *st); int (*calc_npc_) (struct npc_data *nd, enum e_status_calc_opt opt); unsigned short (*calc_str) (struct block_list *bl, struct status_change *sc, int str); unsigned short (*calc_agi) (struct block_list *bl, struct status_change *sc, int agi); @@ -2114,11 +2111,11 @@ struct status_interface { void (*display_remove) (struct map_session_data *sd, enum sc_type type); int (*natural_heal) (struct block_list *bl, va_list args); int (*natural_heal_timer) (int tid, int64 tick, int id, intptr_t data); - bool (*readdb_job1) (char *fields[], int columns, int current); bool (*readdb_job2) (char *fields[], int columns, int current); bool (*readdb_sizefix) (char *fields[], int columns, int current); bool (*readdb_refine) (char *fields[], int columns, int current); bool (*readdb_scconfig) (char *fields[], int columns, int current); + void (*read_job_db) (void); }; struct status_interface *status; diff --git a/src/map/unit.c b/src/map/unit.c index 2e96e9c20..2dba10aeb 100644 --- a/src/map/unit.c +++ b/src/map/unit.c @@ -1604,7 +1604,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui unit->setdir(src, map->calc_dir(src, target->x, target->y)); ud->skilltimer = timer->add( tick+casttime, skill->castend_id, src->id, 0 ); if( sd && (pc->checkskill(sd,SA_FREECAST) > 0 || skill_id == LG_EXEEDBREAK) ) - status_calc_bl(&sd->bl, SCB_SPEED); + status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD); } else skill->castend_id(ud->skilltimer,tick,src->id,0); @@ -1747,8 +1747,9 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui if( casttime > 0 ) { unit->setdir(src, map->calc_dir(src, skill_x, skill_y)); ud->skilltimer = timer->add( tick+casttime, skill->castend_pos, src->id, 0 ); - if( (sd && pc->checkskill(sd,SA_FREECAST) > 0) || skill_id == LG_EXEEDBREAK) - status_calc_bl(&sd->bl, SCB_SPEED); + if ( (sd && pc->checkskill(sd, SA_FREECAST) > 0) || skill_id == LG_EXEEDBREAK ) { + status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD); + } } else { ud->skilltimer = INVALID_TIMER; skill->castend_pos(ud->skilltimer,tick,src->id,0); @@ -2231,7 +2232,7 @@ int unit_skillcastcancel(struct block_list *bl,int type) ud->skilltimer = INVALID_TIMER; if( sd && pc->checkskill(sd,SA_FREECAST) > 0 ) - status_calc_bl(&sd->bl, SCB_SPEED); + status_calc_bl(&sd->bl, SCB_SPEED|SCB_ASPD); if( sd ) { switch( skill_id ) { -- cgit v1.2.3-60-g2f50