From 14d6052e5b4a5de00a4d1ad961e89778dd930463 Mon Sep 17 00:00:00 2001 From: Lemongrass3110 Date: Thu, 14 Apr 2022 15:04:02 +0200 Subject: [PATCH] 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 --- src/map/pc.cpp | 161 +++++++++++++++++++++++++---------- src/map/script_constants.hpp | 1 - src/map/skill.hpp | 123 +++++++++++++++++++++++++- 3 files changed, 237 insertions(+), 48 deletions(-) diff --git a/src/map/pc.cpp b/src/map/pc.cpp index a61cbcd0c1..20da804512 100755 --- a/src/map/pc.cpp +++ b/src/map/pc.cpp @@ -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 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 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 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) { diff --git a/src/map/script_constants.hpp b/src/map/script_constants.hpp index e3a764171f..0677c6f2bb 100644 --- a/src/map/script_constants.hpp +++ b/src/map/script_constants.hpp @@ -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); diff --git a/src/map/skill.hpp b/src/map/skill.hpp index 7516e1d689..84c6ef1fd8 100644 --- a/src/map/skill.hpp +++ b/src/map/skill.hpp @@ -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,