-
Posts
56 -
Joined
-
Last visited
-
Days Won
4
Content Type
Profiles
Forums
Downloads
Jobs Available
Server Database
Third-Party Services
Top Guides
Store
Crowdfunding
Everything posted by eleriaqueen
-
[QoL] Show warning when trying to allocate skill points on a higher job tab
eleriaqueen replied to exequens's question in Source Requests
I'll look into these functions, thanks for the info. Look I'm happy to at least try and come up with a solution for this "puzzle", since I'll likely use it too! I tried to handle Super Novice, but at first glance it doesn't look doable, becuase the job has access to other classes' skills mixed with his skills. I'll try to work some more on Super Novice and Summoner. If I can't do it I'll look into using the functions you mentioned, it will likely require a huge rewrite so I rather try to fix it with the "current code". Edit: I managed to make Super Novice and Summoner work. I also swapped ShowError() with clif_displaymessage() so that the messages appear ingame. enum Job_Tier { Basic = 0, First, First_High, Second, Second_High, Third, Third_High, Fourth, Super_Novice, Super_Novice_E, Hyper_Novice, Summoner, Spirit_Handler, }; // Helper Function: Returns the job tier Job_Tier pc_get_job_tier(uint64 class_) { if (class_ == MAPID_SPIRIT_HANDLER) return Job_Tier::Spirit_Handler; if (class_ == MAPID_SUMMONER) return Job_Tier::Summoner; if (class_ == MAPID_HYPER_NOVICE) return Job_Tier::Hyper_Novice; if (class_ == MAPID_SUPER_NOVICE_E) return Job_Tier::Super_Novice_E; if (class_ == MAPID_SUPER_NOVICE) return Job_Tier::Super_Novice; if (class_ & JOBL_FOURTH) return Job_Tier::Fourth; if (class_ == MAPID_RUNE_KNIGHT_T) return Job_Tier::Third_High; if (class_ == MAPID_WARLOCK_T) return Job_Tier::Third_High; if (class_ == MAPID_RANGER_T) return Job_Tier::Third_High; if (class_ == MAPID_ARCH_BISHOP_T) return Job_Tier::Third_High; if (class_ == MAPID_MECHANIC_T) return Job_Tier::Third_High; if (class_ == MAPID_GUILLOTINE_CROSS_T) return Job_Tier::Third_High; if (class_ == MAPID_ROYAL_GUARD_T) return Job_Tier::Third_High; if (class_ == MAPID_SORCERER_T) return Job_Tier::Third_High; if (class_ == MAPID_MINSTRELWANDERER_T) return Job_Tier::Third_High; if (class_ == MAPID_SURA_T) return Job_Tier::Third_High; if (class_ == MAPID_GENETIC_T) return Job_Tier::Third_High; if (class_ == MAPID_SHADOW_CHASER_T) return Job_Tier::Third_High; if (class_ & JOBL_THIRD) return Job_Tier::Third; if (class_ == MAPID_LORD_KNIGHT) return Job_Tier::Second_High; if (class_ == MAPID_HIGH_WIZARD) return Job_Tier::Second_High; if (class_ == MAPID_SNIPER) return Job_Tier::Second_High; if (class_ == MAPID_HIGH_PRIEST) return Job_Tier::Second_High; if (class_ == MAPID_WHITESMITH) return Job_Tier::Second_High; if (class_ == MAPID_ASSASSIN_CROSS) return Job_Tier::Second_High; if (class_ == MAPID_PALADIN) return Job_Tier::Second_High; if (class_ == MAPID_PROFESSOR) return Job_Tier::Second_High; if (class_ == MAPID_CLOWNGYPSY) return Job_Tier::Second_High; if (class_ == MAPID_CHAMPION) return Job_Tier::Second_High; if (class_ == MAPID_CREATOR) return Job_Tier::Second_High; if (class_ == MAPID_STALKER) return Job_Tier::Second_High; if (class_ & JOBL_2) return Job_Tier::Second; if (class_ == MAPID_SWORDMAN_HIGH) return Job_Tier::First_High; if (class_ == MAPID_MAGE_HIGH) return Job_Tier::First_High; if (class_ == MAPID_ARCHER_HIGH) return Job_Tier::First_High; if (class_ == MAPID_ACOLYTE_HIGH) return Job_Tier::First_High; if (class_ == MAPID_MERCHANT_HIGH) return Job_Tier::First_High; if (class_ == MAPID_THIEF_HIGH) return Job_Tier::First_High; if ((class_ & MAPID_BASEMASK) != MAPID_NOVICE) return Job_Tier::First; return Job_Tier::Basic; // Novice/Summoner } // Helper Function : Returns the skill's job tier Job_Tier skill_get_job_tier(uint16 skill_id) { // Novice if (skill_id > 0 && skill_id < SM_SWORD) return Job_Tier::Basic; // Swordman else if (skill_id >= SM_SWORD && skill_id <= SM_ENDURE) return Job_Tier::First; // Magician else if (skill_id >= MG_SRECOVERY && skill_id <= MG_THUNDERSTORM) return Job_Tier::First; // Acolyte else if (skill_id >= AL_DP && skill_id <= AL_CURE) return Job_Tier::First; // Merchant else if (skill_id >= MC_INCCARRY && skill_id <= MC_MAMMONITE) return Job_Tier::First; // Archer else if (skill_id >= AC_OWL && skill_id <= AC_SHOWER) return Job_Tier::First; // Thief else if (skill_id >= TF_DOUBLE && skill_id <= TF_DETOXIFY) return Job_Tier::First; // Taekwon Kid else if (skill_id >= TK_RUN && skill_id <= TK_HIGHJUMP) return Job_Tier::First; else if (skill_id == TK_MISSION) return Job_Tier::First; // Knight else if (skill_id >= KN_SPEARMASTERY && skill_id <= KN_CAVALIERMASTERY) return Job_Tier::Second; // Priest else if (skill_id >= PR_MACEMASTERY && skill_id <= PR_MAGNUS) return Job_Tier::Second; // Wizard else if (skill_id >= WZ_FIREPILLAR && skill_id <= WZ_ESTIMATION) return Job_Tier::Second; // Blacksmith else if (skill_id >= BS_IRON && skill_id <= BS_MAXIMIZE) return Job_Tier::Second; // Hunter else if (skill_id >= HT_SKIDTRAP && skill_id <= HT_SPRINGTRAP) return Job_Tier::Second; // Assassin else if (skill_id >= AS_RIGHT && skill_id <= AS_SPLASHER) return Job_Tier::Second; // Rogue else if (skill_id >= RG_SNATCHER && skill_id <= RG_PLAGIARISM) return Job_Tier::Second; // Alchemist else if (skill_id >= AM_AXEMASTERY && skill_id <= AM_RESURRECTHOMUN) return Job_Tier::Second; // Crusader else if (skill_id >= CR_TRUST && skill_id <= CR_SPEARQUICKEN) return Job_Tier::Second; // Monk else if (skill_id >= MO_IRONHAND && skill_id <= MO_COMBOFINISH) return Job_Tier::Second; // Sage else if (skill_id >= SA_ADVANCEDBOOK && skill_id <= SA_COMA) return Job_Tier::Second; // Bard & Dancer else if (skill_id >= BD_ADAPTATION && skill_id <= BD_RAGNAROK) return Job_Tier::Second; // Bard else if (skill_id >= BA_MUSICALLESSON && skill_id <= BA_APPLEIDUN) return Job_Tier::Second; // Dancer else if (skill_id >= DC_DANCINGLESSON && skill_id <= DC_SERVICEFORYOU) return Job_Tier::Second; // Lord Knight else if (skill_id >= LK_AURABLADE && skill_id <= LK_FURY) return Job_Tier::Second_High; else if (skill_id >= LK_SPIRALPIERCE && skill_id <= LK_JOINTBEAT) return Job_Tier::Second_High; // High Priest else if (skill_id >= HP_ASSUMPTIO && skill_id <= HP_MEDITATIO) return Job_Tier::Second_High; else if (skill_id == HP_MANARECHARGE) return Job_Tier::Second_High; // High Wizard else if (skill_id >= HW_SOULDRAIN && skill_id <= HW_MAGICPOWER) return Job_Tier::Second_High; else if (skill_id == HW_NAPALMVULCAN) return Job_Tier::Second_High; else if (skill_id >= HW_GANBANTEIN && skill_id <= HW_GRAVITATION) return Job_Tier::Second_High; // Paladin else if (skill_id >= PA_PRESSURE && skill_id <= PA_GOSPEL) return Job_Tier::Second_High; else if (skill_id == PA_SHIELDCHAIN) return Job_Tier::Second_High; // Champion else if (skill_id >= CH_PALMSTRIKE && skill_id <= CH_CHAINCRUSH) return Job_Tier::Second_High; else if (skill_id == CH_SOULCOLLECT) return Job_Tier::Second_High; // Professor else if (skill_id >= PF_HPCONVERSION && skill_id <= PF_SOULBURN) return Job_Tier::Second_High; else if (skill_id >= PF_MINDBREAKER && skill_id <= PF_SPIDERWEB) return Job_Tier::Second_High; else if (skill_id == PF_DOUBLECASTING) return Job_Tier::Second_High; // Assassin Cross else if (skill_id >= ASC_KATAR && skill_id <= ASC_BREAKER) return Job_Tier::Second_High; else if (skill_id >= ASC_METEORASSAULT && skill_id <= ASC_CDP) return Job_Tier::Second_High; // Sniper else if (skill_id >= SN_SIGHT && skill_id <= SN_WINDWALK) return Job_Tier::Second_High; // Whitesmith else if (skill_id >= WS_MELTDOWN && skill_id <= WS_SYSTEMCREATE) return Job_Tier::Second_High; else if (skill_id == WS_WEAPONREFINE) return Job_Tier::Second_High; else if (skill_id >= WS_CARTTERMINATION && skill_id <= WS_OVERTHRUSTMAX) return Job_Tier::Second_High; // Stalker else if (skill_id >= ST_CHASEWALK && skill_id <= ST_STEALBACKPACK) return Job_Tier::Second_High; else if (skill_id >= ST_PRESERVE && skill_id <= ST_FULLSTRIP) return Job_Tier::Second_High; // Creator else if (skill_id >= CR_ALCHEMY && skill_id <= CR_SYNTHESISPOTION) return Job_Tier::Second_High; else if (skill_id >= CR_SLIMPITCHER && skill_id <= CR_FULLPROTECTION) return Job_Tier::Second_High; else if (skill_id == CR_ACIDDEMONSTRATION) return Job_Tier::Second_High; // Clown / Gypsy else if (skill_id >= CG_ARROWVULCAN && skill_id <= CG_MARIONETTE) return Job_Tier::Second_High; else if (skill_id >= CG_LONGINGFREEDOM && skill_id <= CG_TAROTCARD) return Job_Tier::Second_High; else if (skill_id == CG_SPECIALSINGER) return Job_Tier::Second_High; // Star Gladiator else if (skill_id >= SG_FEEL && skill_id <= SG_FUSION) return Job_Tier::Second; // Soul Linker else if (skill_id == SL_ALCHEMIST) return Job_Tier::Second; else if (skill_id >= SL_MONK && skill_id <= SL_SKA) return Job_Tier::Second; else if (skill_id == SL_HIGH) return Job_Tier::Second; // else if (skill_id >= SL_DEATHKNIGHT && skill_id <= SL_GUNNER) return 2; // Gunslinger else if (skill_id >= GS_GLITTERING && skill_id <= GS_GROUNDDRIFT) return Job_Tier::Second_High; // Ninja else if (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN) return Job_Tier::Second_High; // Rune Knight else if (skill_id >= RK_ENCHANTBLADE && skill_id <= RK_PHANTOMTHRUST) return Job_Tier::Third; else if (skill_id >= RK_DRAGONBREATH_WATER && skill_id <= RK_LUXANIMA) return Job_Tier::Third; // Guillotine Cross else if (skill_id >= GC_VENOMIMPRESS && skill_id <= GC_CROSSRIPPERSLASHER) return Job_Tier::Third; else if (skill_id == GC_DARKCROW) return Job_Tier::Third; // Arch-Bishop else if (skill_id >= AB_JUDEX && skill_id <= AB_SILENTIUM) return Job_Tier::Third; else if (skill_id == AB_SECRAMENT) return Job_Tier::Third; else if (skill_id == AB_OFFERTORIUM) return Job_Tier::Third; else if (skill_id >= AB_VITUPERATUM && skill_id <= AB_CONVENIO) return Job_Tier::Third; // Warlock else if (skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP) return Job_Tier::Third; else if (skill_id == WL_TELEKINESIS_INTENSE) return Job_Tier::Third; // Ranger else if (skill_id >= RA_ARROWSTORM && skill_id <= RA_ICEBOUNDTRAP) return Job_Tier::Third; else if (skill_id == RA_UNLIMIT) return Job_Tier::Third; // Mechanic else if (skill_id >= NC_MADOLICENCE && skill_id <= NC_DISJOINT) return Job_Tier::Third; else if (skill_id == NC_MAGMA_ERUPTION) return Job_Tier::Third; // Shadow Chaser else if (skill_id >= SC_FATALMENACE && skill_id <= SC_FEINTBOMB) return Job_Tier::Third; else if (skill_id == SC_ESCAPE) return Job_Tier::Third; // Royal Guard else if (skill_id >= LG_CANNONSPEAR && skill_id <= LG_INSPIRATION) return Job_Tier::Third; else if (skill_id == LG_KINGS_GRACE) return Job_Tier::Third; // Sura else if (skill_id >= SR_DRAGONCOMBO && skill_id <= SR_GENTLETOUCH_REVITALIZE) return Job_Tier::Third; else if (skill_id >= SR_HOWLINGOFLION && skill_id <= SR_RIDEINLIGHTNING) return Job_Tier::Third; else if (skill_id == SR_FLASHCOMBO) return Job_Tier::Third; // Wanderer else if (skill_id >= WA_SWING_DANCE && skill_id <= WA_MOONLIT_SERENADE) return Job_Tier::Third; // Ministrel else if (skill_id >= MI_RUSH_WINDMILL && skill_id <= MI_HARMONIZE) return Job_Tier::Third; // Wanderer && Ministrel else if (skill_id >= WM_LESSON && skill_id <= WM_UNLIMITED_HUMMING_VOICE) return Job_Tier::Third; else if (skill_id == WM_FRIGG_SONG) return Job_Tier::Third; // Sorcerer else if (skill_id >= SO_FIREWALK && skill_id <= SO_EARTH_INSIGNIA) return Job_Tier::Third; else if (skill_id == SO_ELEMENTAL_SHIELD) return Job_Tier::Third; // Genetic else if (skill_id >= GN_TRAINING_SWORD && skill_id <= GN_SLINGITEM_RANGEMELEEATK) return Job_Tier::Third; else if (skill_id == GN_ILLUSIONDOPING) return Job_Tier::Third; // Rebellion else if (skill_id >= RL_GLITTERING_GREED && skill_id <= RL_B_FLICKER_ATK) return Job_Tier::Third; // Star Emperor else if (skill_id >= SJ_LIGHTOFMOON && skill_id <= SJ_PROMINENCEKICK) return Job_Tier::Third; // Soul Reaper else if (skill_id >= SP_SOULGOLEM && skill_id <= SP_KAUTE) return Job_Tier::Third; // Kagerou && Oboro else if (skill_id >= KO_YAMIKUMO && skill_id <= KO_IZAYOI) return Job_Tier::Third; // Kagerou else if (skill_id >= KG_KAGEHUMI && skill_id <= KG_KAGEMUSYA) return Job_Tier::Third; // Oboro else if (skill_id >= OB_ZANGETSU && skill_id <= OB_AKAITSUKI) return Job_Tier::Third; // Super Novice 2 else if (skill_id >= NV_BREAKTHROUGH && skill_id <= NV_TRANSCENDENCE) return Job_Tier::Third; // Summoner else if (skill_id >= SU_BASIC_SKILL && skill_id <= SU_SPIRITOFSEA) return Job_Tier::Third; // ALL 3rd jobs else if (skill_id == ALL_FULL_THROTTLE) return Job_Tier::Third; // Dragon Knight else if (skill_id >= DK_SERVANTWEAPON && skill_id <= DK_STORMSLASH) return Job_Tier::Fourth; else if (skill_id == DK_DRAGONIC_BREATH) return Job_Tier::Fourth; else if (skill_id == DK_DRAGONIC_PIERCE) return Job_Tier::Fourth; // Arc Mage else if (skill_id >= AG_DEADLY_PROJECTION && skill_id <= AG_FROZEN_SLASH) return Job_Tier::Fourth; else if (skill_id == AG_DESTRUCTIVE_HURRICANE_CLIMAX) return Job_Tier::Fourth; else if (skill_id == AG_ENERGY_CONVERSION) return Job_Tier::Fourth; // Inquisitor else if (skill_id >= IQ_POWERFUL_FAITH && skill_id <= IQ_THIRD_EXOR_FLAME) return Job_Tier::Fourth; else if (skill_id == IQ_BLAZING_FLAME_BLAST) return Job_Tier::Fourth; // Imperial Guard else if (skill_id >= IG_GUARD_STANCE && skill_id <= IG_CROSS_RAIN) return Job_Tier::Fourth; else if (skill_id >= IG_RADIANT_SPEAR && skill_id <= IG_IMPERIAL_PRESSURE) return Job_Tier::Fourth; // Cardinal else if (skill_id >= CD_REPARATIO && skill_id <= CD_FRAMEN) return Job_Tier::Fourth; else if (skill_id == CD_DIVINUS_FLOS) return Job_Tier::Fourth; // Shadow Cross else if (skill_id >= SHC_SHADOW_EXCEED && skill_id <= SHC_FATAL_SHADOW_CROW) return Job_Tier::Fourth; else if (skill_id == SHC_CROSS_SLASH) return Job_Tier::Fourth; // Meister else if (skill_id >= MT_AXE_STOMP && skill_id <= MT_SUMMON_ABR_INFINITY) return Job_Tier::Fourth; else if (skill_id >= MT_SPARK_BLASTER && skill_id <= MT_MIGHTY_SMASH) return Job_Tier::Fourth; else if (skill_id >= MT_RUSH_STRIKE && skill_id <= MT_ENERGY_CANNONADE) return Job_Tier::Fourth; // Biolo else if (skill_id >= BO_ACIDIFIED_ZONE_WATER_ATK && skill_id <= BO_ACIDIFIED_ZONE_FIRE_ATK) return Job_Tier::Fourth; else if (skill_id >= BO_BIONIC_PHARMACY && skill_id <= BO_HELLTREE) return Job_Tier::Fourth; else if (skill_id >= BO_EXPLOSIVE_POWDER && skill_id <= BO_MAYHEMIC_THORNS) return Job_Tier::Fourth; else if (skill_id >= BO_MYSTERY_POWDER && skill_id <= BO_DUST_EXPLOSION) return Job_Tier::Fourth; // Abyss Chaser else if (skill_id >= ABC_DAGGER_AND_BOW_M && skill_id <= ABC_FRENZY_SHOT) return Job_Tier::Fourth; else if (skill_id >= ABC_HIT_AND_SLIDING && skill_id <= ABC_ABYSS_FLAME) return Job_Tier::Fourth; // Wind Hawk else if (skill_id >= WH_ADVANCED_TRAP && skill_id <= WH_FLAMETRAP) return Job_Tier::Fourth; else if (skill_id == WH_WILD_WALK) return Job_Tier::Fourth; // Troubadour && Trouvere else if (skill_id >= TR_STAGE_MANNER && skill_id <= TR_PRON_MARCH) return Job_Tier::Fourth; else if (skill_id == TR_RHYTHMICAL_WAVE) return Job_Tier::Fourth; // Elemental Master else if (skill_id >= EM_MAGIC_BOOK_M && skill_id <= EM_ELEMENTAL_VEIL) return Job_Tier::Fourth; else if (skill_id == EM_PSYCHIC_STREAM) return Job_Tier::Fourth; // Night Watch else if (skill_id >= NW_P_F_I && skill_id <= NW_MISSION_BOMBARD) return Job_Tier::Fourth; else if (skill_id >= NW_WILD_SHOT && skill_id <= NW_MIDNIGHT_FALLEN) return Job_Tier::Fourth; // Soul Ascetic else if (skill_id >= SOA_TALISMAN_MASTERY && skill_id <= SOA_SOUL_OF_HEAVEN_AND_EARTH) return Job_Tier::Fourth; // Spirit Handler else if (skill_id >= SH_MYSTICAL_CREATURE_MASTERY && skill_id <= SH_BLESSING_OF_MYSTICAL_CREATURES) return Job_Tier::Fourth; else if (skill_id >= SH_CHUL_HO_BATTERING && skill_id <= SH_HYUN_ROK_SPIRIT_POWER) return Job_Tier::Fourth; // Hyper Novice else if (skill_id >= HN_SELFSTUDY_TATICS && skill_id <= HN_RULEBREAK) return Job_Tier::Fourth; else if (skill_id == HN_OVERCOMING_CRISIS) return Job_Tier::Fourth; // Sky Emperor else if (skill_id >= SKE_SKY_MASTERY && skill_id <= SKE_ENCHANTING_SKY) return Job_Tier::Fourth; else if (skill_id >= SKE_SKY_SUN && skill_id <= SKE_STAR_LIGHT_KICK) return Job_Tier::Fourth; // Shinkiro && Shiranui else if (skill_id >= SS_TOKEDASU && skill_id <= SS_ANKOKURYUUAKUMU) return Job_Tier::Fourth; else if (skill_id == SS_FOUR_CHARM) return Job_Tier::Fourth; // Sky Emperor else if (skill_id >= SKE_SKY_MASTERY && skill_id <= SKE_ENCHANTING_SKY) return Job_Tier::Fourth; return Job_Tier::Basic; // Default to Novice if unknown } /*========================================== * Update skill_lv for player sd * Skill point allocation *------------------------------------------*/ void pc_skillup(map_session_data *sd,uint16 skill_id) { uint16 idx = skill_get_index(skill_id); nullpo_retv(sd); if (!idx) { if (skill_id) ShowError("pc_skillup: Player attempts to level up invalid skill '%d'\n", skill_id); return; } int32 skill_point = pc_calc_skillpoint( sd ); int32 novice_max_skillpoint = job_db.find( JOB_NOVICE )->max_job_level - 1; int32 summoner_max_skillpoint = job_db.find( JOB_SUMMONER )->max_job_level - 1; int32 max_skillpoint_1st = job_db.find( JOB_SWORDMAN )->max_job_level - 1; int32 max_skillpoint_2nd = job_db.find( JOB_KNIGHT )->max_job_level - 1; int32 max_skillpoint_2nd_high = job_db.find( JOB_LORD_KNIGHT )->max_job_level - 1; int32 max_skillpoint_3rd = job_db.find( JOB_RUNE_KNIGHT )->max_job_level - 1; int32 max_skillpoint_sn = job_db.find( JOB_SUPER_NOVICE )->max_job_level - 1; int32 max_skillpoint_sn_e = job_db.find( JOB_SUPER_NOVICE_E )->max_job_level - 1; int32 max_skillpoint_summ = job_db.find( JOB_SUMMONER )->max_job_level - 1; int32 skillpoint_1st = sd->change_level_2nd - 1; int32 skillpoint_2nd = sd->change_level_3rd - 1; int32 must_spend_novice = novice_max_skillpoint - skill_point; int32 must_spend_1st = min(max_skillpoint_1st, novice_max_skillpoint + skillpoint_1st - skill_point); int32 must_spend_2nd = min(max_skillpoint_2nd, novice_max_skillpoint + skillpoint_1st + skillpoint_2nd - skill_point); int32 must_spend_2nd_high = min(max_skillpoint_2nd_high, novice_max_skillpoint + skillpoint_1st + skillpoint_2nd - skill_point); int32 must_spend_3rd = min(max_skillpoint_3rd, novice_max_skillpoint + skillpoint_1st + skillpoint_2nd + max_skillpoint_3rd - skill_point); int32 must_spend_sn = min(max_skillpoint_sn, novice_max_skillpoint + max_skillpoint_sn - skill_point); int32 must_spend_sn_e = min(max_skillpoint_sn_e, novice_max_skillpoint + max_skillpoint_sn + max_skillpoint_sn_e - skill_point); int32 must_spend_summ = max_skillpoint_summ - skill_point; StringBuf *helper_msg_novice = StringBuf_Malloc(); StringBuf *helper_msg_novice_high = StringBuf_Malloc(); StringBuf *helper_msg_1st = StringBuf_Malloc(); StringBuf *helper_msg_1st_high = StringBuf_Malloc(); StringBuf *helper_msg_2nd = StringBuf_Malloc(); StringBuf *helper_msg_2nd_high = StringBuf_Malloc(); StringBuf *helper_msg_3rd = StringBuf_Malloc(); StringBuf *helper_msg_sn = StringBuf_Malloc(); StringBuf *helper_msg_sn_e = StringBuf_Malloc(); StringBuf *helper_msg_hn = StringBuf_Malloc(); StringBuf *helper_msg_summoner = StringBuf_Malloc(); StringBuf_Printf(helper_msg_novice, "%d %s", must_spend_novice, "more skillpoints are required in Basic Skill\n"); StringBuf_Printf(helper_msg_novice_high, "%d %s", must_spend_novice, "more skillpoints are required in Basic Skill\n"); StringBuf_Printf(helper_msg_1st, "%d %s", must_spend_1st, "more skillpoints are required in 1st Job Skill Tree\n"); StringBuf_Printf(helper_msg_1st_high, "%d %s", must_spend_1st, "more skillpoints are required in 1st High Job Skill Tree\n"); StringBuf_Printf(helper_msg_2nd, "%d %s", must_spend_2nd, "more skillpoints are required in 2nd Job Skill Tree\n"); StringBuf_Printf(helper_msg_2nd_high, "%d %s", must_spend_2nd_high, "more skillpoints are required in 2nd High Job Skill Tree\n"); StringBuf_Printf(helper_msg_3rd, "%d %s", must_spend_3rd, "more skillpoints are required in 3rd Job Skill Tree\n"); StringBuf_Printf(helper_msg_sn, "%d %s", must_spend_sn, "more skillpoints are required in Super Novice (considered Novice Job) Skill Tree\n"); StringBuf_Printf(helper_msg_sn_e, "%d %s", must_spend_sn_e, "more skillpoints are required in Expanded Super Novice (considered 2nd Job) Skill Tree\n"); StringBuf_Printf(helper_msg_summoner, "%d %s", must_spend_summ, "more skillpoints are required in Summoner Skill Tree\n"); // Special Case for Super Novice if (pc_get_job_tier(sd->class_) == Job_Tier::Super_Novice) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } } // Special Case for Expanded Super Novice else if (pc_get_job_tier(sd->class_) == Job_Tier::Super_Novice_E) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second || skill_get_job_tier(skill_id) == Job_Tier::Third && (skill_point < novice_max_skillpoint + max_skillpoint_sn)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_sn, must_spend_sn); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_sn)); } } } // Special Case for Hyper Novice else if (pc_get_job_tier(sd->class_) == Job_Tier::Hyper_Novice) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second || skill_get_job_tier(skill_id) == Job_Tier::Third && (skill_point < novice_max_skillpoint + max_skillpoint_sn)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + max_skillpoint_sn) { // ShowError(helper_msg_sn, must_spend_sn); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_sn)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Fourth && (skill_point < novice_max_skillpoint + max_skillpoint_sn + max_skillpoint_sn_e)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + max_skillpoint_sn) { // ShowError(helper_msg_sn, must_spend_sn); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_sn)); } if (skill_point < novice_max_skillpoint + max_skillpoint_sn + max_skillpoint_sn_e) { // ShowError(helper_msg_sn_e, must_spend_sn_e); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_sn_e)); } } } // Special Case for Spirit Handler else if (pc_get_job_tier(sd->class_) == Job_Tier::Spirit_Handler) { if (skill_get_job_tier(skill_id) == Job_Tier::Fourth && (skill_point < max_skillpoint_summ)) { // ShowError(helper_msg_summoner, must_spend_summ); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_summoner)); } } else if (pc_get_job_tier(sd->class_) == Job_Tier::First) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } } else if (pc_get_job_tier(sd->class_) == Job_Tier::First_High) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } } } else if (pc_get_job_tier(sd->class_) == Job_Tier::Second) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st)); } } } else if (pc_get_job_tier(sd->class_) == Job_Tier::Second_High) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice_high, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice_high)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice_high, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice_high)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st_high, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st_high)); } } } else if (pc_get_job_tier(sd->class_) == Job_Tier::Third) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Third && (skill_point < novice_max_skillpoint + skillpoint_1st + max_skillpoint_2nd)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st)); } if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) { // ShowError(helper_msg_2nd, must_spend_2nd); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_2nd)); } } } else if (pc_get_job_tier(sd->class_) == Job_Tier::Third_High) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice_high, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice_high)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice_high, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice_high)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st_high, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st_high)); } } if ((skill_get_job_tier(skill_id) == Job_Tier::Third || Job_Tier::Third_High) && (skill_point < novice_max_skillpoint + skillpoint_1st + max_skillpoint_2nd)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice_high, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice_high)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st_high, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st_high)); } if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) { // ShowError(helper_msg_2nd_high, must_spend_2nd_high); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_2nd_high)); } } } else if (pc_get_job_tier(sd->class_) == Job_Tier::Fourth) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Third && (skill_point < novice_max_skillpoint + skillpoint_1st + max_skillpoint_2nd)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st)); } // If character went rebirth 2nd and 3rd if ((skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) && (skillpoint_2nd == max_skillpoint_2nd_high)) { // ShowError(helper_msg_2nd_high, must_spend_2nd_high); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_2nd_high)); } // If character went non-rebirth 2nd and 3rd else if ((skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) && (skillpoint_2nd == max_skillpoint_2nd)) { // ShowError(helper_msg_2nd, must_spend_2nd); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_2nd)); } } if (skill_get_job_tier(skill_id) == Job_Tier::Fourth && (skill_point < novice_max_skillpoint + skillpoint_1st + max_skillpoint_2nd + max_skillpoint_3rd)) { if (skill_point < novice_max_skillpoint) { // ShowError(helper_msg_novice, must_spend_novice); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_novice)); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { // ShowError(helper_msg_1st, must_spend_1st); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_1st)); } // if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) { // // ShowError(helper_msg_2nd, must_spend_2nd); // clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_2nd)); // } // If character went rebirth 2nd and 3rd then 4th if ((skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) && (skillpoint_2nd == max_skillpoint_2nd_high)) { // ShowError(helper_msg_2nd_high, must_spend_2nd_high); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_2nd_high)); } // If character went non-rebirth 2nd and 3rd then 4th else if ((skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) && (skillpoint_2nd == max_skillpoint_2nd)) { // ShowError(helper_msg_2nd, must_spend_2nd); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_2nd)); } if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd + max_skillpoint_3rd) { // ShowError(helper_msg_3rd, must_spend_3rd); clif_displaymessage(sd->fd, StringBuf_Value(helper_msg_3rd)); } } } StringBuf_Free(helper_msg_novice); StringBuf_Free(helper_msg_novice_high); StringBuf_Free(helper_msg_1st); StringBuf_Free(helper_msg_1st_high); StringBuf_Free(helper_msg_2nd); StringBuf_Free(helper_msg_2nd_high); StringBuf_Free(helper_msg_3rd); StringBuf_Free(helper_msg_sn); StringBuf_Free(helper_msg_sn_e); StringBuf_Free(helper_msg_hn); StringBuf_Free(helper_msg_summoner); ... Rest of the function code ... } -
[QoL] Show warning when trying to allocate skill points on a higher job tab
eleriaqueen replied to exequens's question in Source Requests
Class skills aren't well organized into neatly defined id ranges if I recall correctly. Some SM_ skills may have high ID's. We also need a way to check skillpoints invested in a specific job, so that if user tries to skill up a 2nd Job skill we could check if they spent all their first job skills. Oh dang, we also need to have specific code to handle Second High jobs / Third High jobs as high 2nd can go to joblvl 70. Edit: I may have found a way, but my code is very long. This time I'm using ShowError() function for testing purposes. enum Job_Tier { Basic = 0, First, First_High, Second, Second_High, Third, Third_High, Fourth }; // Helper Function: Returns the player character's job tier Job_Tier pc_get_job_tier(uint64 class_) { if (class_ & JOBL_FOURTH) return Job_Tier::Fourth; if (class_ == MAPID_RUNE_KNIGHT_T) return Job_Tier::Third_High; if (class_ == MAPID_WARLOCK_T) return Job_Tier::Third_High; if (class_ == MAPID_RANGER_T) return Job_Tier::Third_High; if (class_ == MAPID_ARCH_BISHOP_T) return Job_Tier::Third_High; if (class_ == MAPID_MECHANIC_T) return Job_Tier::Third_High; if (class_ == MAPID_GUILLOTINE_CROSS_T) return Job_Tier::Third_High; if (class_ == MAPID_ROYAL_GUARD_T) return Job_Tier::Third_High; if (class_ == MAPID_SORCERER_T) return Job_Tier::Third_High; if (class_ == MAPID_MINSTRELWANDERER_T) return Job_Tier::Third_High; if (class_ == MAPID_SURA_T) return Job_Tier::Third_High; if (class_ == MAPID_GENETIC_T) return Job_Tier::Third_High; if (class_ == MAPID_SHADOW_CHASER_T) return Job_Tier::Third_High; if (class_ & JOBL_THIRD) return Job_Tier::Third; if (class_ == MAPID_LORD_KNIGHT) return Job_Tier::Second_High; if (class_ == MAPID_HIGH_WIZARD) return Job_Tier::Second_High; if (class_ == MAPID_SNIPER) return Job_Tier::Second_High; if (class_ == MAPID_HIGH_PRIEST) return Job_Tier::Second_High; if (class_ == MAPID_WHITESMITH) return Job_Tier::Second_High; if (class_ == MAPID_ASSASSIN_CROSS) return Job_Tier::Second_High; if (class_ == MAPID_PALADIN) return Job_Tier::Second_High; if (class_ == MAPID_PROFESSOR) return Job_Tier::Second_High; if (class_ == MAPID_CLOWNGYPSY) return Job_Tier::Second_High; if (class_ == MAPID_CHAMPION) return Job_Tier::Second_High; if (class_ == MAPID_CREATOR) return Job_Tier::Second_High; if (class_ == MAPID_STALKER) return Job_Tier::Second_High; if (class_ & JOBL_2) return Job_Tier::Second; if (class_ == MAPID_SWORDMAN_HIGH) return Job_Tier::First_High; if (class_ == MAPID_MAGE_HIGH) return Job_Tier::First_High; if (class_ == MAPID_ARCHER_HIGH) return Job_Tier::First_High; if (class_ == MAPID_ACOLYTE_HIGH) return Job_Tier::First_High; if (class_ == MAPID_MERCHANT_HIGH) return Job_Tier::First_High; if (class_ == MAPID_THIEF_HIGH) return Job_Tier::First_High; if ((class_ & MAPID_BASEMASK) != MAPID_NOVICE) return Job_Tier::First; return Job_Tier::Basic; // Novice/Summoner } // Helper Function : Returns the skill's job tier Job_Tier skill_get_job_tier(uint16 skill_id) { // Novice if (skill_id > 0 && skill_id < SM_SWORD) return Job_Tier::Basic; // Swordman else if (skill_id >= SM_SWORD && skill_id <= SM_ENDURE) return Job_Tier::First; // Magician else if (skill_id >= MG_SRECOVERY && skill_id <= MG_THUNDERSTORM) return Job_Tier::First; // Acolyte else if (skill_id >= AL_DP && skill_id <= AL_CURE) return Job_Tier::First; // Merchant else if (skill_id >= MC_INCCARRY && skill_id <= MC_MAMMONITE) return Job_Tier::First; // Archer else if (skill_id >= AC_OWL && skill_id <= AC_SHOWER) return Job_Tier::First; // Thief else if (skill_id >= TF_DOUBLE && skill_id <= TF_DETOXIFY) return Job_Tier::First; // Taekwon Kid else if (skill_id >= TK_RUN && skill_id <= TK_HIGHJUMP) return Job_Tier::First; else if (skill_id == TK_MISSION) return Job_Tier::First; // Knight else if (skill_id >= KN_SPEARMASTERY && skill_id <= KN_CAVALIERMASTERY) return Job_Tier::Second; // Priest else if (skill_id >= PR_MACEMASTERY && skill_id <= PR_MAGNUS) return Job_Tier::Second; // Wizard else if (skill_id >= WZ_FIREPILLAR && skill_id <= WZ_ESTIMATION) return Job_Tier::Second; // Blacksmith else if (skill_id >= BS_IRON && skill_id <= BS_MAXIMIZE) return Job_Tier::Second; // Hunter else if (skill_id >= HT_SKIDTRAP && skill_id <= HT_SPRINGTRAP) return Job_Tier::Second; // Assassin else if (skill_id >= AS_RIGHT && skill_id <= AS_SPLASHER) return Job_Tier::Second; // Rogue else if (skill_id >= RG_SNATCHER && skill_id <= RG_PLAGIARISM) return Job_Tier::Second; // Alchemist else if (skill_id >= AM_AXEMASTERY && skill_id <= AM_RESURRECTHOMUN) return Job_Tier::Second; // Crusader else if (skill_id >= CR_TRUST && skill_id <= CR_SPEARQUICKEN) return Job_Tier::Second; // Monk else if (skill_id >= MO_IRONHAND && skill_id <= MO_COMBOFINISH) return Job_Tier::Second; // Sage else if (skill_id >= SA_ADVANCEDBOOK && skill_id <= SA_COMA) return Job_Tier::Second; // Bard & Dancer else if (skill_id >= BD_ADAPTATION && skill_id <= BD_RAGNAROK) return Job_Tier::Second; // Bard else if (skill_id >= BA_MUSICALLESSON && skill_id <= BA_APPLEIDUN) return Job_Tier::Second; // Dancer else if (skill_id >= DC_DANCINGLESSON && skill_id <= DC_SERVICEFORYOU) return Job_Tier::Second; // Lord Knight else if (skill_id >= LK_AURABLADE && skill_id <= LK_FURY) return Job_Tier::Second_High; else if (skill_id >= LK_SPIRALPIERCE && skill_id <= LK_JOINTBEAT) return Job_Tier::Second_High; // High Priest else if (skill_id >= HP_ASSUMPTIO && skill_id <= HP_MEDITATIO) return Job_Tier::Second_High; else if (skill_id == HP_MANARECHARGE) return Job_Tier::Second_High; // High Wizard else if (skill_id >= HW_SOULDRAIN && skill_id <= HW_MAGICPOWER) return Job_Tier::Second_High; else if (skill_id == HW_NAPALMVULCAN) return Job_Tier::Second_High; else if (skill_id >= HW_GANBANTEIN && skill_id <= HW_GRAVITATION) return Job_Tier::Second_High; // Paladin else if (skill_id >= PA_PRESSURE && skill_id <= PA_GOSPEL) return Job_Tier::Second_High; else if (skill_id == PA_SHIELDCHAIN) return Job_Tier::Second_High; // Champion else if (skill_id >= CH_PALMSTRIKE && skill_id <= CH_CHAINCRUSH) return Job_Tier::Second_High; else if (skill_id == CH_SOULCOLLECT) return Job_Tier::Second_High; // Professor else if (skill_id >= PF_HPCONVERSION && skill_id <= PF_SOULBURN) return Job_Tier::Second_High; else if (skill_id >= PF_MINDBREAKER && skill_id <= PF_SPIDERWEB) return Job_Tier::Second_High; else if (skill_id == PF_DOUBLECASTING) return Job_Tier::Second_High; // Assassin Cross else if (skill_id >= ASC_KATAR && skill_id <= ASC_BREAKER) return Job_Tier::Second_High; else if (skill_id >= ASC_METEORASSAULT && skill_id <= ASC_CDP) return Job_Tier::Second_High; // Sniper else if (skill_id >= SN_SIGHT && skill_id <= SN_WINDWALK) return Job_Tier::Second_High; // Whitesmith else if (skill_id >= WS_MELTDOWN && skill_id <= WS_SYSTEMCREATE) return Job_Tier::Second_High; else if (skill_id == WS_WEAPONREFINE) return Job_Tier::Second_High; else if (skill_id >= WS_CARTTERMINATION && skill_id <= WS_OVERTHRUSTMAX) return Job_Tier::Second_High; // Stalker else if (skill_id >= ST_CHASEWALK && skill_id <= ST_STEALBACKPACK) return Job_Tier::Second_High; else if (skill_id >= ST_PRESERVE && skill_id <= ST_FULLSTRIP) return Job_Tier::Second_High; // Creator else if (skill_id >= CR_ALCHEMY && skill_id <= CR_SYNTHESISPOTION) return Job_Tier::Second_High; else if (skill_id >= CR_SLIMPITCHER && skill_id <= CR_FULLPROTECTION) return Job_Tier::Second_High; else if (skill_id == CR_ACIDDEMONSTRATION) return Job_Tier::Second_High; // Clown / Gypsy else if (skill_id >= CG_ARROWVULCAN && skill_id <= CG_MARIONETTE) return Job_Tier::Second_High; else if (skill_id >= CG_LONGINGFREEDOM && skill_id <= CG_TAROTCARD) return Job_Tier::Second_High; else if (skill_id == CG_SPECIALSINGER) return Job_Tier::Second_High; // Star Gladiator else if (skill_id >= SG_FEEL && skill_id <= SG_FUSION) return Job_Tier::Second; // Soul Linker else if (skill_id == SL_ALCHEMIST) return Job_Tier::Second; else if (skill_id >= SL_MONK && skill_id <= SL_SKA) return Job_Tier::Second; else if (skill_id == SL_HIGH) return Job_Tier::Second; // else if (skill_id >= SL_DEATHKNIGHT && skill_id <= SL_GUNNER) return 2; // Gunslinger else if (skill_id >= GS_GLITTERING && skill_id <= GS_GROUNDDRIFT) return Job_Tier::Second_High; // Ninja else if (skill_id >= NJ_TOBIDOUGU && skill_id <= NJ_ISSEN) return Job_Tier::Second_High; // Rune Knight else if (skill_id >= RK_ENCHANTBLADE && skill_id <= RK_PHANTOMTHRUST) return Job_Tier::Third; else if (skill_id >= RK_DRAGONBREATH_WATER && skill_id <= RK_LUXANIMA) return Job_Tier::Third; // Guillotine Cross else if (skill_id >= GC_VENOMIMPRESS && skill_id <= GC_CROSSRIPPERSLASHER) return Job_Tier::Third; else if (skill_id == GC_DARKCROW) return Job_Tier::Third; // Arch-Bishop else if (skill_id >= AB_JUDEX && skill_id <= AB_SILENTIUM) return Job_Tier::Third; else if (skill_id == AB_SECRAMENT) return Job_Tier::Third; else if (skill_id == AB_OFFERTORIUM) return Job_Tier::Third; else if (skill_id >= AB_VITUPERATUM && skill_id <= AB_CONVENIO) return Job_Tier::Third; // Warlock else if (skill_id >= WL_WHITEIMPRISON && skill_id <= WL_FREEZE_SP) return Job_Tier::Third; else if (skill_id == WL_TELEKINESIS_INTENSE) return Job_Tier::Third; // Ranger else if (skill_id >= RA_ARROWSTORM && skill_id <= RA_ICEBOUNDTRAP) return Job_Tier::Third; else if (skill_id == RA_UNLIMIT) return Job_Tier::Third; // Mechanic else if (skill_id >= NC_MADOLICENCE && skill_id <= NC_DISJOINT) return Job_Tier::Third; else if (skill_id == NC_MAGMA_ERUPTION) return Job_Tier::Third; // Shadow Chaser else if (skill_id >= SC_FATALMENACE && skill_id <= SC_FEINTBOMB) return Job_Tier::Third; else if (skill_id == SC_ESCAPE) return Job_Tier::Third; // Royal Guard else if (skill_id >= LG_CANNONSPEAR && skill_id <= LG_INSPIRATION) return Job_Tier::Third; else if (skill_id == LG_KINGS_GRACE) return Job_Tier::Third; // Sura else if (skill_id >= SR_DRAGONCOMBO && skill_id <= SR_GENTLETOUCH_REVITALIZE) return Job_Tier::Third; else if (skill_id >= SR_HOWLINGOFLION && skill_id <= SR_RIDEINLIGHTNING) return Job_Tier::Third; else if (skill_id == SR_FLASHCOMBO) return Job_Tier::Third; // Wanderer else if (skill_id >= WA_SWING_DANCE && skill_id <= WA_MOONLIT_SERENADE) return Job_Tier::Third; // Ministrel else if (skill_id >= MI_RUSH_WINDMILL && skill_id <= MI_HARMONIZE) return Job_Tier::Third; // Wanderer && Ministrel else if (skill_id >= WM_LESSON && skill_id <= WM_UNLIMITED_HUMMING_VOICE) return Job_Tier::Third; else if (skill_id == WM_FRIGG_SONG) return Job_Tier::Third; // Sorcerer else if (skill_id >= SO_FIREWALK && skill_id <= SO_EARTH_INSIGNIA) return Job_Tier::Third; else if (skill_id == SO_ELEMENTAL_SHIELD) return Job_Tier::Third; // Genetic else if (skill_id >= GN_TRAINING_SWORD && skill_id <= GN_SLINGITEM_RANGEMELEEATK) return Job_Tier::Third; else if (skill_id == GN_ILLUSIONDOPING) return Job_Tier::Third; // Rebellion else if (skill_id >= RL_GLITTERING_GREED && skill_id <= RL_B_FLICKER_ATK) return Job_Tier::Third; // Star Emperor else if (skill_id >= SJ_LIGHTOFMOON && skill_id <= SJ_PROMINENCEKICK) return Job_Tier::Third; // Soul Reaper else if (skill_id >= SP_SOULGOLEM && skill_id <= SP_KAUTE) return Job_Tier::Third; // Kagerou && Oboro else if (skill_id >= KO_YAMIKUMO && skill_id <= KO_IZAYOI) return Job_Tier::Third; // Kagerou else if (skill_id >= KG_KAGEHUMI && skill_id <= KG_KAGEMUSYA) return Job_Tier::Third; // Oboro else if (skill_id >= OB_ZANGETSU && skill_id <= OB_AKAITSUKI) return Job_Tier::Third; // Super Novice 2 else if (skill_id >= NV_BREAKTHROUGH && skill_id <= NV_TRANSCENDENCE) return Job_Tier::Third; // ALL 3rd jobs else if (skill_id == ALL_FULL_THROTTLE) return Job_Tier::Third; // Dragon Knight else if (skill_id >= DK_SERVANTWEAPON && skill_id <= DK_STORMSLASH) return Job_Tier::Fourth; else if (skill_id == DK_DRAGONIC_BREATH) return Job_Tier::Fourth; else if (skill_id == DK_DRAGONIC_PIERCE) return Job_Tier::Fourth; // Arc Mage else if (skill_id >= AG_DEADLY_PROJECTION && skill_id <= AG_FROZEN_SLASH) return Job_Tier::Fourth; else if (skill_id == AG_DESTRUCTIVE_HURRICANE_CLIMAX) return Job_Tier::Fourth; else if (skill_id == AG_ENERGY_CONVERSION) return Job_Tier::Fourth; // Inquisitor else if (skill_id >= IQ_POWERFUL_FAITH && skill_id <= IQ_THIRD_EXOR_FLAME) return Job_Tier::Fourth; else if (skill_id == IQ_BLAZING_FLAME_BLAST) return Job_Tier::Fourth; // Imperial Guard else if (skill_id >= IG_GUARD_STANCE && skill_id <= IG_CROSS_RAIN) return Job_Tier::Fourth; else if (skill_id >= IG_RADIANT_SPEAR && skill_id <= IG_IMPERIAL_PRESSURE) return Job_Tier::Fourth; // Cardinal else if (skill_id >= CD_REPARATIO && skill_id <= CD_FRAMEN) return Job_Tier::Fourth; else if (skill_id == CD_DIVINUS_FLOS) return Job_Tier::Fourth; // Shadow Cross else if (skill_id >= SHC_SHADOW_EXCEED && skill_id <= SHC_FATAL_SHADOW_CROW) return Job_Tier::Fourth; else if (skill_id == SHC_CROSS_SLASH) return Job_Tier::Fourth; // Meister else if (skill_id >= MT_AXE_STOMP && skill_id <= MT_SUMMON_ABR_INFINITY) return Job_Tier::Fourth; else if (skill_id >= MT_SPARK_BLASTER && skill_id <= MT_MIGHTY_SMASH) return Job_Tier::Fourth; else if (skill_id >= MT_RUSH_STRIKE && skill_id <= MT_ENERGY_CANNONADE) return Job_Tier::Fourth; // Biolo else if (skill_id >= BO_ACIDIFIED_ZONE_WATER_ATK && skill_id <= BO_ACIDIFIED_ZONE_FIRE_ATK) return Job_Tier::Fourth; else if (skill_id >= BO_BIONIC_PHARMACY && skill_id <= BO_HELLTREE) return Job_Tier::Fourth; else if (skill_id >= BO_EXPLOSIVE_POWDER && skill_id <= BO_MAYHEMIC_THORNS) return Job_Tier::Fourth; else if (skill_id >= BO_MYSTERY_POWDER && skill_id <= BO_DUST_EXPLOSION) return Job_Tier::Fourth; // Abyss Chaser else if (skill_id >= ABC_DAGGER_AND_BOW_M && skill_id <= ABC_FRENZY_SHOT) return Job_Tier::Fourth; else if (skill_id >= ABC_HIT_AND_SLIDING && skill_id <= ABC_ABYSS_FLAME) return Job_Tier::Fourth; // Wind Hawk else if (skill_id >= WH_ADVANCED_TRAP && skill_id <= WH_FLAMETRAP) return Job_Tier::Fourth; else if (skill_id == WH_WILD_WALK) return Job_Tier::Fourth; // Troubadour && Trouvere else if (skill_id >= TR_STAGE_MANNER && skill_id <= TR_PRON_MARCH) return Job_Tier::Fourth; else if (skill_id == TR_RHYTHMICAL_WAVE) return Job_Tier::Fourth; // Elemental Master else if (skill_id >= EM_MAGIC_BOOK_M && skill_id <= EM_ELEMENTAL_VEIL) return Job_Tier::Fourth; else if (skill_id == EM_PSYCHIC_STREAM) return Job_Tier::Fourth; // Night Watch else if (skill_id >= NW_P_F_I && skill_id <= NW_MISSION_BOMBARD) return Job_Tier::Fourth; else if (skill_id >= NW_WILD_SHOT && skill_id <= NW_MIDNIGHT_FALLEN) return Job_Tier::Fourth; // Soul Ascetic else if (skill_id >= SOA_TALISMAN_MASTERY && skill_id <= SOA_SOUL_OF_HEAVEN_AND_EARTH) return Job_Tier::Fourth; // Spirit Handler else if (skill_id >= SH_MYSTICAL_CREATURE_MASTERY && skill_id <= SH_BLESSING_OF_MYSTICAL_CREATURES) return Job_Tier::Fourth; else if (skill_id >= SH_CHUL_HO_BATTERING && skill_id <= SH_HYUN_ROK_SPIRIT_POWER) return Job_Tier::Fourth; // Hyper Novice else if (skill_id >= HN_SELFSTUDY_TATICS && skill_id <= HN_RULEBREAK) return Job_Tier::Fourth; else if (skill_id == HN_OVERCOMING_CRISIS) return Job_Tier::Fourth; // Sky Emperor else if (skill_id >= SKE_SKY_MASTERY && skill_id <= SKE_ENCHANTING_SKY) return Job_Tier::Fourth; else if (skill_id >= SKE_SKY_SUN && skill_id <= SKE_STAR_LIGHT_KICK) return Job_Tier::Fourth; // Shinkiro && Shiranui else if (skill_id >= SS_TOKEDASU && skill_id <= SS_ANKOKURYUUAKUMU) return Job_Tier::Fourth; else if (skill_id == SS_FOUR_CHARM) return Job_Tier::Fourth; // Sky Emperor else if (skill_id >= SKE_SKY_MASTERY && skill_id <= SKE_ENCHANTING_SKY) return Job_Tier::Fourth; return Job_Tier::Basic; // Default to Novice if unknown } /*========================================== * Update skill_lv for player sd * Skill point allocation *------------------------------------------*/ void pc_skillup(map_session_data *sd,uint16 skill_id) { uint16 idx = skill_get_index(skill_id); nullpo_retv(sd); if (!idx) { if (skill_id) ShowError("pc_skillup: Player attempts to level up invalid skill '%d'\n", skill_id); return; } int32 skill_point = pc_calc_skillpoint( sd ); int32 novice_max_skillpoint = job_db.find( JOB_NOVICE )->max_job_level - 1; int32 summoner_max_skillpoint = job_db.find( JOB_SUMMONER )->max_job_level - 1; int32 max_skillpoint_1st = job_db.find( JOB_SWORDMAN )->max_job_level - 1; int32 max_skillpoint_2nd = job_db.find( JOB_KNIGHT )->max_job_level - 1; int32 max_skillpoint_2nd_high = job_db.find( JOB_LORD_KNIGHT )->max_job_level - 1; int32 max_skillpoint_3rd = job_db.find( JOB_RUNE_KNIGHT )->max_job_level - 1; int32 max_skillpoint_4th = job_db.find( JOB_DRAGON_KNIGHT )->max_job_level - 1; int32 skillpoint_1st = sd->change_level_2nd - 1; int32 skillpoint_2nd = sd->change_level_3rd - 1; int32 must_spend_novice = novice_max_skillpoint - skill_point; int32 must_spend_1st = min(max_skillpoint_1st, novice_max_skillpoint + skillpoint_1st - skill_point); int32 must_spend_2nd = min(max_skillpoint_2nd, novice_max_skillpoint + skillpoint_1st + skillpoint_2nd - skill_point); int32 must_spend_2nd_high = min(max_skillpoint_2nd_high, novice_max_skillpoint + skillpoint_1st + skillpoint_2nd - skill_point); int32 must_spend_3rd = min(max_skillpoint_3rd, novice_max_skillpoint + skillpoint_1st + skillpoint_2nd + max_skillpoint_3rd - skill_point); char helper_msg_novice[128]; char helper_msg_novice_high[128]; char helper_msg_1st[128]; char helper_msg_1st_high[128]; char helper_msg_2nd[128]; char helper_msg_2nd_high[128]; char helper_msg_3rd[128]; sprintf(helper_msg_novice, "%s", "You need to spend %d more skillpoints in Novice Skill Tree\n"); sprintf(helper_msg_novice_high, "%s", "You need to spend %d more skillpoints in Novice High Skill Tree\n"); sprintf(helper_msg_1st, "%s", "You need to spend %d more skillpoints in 1st Job Skill Tree\n"); sprintf(helper_msg_1st_high, "%s", "You need to spend %d more skillpoints in 1st High Job Skill Tree\n"); sprintf(helper_msg_2nd, "%s", "You need to spend %d more skillpoints in 2nd Job Skill Tree\n"); sprintf(helper_msg_2nd_high, "%s", "You need to spend %d more skillpoints in 2nd High Job Skill Tree\n"); sprintf(helper_msg_3rd, "%s", "You need to spend %d more skillpoints in 3rd Job Skill Tree\n"); if (pc_get_job_tier(sd->class_) == Job_Tier::First) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { ShowError(helper_msg_novice, must_spend_novice); } } if (pc_get_job_tier(sd->class_) == Job_Tier::First_High) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } } } if (pc_get_job_tier(sd->class_) == Job_Tier::Second) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st, must_spend_1st); } } } if (pc_get_job_tier(sd->class_) == Job_Tier::Second_High) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice_high, must_spend_novice); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice_high, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st_high, must_spend_1st); } } } if (pc_get_job_tier(sd->class_) == Job_Tier::Third) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st, must_spend_1st); } } if (skill_get_job_tier(skill_id) == Job_Tier::Third && (skill_point < novice_max_skillpoint + skillpoint_1st + max_skillpoint_2nd)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st, must_spend_1st); } if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) { ShowError(helper_msg_2nd, must_spend_2nd); } } } if (pc_get_job_tier(sd->class_) == Job_Tier::Third_High) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice_high, must_spend_novice); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice_high, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st_high, must_spend_1st); } } if ((skill_get_job_tier(skill_id) == Job_Tier::Third || Job_Tier::Third_High) && (skill_point < novice_max_skillpoint + skillpoint_1st + max_skillpoint_2nd)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice_high, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st_high, must_spend_1st); } if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) { ShowError(helper_msg_2nd_high, must_spend_2nd_high); } } } if (pc_get_job_tier(sd->class_) == Job_Tier::Fourth) { if (skill_get_job_tier(skill_id) == Job_Tier::First && (skill_point < novice_max_skillpoint)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } } if (skill_get_job_tier(skill_id) == Job_Tier::Second && (skill_point < novice_max_skillpoint + skillpoint_1st)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st, must_spend_1st); } } if (skill_get_job_tier(skill_id) == Job_Tier::Third && (skill_point < novice_max_skillpoint + skillpoint_1st + max_skillpoint_2nd)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st, must_spend_1st); } if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) { ShowError(helper_msg_2nd, must_spend_2nd); } } if (skill_get_job_tier(skill_id) == Job_Tier::Fourth && (skill_point < novice_max_skillpoint + skillpoint_1st + max_skillpoint_2nd + max_skillpoint_3rd)) { if (skill_point < novice_max_skillpoint) { ShowError(helper_msg_novice, must_spend_novice); } if (skill_point < novice_max_skillpoint + skillpoint_1st) { ShowError(helper_msg_1st, must_spend_1st); } if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd) { ShowError(helper_msg_2nd, must_spend_2nd); } if (skill_point < novice_max_skillpoint + skillpoint_1st + skillpoint_2nd + max_skillpoint_3rd) { ShowError(helper_msg_3rd, must_spend_3rd); } } } ... Rest of Function ... } Summoner and Super Novice are likely badly handled. -
[QoL] Show warning when trying to allocate skill points on a higher job tab
eleriaqueen replied to exequens's question in Source Requests
Hi. I'm trying to achieve this too now that I read your request, It made me remember that a while ago I wanted to do something like what you explained. Here's what I managed to produce so far, sadly it only works with Novice as I'm checking NV_BASIC skill level. /*========================================== * Update skill_lv for player sd * Skill point allocation *------------------------------------------*/ void pc_skillup(map_session_data *sd,uint16 skill_id) { uint16 idx = skill_get_index(skill_id); nullpo_retv(sd); if (!idx) { if (skill_id) ShowError("pc_skillup: Player attempts to level up invalid skill '%d'\n", skill_id); return; } // If user tries to put points in a skill other than NV_BASIC while NV_BASIC is not maxed if(skill_id > NV_BASIC && sd->status.skill[NV_BASIC].lv < skill_tree_get_max(NV_BASIC, sd->status.class_)){ StringBuf *nov_msg = StringBuf_Malloc(); StringBuf_Printf(nov_msg, "You must spend %d skillpoints on Basic Skill in Novice skill tree first", skill_tree_get_max(NV_BASIC, sd->status.class_)); clif_displaymessage(sd->fd, StringBuf_Value(nov_msg)); StringBuf_Free(nov_msg); // Do not spend the point // return; } ... Rest of the function ... } Edit: I can't find a way to check how many skillpoints have been invested in a specific job by the player. With that info we could check invested points in 1st / 2nd / 3rd jobs and display a message when trying to up a skill when not all previous job skills have been invested. -
[GUIDE] Upscaling textures with AI
eleriaqueen replied to Iamanewbiehere's topic in Spriting & Palette Showcase
A free tool I've used several times to upscale various game textures and stuff (mainly out of curiosity) is Chainner. It works well with NVIDIA GPU slightly less so with AMD/ATI GPU. It's not particularly easy nor particularly hard to use either but it's different to say the least ! I wouldn't recommend converting to JPEG before upscaling, you want to have the least amount of artifacts before doing AI uspcaling. (JPEG compression creates artifacts and image noise) PNG always preferred as it has losless compression. -
How to remove or replace this bottom circle
eleriaqueen replied to eloscar23's question in Source Support
Are maybe you talking about the player "shadow" blob ? If so, yes you can, I made a "HD" (rounder / smoother) shadow a few months back. -
@Sapito Sucio I think patch "BodyPalMF" can cause issues. I had the game crash when switching to job High Thief and it would subsequently crash everytime I would get to character select screen. I then made my own patched 2022-04-06 exe to confirm and tried with "BodyPalMF" -> it crashed. Then I disabled that patch -> it didn't crash any more.
-
Are you gonna ask for this on every topic on these forums ? Haven't you made your own topic asking for it already ?
-
RagnaDB - Ragnarok Online Cross-Episode Database
eleriaqueen replied to vitcunha's topic in Project Concepts & In Progress
Woah this is cool, I love the concept and the website is super responsive. Also it's pretty cool that you were able to get the domain "ragnadb" ! -
Utility: Reset NPC that can only reset your current class
eleriaqueen replied to Tero's topic in Utility Script Releases
I love this. And yeah this should be the default behavior of the reset npc! Could someone with good rA scripting knowledge check the script, could there be issues with 4th jobs ? -
Oh nice! I'm glad you were able to resolve it.
-
Hi, I didn't have to do anything to enable 4th jobs on my local server using (hexed) 20220406 ragexe on 2022 client data. Maybe you're missing the 4th jobs sprites while the server side works fine ?
-
[Showcase] Lhz Dun Mobs Update aka Bio Lab Family
eleriaqueen replied to w0wZukuBg's topic in Spriting & Palette Showcase
Very nice work, thanks. -
Hi, the new minimap option/feature is awesome, thank you for improving GRF Editor still.
-
@Sapito Sucio If I'm not mistaken Froggo RO seems to have been hexed for 150 inventory limit but as far as I understand this requires editing the server config ? Perhaps you should leave this at 90 or whatever's the standard KRO limit or add mention of this quirk on the first post ? Also, not sure you can do something about it even if I set DirectX7 in Setup it always reverts to DirectX9 for some reason
-
Syntax Highlighter and Snippets for Visual Studio Code
eleriaqueen replied to Secrets's topic in Project Releases
I've been using this syntax highlighting plugin for a short while. It's awesome. -
A possible fix for the position bug when attacking (Netcode)
eleriaqueen replied to Tero's topic in Source Releases
I have do admit I was quite a bit skeptical when I saw your fixes consisted of such a small amount of code, but they make a huge difference ! Thank you !