Fixed some 4th class ex issues (#6806)

Added all required skill and skill unit constants - thanks to @Rytech2
Fixed the order of some jobchange checks
Added missing MAPID to JOBID conversion
Fixed pc_calc_skilltree_normalize and added support for gaps in the job tree
This commit is contained in:
Lemongrass3110 2022-04-14 15:04:02 +02:00 committed by GitHub
parent f083caf28d
commit 14d6052e5b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 237 additions and 48 deletions

View File

@ -2422,54 +2422,121 @@ void pc_clean_skilltree(struct map_session_data *sd)
}
}
uint64 pc_calc_skilltree_normalize_job(struct map_session_data *sd)
{
int skill_point, novice_skills;
uint64 c = sd->class_;
uint64 pc_calc_skilltree_normalize_job_sub( struct map_session_data *sd ){
int skill_point = pc_calc_skillpoint( sd );
if (!battle_config.skillup_limit || pc_has_permission(sd, PC_PERM_ALL_SKILL))
return c;
if( sd->class_ & MAPID_SUMMONER ){
// Novice's skill points for basic skill.
std::shared_ptr<s_job_info> summoner_job = job_db.find( JOB_SUMMONER );
skill_point = pc_calc_skillpoint(sd);
int summoner_skills = summoner_job->max_job_level - 1;
// Novice's skill points for basic skill.
std::shared_ptr<s_job_info> novice_job = job_db.find(JOB_NOVICE);
if( skill_point < summoner_skills ){
return MAPID_SUMMONER;
}
novice_skills = novice_job->max_job_level - 1;
skill_point -= summoner_skills;
}else{
// Novice's skill points for basic skill.
std::shared_ptr<s_job_info> novice_job = job_db.find( JOB_NOVICE );
int novice_skills = novice_job->max_job_level - 1;
if( skill_point < novice_skills ){
return MAPID_NOVICE;
}
skill_point -= novice_skills;
}
// 1st Class Job LV Check
if (sd->class_ & JOBL_2 && (sd->class_ & MAPID_UPPERMASK) != MAPID_SUPER_NOVICE && !sd->change_level_2nd) {
sd->change_level_2nd = job_db.find(pc_mapid2jobid(sd->class_ & MAPID_BASEMASK, sd->status.sex))->max_job_level;
pc_setglobalreg(sd, add_str(JOBCHANGE2ND_VAR), sd->change_level_2nd);
if( sd->class_ & JOBL_2 && ( sd->class_ & MAPID_UPPERMASK ) != MAPID_SUPER_NOVICE ){
uint64 mapid_1st = sd->class_ & MAPID_BASEMASK;
int class_1st = pc_mapid2jobid( mapid_1st, sd->status.sex );
if( !sd->change_level_2nd ){
if( class_1st >= JOB_NOVICE ){
sd->change_level_2nd = job_db.find( class_1st )->max_job_level;
}else{
sd->change_level_2nd = 0;
}
pc_setglobalreg( sd, add_str( JOBCHANGE2ND_VAR ), sd->change_level_2nd );
}
if( class_1st > 0 && skill_point < ( sd->change_level_2nd - 1 ) ){
return mapid_1st;
}
skill_point -= ( sd->change_level_2nd - 1 );
}
// 2nd Class Job LV Check
if (sd->class_ & JOBL_THIRD && (sd->class_ & MAPID_THIRDMASK) != MAPID_SUPER_NOVICE_E && !sd->change_level_3rd) {
sd->change_level_3rd = job_db.find(pc_mapid2jobid(sd->class_ & MAPID_UPPERMASK, sd->status.sex))->max_job_level;
pc_setglobalreg(sd, add_str(JOBCHANGE3RD_VAR), sd->change_level_3rd);
if( sd->class_ & JOBL_THIRD && (sd->class_ & MAPID_THIRDMASK) != MAPID_SUPER_NOVICE_E ){
uint64 mapid_2nd = sd->class_ & MAPID_UPPERMASK;
int class_2nd = pc_mapid2jobid( mapid_2nd, sd->status.sex );
if( !sd->change_level_3rd ){
if( class_2nd >= JOB_NOVICE ){
sd->change_level_3rd = job_db.find( class_2nd )->max_job_level;
}else{
sd->change_level_3rd = 0;
}
pc_setglobalreg( sd, add_str( JOBCHANGE3RD_VAR ), sd->change_level_3rd );
}
if( class_2nd > 0 && skill_point < ( sd->change_level_3rd - 1 ) ){
return mapid_2nd;
}
skill_point -= ( sd->change_level_3rd - 1 );
}
// 3rd Class Job LV Check
if (sd->class_ & JOBL_FOURTH && !sd->change_level_4th) {
sd->change_level_4th = job_db.find(pc_mapid2jobid(sd->class_ & MAPID_THIRDMASK | JOBL_THIRD, sd->status.sex))->max_job_level;
pc_setglobalreg(sd, add_str(JOBCHANGE4TH_VAR), sd->change_level_4th);
if( sd->class_ & JOBL_FOURTH ){
uint64 mapid_3rd = sd->class_ & MAPID_THIRDMASK | JOBL_THIRD;
int class_3rd = pc_mapid2jobid( mapid_3rd, sd->status.sex );
if( !sd->change_level_4th ){
if( class_3rd >= JOB_NOVICE ){
sd->change_level_4th = job_db.find( class_3rd )->max_job_level;
}else{
sd->change_level_4th = 0;
}
pc_setglobalreg( sd, add_str( JOBCHANGE4TH_VAR ), sd->change_level_4th );
}
if( class_3rd > 0 && skill_point < ( sd->change_level_4th - 1 ) ){
return mapid_3rd;
}
skill_point -= ( sd->change_level_4th - 1 );
}
// Check the skill tree the player has access to depending on the used number of skill points.
if (skill_point < novice_skills && (sd->class_&MAPID_BASEMASK) != MAPID_SUMMONER) // Novice Skill Tree
c = MAPID_NOVICE;
else if (skill_point < novice_skills + (sd->change_level_2nd - 1) && (sd->class_&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE) // 1st Job Skill Tree
c &= MAPID_BASEMASK;
else if (skill_point < novice_skills + (sd->change_level_2nd - 1) + (sd->change_level_3rd - 1) && (sd->class_&MAPID_THIRDMASK) != MAPID_SUPER_NOVICE_E) // 2nd Job Skill Tree
c &= MAPID_UPPERMASK;
else if (skill_point < novice_skills + (sd->change_level_2nd - 1) + (sd->change_level_3rd - 1) + (sd->change_level_4th - 1)) // 3rd Job Skill Tree
c &= MAPID_THIRDMASK;
return sd->class_;
}
uint64 pc_calc_skilltree_normalize_job( struct map_session_data *sd ){
if( !battle_config.skillup_limit || pc_has_permission( sd, PC_PERM_ALL_SKILL ) ){
return sd->class_;
}
uint64 c = pc_calc_skilltree_normalize_job_sub( sd );
// Special Masks
if (sd->class_&JOBL_UPPER)
c |= JOBL_UPPER;// Rebirth Job
if (sd->class_&JOBL_BABY)
c |= JOBL_BABY;// Baby Job
if( sd->class_&JOBL_UPPER ){
if( pc_mapid2jobid( c | JOBL_UPPER, sd->status.sex ) >= JOB_NOVICE ){
c |= JOBL_UPPER;// Rebirth Job
}
}
if( sd->class_&JOBL_BABY ){
if( pc_mapid2jobid( c | JOBL_BABY, sd->status.sex ) >= JOB_NOVICE ){
c |= JOBL_BABY;// Baby Job
}
}
return c;
}
@ -6941,6 +7008,7 @@ uint64 pc_jobid2mapid(unsigned short b_class)
case JOB_TROUVERE: return MAPID_TROUBADOURTROUVERE;
case JOB_BIOLO: return MAPID_BIOLO;
case JOB_ABYSS_CHASER: return MAPID_ABYSS_CHASER;
case JOB_SOUL_ASCETIC: return MAPID_SOUL_ASCETIC;
//Unknown
default:
return -1;
@ -7095,12 +7163,16 @@ int pc_mapid2jobid(uint64 class_, int sex)
case MAPID_SUMMONER: return JOB_SUMMONER;
case MAPID_SPIRIT_HANDLER: return JOB_SPIRIT_HANDLER;
//4-1 Jobs
case MAPID_HYPER_NOVICE: return JOB_HYPER_NOVICE;
case MAPID_DRAGON_KNIGHT: return JOB_DRAGON_KNIGHT;
case MAPID_ARCH_MAGE: return JOB_ARCH_MAGE;
case MAPID_WINDHAWK: return JOB_WINDHAWK;
case MAPID_CARDINAL: return JOB_CARDINAL;
case MAPID_MEISTER: return JOB_MEISTER;
case MAPID_SHADOW_CROSS: return JOB_SHADOW_CROSS;
case MAPID_SKY_EMPEROR: return JOB_SKY_EMPEROR;
case MAPID_NIGHT_WATCH: return JOB_NIGHT_WATCH;
case MAPID_SHINKIRO_SHIRANUI: return sex?JOB_SHINKIRO:JOB_SHIRANUI;
//4-2 Jobs
case MAPID_IMPERIAL_GUARD: return JOB_IMPERIAL_GUARD;
case MAPID_ELEMENTAL_MASTER: return JOB_ELEMENTAL_MASTER;
@ -7108,6 +7180,7 @@ int pc_mapid2jobid(uint64 class_, int sex)
case MAPID_TROUBADOURTROUVERE: return sex?JOB_TROUBADOUR:JOB_TROUVERE;
case MAPID_BIOLO: return JOB_BIOLO;
case MAPID_ABYSS_CHASER: return JOB_ABYSS_CHASER;
case MAPID_SOUL_ASCETIC: return JOB_SOUL_ASCETIC;
//Unknown
default:
return -1;
@ -10098,20 +10171,18 @@ bool pc_jobchange(struct map_session_data *sd,int job, char upper)
return false;
}
// changing from 1st to 2nd job
if ((b_class&JOBL_2) && !(sd->class_&JOBL_2) && (sd->class_&MAPID_UPPERMASK) != MAPID_SUPER_NOVICE) {
sd->change_level_2nd = sd->status.job_level;
pc_setglobalreg(sd, add_str(JOBCHANGE2ND_VAR), sd->change_level_2nd);
}
// changing from 2nd to 3rd job
else if((b_class&JOBL_THIRD) && !(sd->class_&JOBL_THIRD)) {
sd->change_level_3rd = sd->status.job_level;
pc_setglobalreg(sd, add_str(JOBCHANGE3RD_VAR), sd->change_level_3rd);
}
// changing from 3rd to 4th job
else if ((b_class&JOBL_FOURTH) && !(sd->class_&JOBL_FOURTH)) {
if( ( b_class&JOBL_FOURTH ) && !( sd->class_&JOBL_FOURTH ) ){
// Changing to 4th job
sd->change_level_4th = sd->status.job_level;
pc_setglobalreg(sd, add_str(JOBCHANGE4TH_VAR), sd->change_level_4th);
pc_setglobalreg( sd, add_str( JOBCHANGE4TH_VAR ) , sd->change_level_4th );
}else if( ( b_class&JOBL_THIRD ) && !( sd->class_&JOBL_THIRD ) ){
// changing from 2nd to 3rd job
sd->change_level_3rd = sd->status.job_level;
pc_setglobalreg( sd, add_str( JOBCHANGE3RD_VAR ), sd->change_level_3rd );
}else if( ( b_class&JOBL_2 ) && !( sd->class_&JOBL_2 ) ){
// changing from 1st to 2nd job
sd->change_level_2nd = sd->status.job_level;
pc_setglobalreg( sd, add_str( JOBCHANGE2ND_VAR ), sd->change_level_2nd );
}
if(sd->cloneskill_idx > 0) {

View File

@ -8654,7 +8654,6 @@
export_constant(UNT_DUMMY_0);
export_constant(UNT_RAIN_OF_CRYSTAL);
export_constant(UNT_MYSTERY_ILLUSION);
export_constant(UNT_UNKNOWN_1);
export_constant(UNT_STRANTUM_TREMOR);
export_constant(UNT_VIOLENT_QUAKE);
export_constant(UNT_ALL_BLOOM);

View File

@ -2192,6 +2192,111 @@ enum e_skill {
EM_ELEMENTAL_BUSTER_GROUND,
EM_ELEMENTAL_BUSTER_POISON,
NW_P_F_I = 5401,
NW_GRENADE_MASTERY,
NW_INTENSIVE_AIM,
NW_GRENADE_FRAGMENT,
NW_THE_VIGILANTE_AT_NIGHT,
NW_ONLY_ONE_BULLET,
NW_SPIRAL_SHOOTING,
NW_MAGAZINE_FOR_ONE,
NW_WILD_FIRE,
NW_BASIC_GRENADE,
NW_HASTY_FIRE_IN_THE_HOLE,
NW_GRENADES_DROPPING,
NW_AUTO_FIRING_LAUNCHER,
NW_HIDDEN_CARD,
NW_MISSION_BOMBARD,
SOA_TALISMAN_MASTERY,
SOA_SOUL_MASTERY,
SOA_TALISMAN_OF_PROTECTION,
SOA_TALISMAN_OF_WARRIOR,
SOA_TALISMAN_OF_MAGICIAN,
SOA_SOUL_GATHERING,
SOA_TOTEM_OF_TUTELARY,
SOA_TALISMAN_OF_FIVE_ELEMENTS,
SOA_TALISMAN_OF_SOUL_STEALING,
SOA_EXORCISM_OF_MALICIOUS_SOUL,
SOA_TALISMAN_OF_BLUE_DRAGON,
SOA_TALISMAN_OF_WHITE_TIGER,
SOA_TALISMAN_OF_RED_PHOENIX,
SOA_TALISMAN_OF_BLACK_TORTOISE,
SOA_TALISMAN_OF_FOUR_BEARING_GOD,
SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS,
SOA_SOUL_OF_HEAVEN_AND_EARTH,
SH_MYSTICAL_CREATURE_MASTERY,
SH_COMMUNE_WITH_CHUL_HO,
SH_CHUL_HO_SONIC_CLAW,
SH_HOWLING_OF_CHUL_HO,
SH_HOGOGONG_STRIKE,
SH_COMMUNE_WITH_KI_SUL,
SH_KI_SUL_WATER_SPRAYING,
SH_MARINE_FESTIVAL_OF_KI_SUL,
SH_SANDY_FESTIVAL_OF_KI_SUL,
SH_KI_SUL_RAMPAGE,
SH_COMMUNE_WITH_HYUN_ROK,
SH_COLORS_OF_HYUN_ROK,
SH_HYUN_ROKS_BREEZE,
SH_HYUN_ROK_CANNON,
SH_TEMPORARY_COMMUNION,
SH_BLESSING_OF_MYSTICAL_CREATURES,
HN_SELFSTUDY_TATICS,
HN_SELFSTUDY_SOCERY,
HN_DOUBLEBOWLINGBASH,
HN_MEGA_SONIC_BLOW,
HN_SHIELD_CHAIN_RUSH,
HN_SPIRAL_PIERCE_MAX,
HN_METEOR_STORM_BUSTER,
HN_JUPITEL_THUNDER_STORM,
HN_JACK_FROST_NOVA,
HN_HELLS_DRIVE,
HN_GROUND_GRAVITATION,
HN_NAPALM_VULCAN_STRIKE,
HN_BREAKINGLIMIT,
HN_RULEBREAK,
SKE_SKY_MASTERY,
SKE_WAR_BOOK_MASTERY,
SKE_RISING_SUN,
SKE_NOON_BLAST,
SKE_SUNSET_BLAST,
SKE_RISING_MOON,
SKE_MIDNIGHT_KICK,
SKE_DAWN_BREAK,
SKE_TWINKLING_GALAXY,
SKE_STAR_BURST,
SKE_STAR_CANNON,
SKE_ALL_IN_THE_SKY,
SKE_ENCHANTING_SKY,
SS_TOKEDASU,
SS_SHIMIRU,
SS_AKUMUKESU,
SS_SHINKIROU,
SS_KAGEGARI,
SS_KAGENOMAI,
SS_KAGEGISSEN,
SS_FUUMASHOUAKU,
SS_FUUMAKOUCHIKU,
SS_KUNAIWAIKYOKU,
SS_KUNAIKAITEN,
SS_KUNAIKUSSETSU,
SS_SEKIENHOU,
SS_REIKETSUHOU,
SS_RAIDENPOU,
SS_KINRYUUHOU,
SS_ANTENPOU,
SS_KAGEAKUMU,
SS_HITOUAKUMU,
SS_ANKOKURYUUAKUMU,
NW_THE_VIGILANTE_AT_NIGHT_GUN_GATLING,
NW_THE_VIGILANTE_AT_NIGHT_GUN_SHOTGUN,
SS_FUUMAKOUCHIKU_BLASTING,
HLIF_HEAL = 8001,
HLIF_AVOID,
HLIF_BRAIN,
@ -2491,8 +2596,8 @@ enum e_skill_unit_id : uint16 {
UNT_RAIN_OF_CRYSTAL,
UNT_MYSTERY_ILLUSION,
UNT_UNKNOWN_1,// No idea. Makes a old style plant appear for a second.
UNT_STRANTUM_TREMOR,
UNT_STRANTUM_TREMOR = 269,
UNT_VIOLENT_QUAKE,
UNT_ALL_BLOOM,
UNT_TORNADO_STORM,
@ -2508,6 +2613,20 @@ enum e_skill_unit_id : uint16 {
UNT_LIGHTNING_LAND,
UNT_VENOM_SWAMP,
UNT_CONFLAGRATION,
UNT_CANE_OF_EVIL_EYE,
UNT_TWINKLING_GALAXY,
UNT_STAR_CANNON,
UNT_GRENADES_DROPPING,
UNT_FUUMASHOUAKU = 290, // Huuma Shuriken - Grasp
UNT_MISSION_BOMBARD,
UNT_TOTEM_OF_TUTELARY,
UNT_HYUN_ROKS_BREEZE,
UNT_SHINKIROU, // Mirage
UNT_JACK_FROST_NOVA,
UNT_GROUND_GRAVITATION,
UNT_KUNAIWAIKYOKU = 298, // Kunai - Distortion
// Skill units outside the normal unit range.
UNT_DEEPBLINDTRAP = 20852,