diff options
Diffstat (limited to 'src/map/status.c')
-rw-r--r-- | src/map/status.c | 248 |
1 files changed, 183 insertions, 65 deletions
diff --git a/src/map/status.c b/src/map/status.c index 5e65244ef..78c11899b 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -2,7 +2,7 @@ * This file is part of Hercules. * http://herc.ws - http://github.com/HerculesWS/Hercules * - * Copyright (C) 2012-2015 Hercules Dev Team + * Copyright (C) 2012-2016 Hercules Dev Team * Copyright (C) Athena Dev Teams * * Hercules is free software: you can redistribute it and/or modify @@ -719,6 +719,24 @@ void initChangeTables(void) status->set_sc( GN_FIRE_EXPANSION_TEAR_GAS , SC_FIRE_EXPANSION_TEAR_GAS , SI_FIRE_EXPANSION_TEAR_GAS , SCB_NONE ); status->set_sc( GN_MANDRAGORA , SC_MANDRAGORA , SI_MANDRAGORA , SCB_INT ); + /** + * Summoner + */ + status->set_sc(SU_HIDE, SC_SUHIDE, SI_SUHIDE, SCB_SPEED); + add_sc(SU_SCRATCH, SC_BLOODING); + status->set_sc(SU_STOOP, SC_SU_STOOP, SI_SU_STOOP, SCB_NONE); + status->set_sc(SU_FRESHSHRIMP, SC_FRESHSHRIMP, SI_FRESHSHRIMP, SCB_NONE); + add_sc(SU_SV_STEMSPEAR, SC_BLOODING); + status->set_sc(SU_CN_POWDERING, SC_CATNIPPOWDER, SI_CATNIPPOWDER, SCB_WATK | SCB_SPEED | SCB_REGEN); + add_sc(SU_CN_METEOR, SC_CURSE); + set_sc_with_vfx(SU_SV_ROOTTWIST, SC_SV_ROOTTWIST, SI_SV_ROOTTWIST, SCB_NONE); + add_sc(SU_SCAROFTAROU, SC_STUN ); + status->set_sc(SU_SCAROFTAROU, SC_BITESCAR, SI_BITESCAR, SCB_NONE); + status->set_sc(SU_ARCLOUSEDASH, SC_ARCLOUSEDASH, SI_ARCLOUSEDASH, SCB_AGI | SCB_SPEED); + add_sc(SU_LUNATICCARROTBEAT, SC_STUN); + status->set_sc(SU_TUNAPARTY, SC_TUNAPARTY, SI_TUNAPARTY, SCB_NONE); + status->set_sc(SU_BUNCHOFSHRIMP, SC_SHRIMP, SI_SHRIMP, SCB_BATK | SCB_MATK); + // Elemental Spirit summoner's 'side' status changes. status->set_sc( EL_CIRCLE_OF_FIRE , SC_CIRCLE_OF_FIRE_OPTION, SI_CIRCLE_OF_FIRE_OPTION, SCB_NONE ); status->set_sc( EL_FIRE_CLOAK , SC_FIRE_CLOAK_OPTION , SI_FIRE_CLOAK_OPTION , SCB_ALL ); @@ -997,6 +1015,9 @@ void initChangeTables(void) status->dbs->IconChangeTable[SC_MAGICAL_FEATHER] = SI_MAGICAL_FEATHER; status->dbs->IconChangeTable[SC_BLOSSOM_FLUTTERING] = SI_BLOSSOM_FLUTTERING; + // Summoner + status->dbs->IconChangeTable[SC_SPRITEMABLE] = SI_SPRITEMABLE; + // Other SC which are not necessarily associated to skills. status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION1] |= SCB_ASPD; status->dbs->ChangeFlagTable[SC_ATTHASTE_POTION2] |= SCB_ASPD; @@ -1347,6 +1368,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 in_hp, status_change_end(target, SC_CLOAKING, INVALID_TIMER); status_change_end(target, SC_CHASEWALK, INVALID_TIMER); status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER); + status_change_end(target, SC_SUHIDE, INVALID_TIMER); if ((sce=sc->data[SC_ENDURE]) && !sce->val4 && !sc->data[SC_LKCONCENTRATION]) { //Endure count is only reduced by non-players on non-gvg maps. //val4 signals infinite endure. [Skotlex] @@ -1802,6 +1824,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, uin (sc->data[SC_TRICKDEAD] && skill_id != NV_TRICKDEAD) || (sc->data[SC_AUTOCOUNTER] && !flag && skill_id) || (sc->data[SC_GOSPEL] && sc->data[SC_GOSPEL]->val4 == BCT_SELF && skill_id != PA_GOSPEL) + || (sc->data[SC_SUHIDE] && skill_id != SU_HIDE) ) return 0; @@ -2246,14 +2269,14 @@ unsigned int status_get_base_maxsp(const struct map_session_data *sd, const stru nullpo_ret(sd); nullpo_ret(st); - val = pc->class2idx(sd->status.class_); + val = pc->class2idx(sd->status.class); val = status->dbs->SP_table[val][sd->status.base_level]; - if ( sd->class_&JOBL_UPPER ) + if ((sd->job & JOBL_UPPER) != 0) val += val * 25 / 100; - else if ( sd->class_&JOBL_BABY ) + else if ((sd->job & JOBL_BABY) != 0) val = val * 70 / 100; - if ( (sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->famerank(sd->status.char_id, MAPID_TAEKWON) ) + if ((sd->job & MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->fame_rank(sd->status.char_id, RANKTYPE_TAEKWON) > 0) val *= 3; //Triple max SP for top ranking Taekwons over level 90. val += val * st->int_ / 100; @@ -2267,20 +2290,20 @@ unsigned int status_get_base_maxhp(const struct map_session_data *sd, const stru nullpo_ret(sd); nullpo_ret(st); - val = pc->class2idx(sd->status.class_); + val = pc->class2idx(sd->status.class); val = status->dbs->HP_table[val][sd->status.base_level]; - if ( (sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99 ) + if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->status.base_level >= 99) val += 2000; //Supernovice lvl99 hp bonus. - if ( (sd->class_&MAPID_THIRDMASK) == MAPID_SUPER_NOVICE_E && sd->status.base_level >= 150 ) + if ((sd->job & MAPID_THIRDMASK) == MAPID_SUPER_NOVICE_E && sd->status.base_level >= 150) val += 2000; //Extented Supernovice lvl150 hp bonus. - if ( sd->class_&JOBL_UPPER ) + if ((sd->job & JOBL_UPPER) != 0) val += val * 25 / 100; //Trans classes get a 25% hp bonus - else if ( sd->class_&JOBL_BABY ) + else if ((sd->job & JOBL_BABY) != 0) 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) ) + if ((sd->job & MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc->fame_rank(sd->status.char_id, RANKTYPE_TAEKWON)) val *= 3; //Triple max HP for top ranking Taekwons over level 90. val += val * st->vit / 100; // +1% per each point of VIT @@ -2319,7 +2342,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) pc->calc_skilltree(sd); // SkillTree calculation - sd->max_weight = status->dbs->max_weight_base[pc->class2idx(sd->status.class_)]+sd->status.str*300; + sd->max_weight = status->dbs->max_weight_base[pc->class2idx(sd->status.class)]+sd->status.str*300; if(opt&SCO_FIRST) { //Load Hp/SP from char-received data. @@ -2381,9 +2404,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) //Give them all modes except these (useful for clones) bstatus->mode = MD_MASK&~(MD_BOSS|MD_PLANT|MD_DETECTOR|MD_ANGRY|MD_TARGETWEAK); - bstatus->size = (sd->class_&JOBL_BABY)?SZ_SMALL:SZ_MEDIUM; + bstatus->size = ((sd->job & JOBL_BABY) != 0 || (sd->job & MAPID_BASEMASK) == MAPID_SUMMONER)?SZ_SMALL:SZ_MEDIUM; if (battle_config.character_size && (pc_isridingpeco(sd) || pc_isridingdragon(sd))) { //[Lupus] - if (sd->class_&JOBL_BABY) { + if ((sd->job & JOBL_BABY) != 0) { if (battle_config.character_size&SZ_BIG) bstatus->size++; } else { @@ -2393,7 +2416,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) } bstatus->aspd_rate = 1000; bstatus->ele_lv = 1; - bstatus->race = RC_PLAYER; + bstatus->race = ((sd->job & MAPID_BASEMASK) == MAPID_SUMMONER)?RC_BRUTE:RC_PLAYER; // Autobonus pc->delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true); @@ -2487,8 +2510,9 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) if (sd->status.inventory[index].card[0]==CARD0_FORGE) { // Forged weapon wd->star += (sd->status.inventory[index].card[1]>>8); - if(wd->star >= 15) wd->star = 40; // 3 Star Crumbs now give +40 dmg - if(pc->famerank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]) ,MAPID_BLACKSMITH)) + if (wd->star >= 15) + wd->star = 40; // 3 Star Crumbs now give +40 dmg + if (pc->fame_rank(MakeDWord(sd->status.inventory[index].card[2],sd->status.inventory[index].card[3]), RANKTYPE_BLACKSMITH) > 0) wd->star += 10; if (!wa->ele) //Do not overwrite element from previous bonuses. @@ -2663,7 +2687,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) // ----- STATS CALCULATION ----- // Job bonuses - index = pc->class2idx(sd->status.class_); + index = pc->class2idx(sd->status.class); for (i = 0; i < sd->status.job_level && i < MAX_LEVEL; i++) { if(!status->dbs->job_bonus[index][i]) continue; @@ -2678,7 +2702,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) } // If a Super Novice has never died and is at least joblv 70, he gets all stats +10 - if((sd->class_&MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->die_counter == 0 && sd->status.job_level >= 70) { + if ((sd->job & MAPID_UPPERMASK) == MAPID_SUPER_NOVICE && sd->die_counter == 0 && sd->status.job_level >= 70) { bstatus->str += 10; bstatus->agi += 10; bstatus->vit += 10; @@ -2696,6 +2720,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) bstatus->dex += skill_lv; if((skill_lv = pc->checkskill(sd,RA_RESEARCHTRAP))>0) bstatus->int_ += skill_lv; + if ((pc->checkskill(sd,SU_POWEROFLAND)) > 0) + bstatus->int_ += 20; // Bonuses from cards and equipment as well as base stat, remember to avoid overflows. i = bstatus->str + sd->status.str + sd->param_bonus[0] + sd->param_equip[0]; @@ -2733,9 +2759,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) bstatus->max_hp = (unsigned int)cap_value(i64, 0, INT_MAX); // Absolute modifiers from passive skills - if((skill_lv=pc->checkskill(sd,CR_TRUST))>0) + if ((skill_lv=pc->checkskill(sd,CR_TRUST)) > 0) bstatus->max_hp += skill_lv*200; + if ((pc->checkskill(sd,SU_SPRITEMABLE)) > 0) + bstatus->max_hp += 1000; + // Apply relative modifiers from equipment if(sd->hprate < 0) sd->hprate = 0; @@ -2768,6 +2797,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) bstatus->max_sp += 200 + 20 * skill_lv; if( (skill_lv = pc->checkskill(sd,WM_LESSON)) > 0 ) bstatus->max_sp += 30 * skill_lv; + if ((pc->checkskill(sd,SU_SPRITEMABLE)) > 0) + bstatus->max_sp += 100; // Apply relative modifiers from equipment if(sd->sprate < 0) @@ -2790,7 +2821,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) bstatus->hp = bstatus->max_hp; bstatus->sp = bstatus->max_sp; } else { - if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2) + if ((sd->job & MAPID_BASEMASK) == MAPID_NOVICE && (sd->job & JOBL_2) == 0 && battle_config.restart_hp_rate < 50) bstatus->hp = bstatus->max_hp>>1; else @@ -2840,6 +2871,8 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) sd->critical_rate = 0; if(sd->critical_rate != 100) bstatus->cri = bstatus->cri * sd->critical_rate/100; + if (pc->checkskill(sd, SU_POWEROFLIFE) > 0) + bstatus->cri += 20; if(sd->flee2_rate < 0) sd->flee2_rate = 0; @@ -2872,14 +2905,18 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) bstatus->hit += 3*skill_lv; if((sd->status.weapon == W_MACE || sd->status.weapon == W_2HMACE) && (skill_lv = pc->checkskill(sd,NC_TRAININGAXE)) > 0) bstatus->hit += 2*skill_lv; + if (pc->checkskill(sd, SU_POWEROFLIFE) > 0) + bstatus->hit += 20; // ----- FLEE CALCULATION ----- // Absolute modifiers from passive skills if((skill_lv=pc->checkskill(sd,TF_MISS))>0) - bstatus->flee += skill_lv*(sd->class_&JOBL_2 && (sd->class_&MAPID_BASEMASK) == MAPID_THIEF? 4 : 3); + bstatus->flee += skill_lv*((sd->job & JOBL_2) != 0 && (sd->job & MAPID_BASEMASK) == MAPID_THIEF? 4 : 3); if((skill_lv=pc->checkskill(sd,MO_DODGE))>0) bstatus->flee += (skill_lv*3)>>1; + if (pc->checkskill(sd, SU_POWEROFLIFE) > 0) + bstatus->flee += 20; // ----- EQUIPMENT-DEF CALCULATION ----- // Apply relative modifiers from equipment @@ -2922,7 +2959,7 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) // Basic ASPD value i = status->base_amotion_pc(sd,bstatus); - bstatus->amotion = cap_value(i,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000); + bstatus->amotion = cap_value(i,((sd->job & JOBL_THIRD) != 0 ? battle_config.max_third_aspd : battle_config.max_aspd),2000); // Relative modifiers from passive skills #ifndef RENEWAL_ASPD @@ -3175,6 +3212,12 @@ int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt) clif->updatestatus(sd,SP_CARTINFO); } + // Spirit Marble status activates automatically for a infinite + // amount of time when the skill is learned. Felt this was the + // best place to put this. [Rytech] + if (pc->checkskill(sd, SU_SPRITEMABLE)) + sc_start(&sd->bl, &sd->bl, SC_SPRITEMABLE, 100, 1, INFINITE_DURATION); + calculating = 0; return 0; @@ -3520,7 +3563,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str || sc->data[SC_OBLIVIONCURSE] != NULL || sc->data[SC_MAXIMIZEPOWER] != NULL || sc->data[SC_REBOUND] != NULL - || (bl->type == BL_PC && (BL_UCAST(BL_PC, bl)->class_&MAPID_UPPERMASK) == MAPID_MONK + || (bl->type == BL_PC && (BL_UCAST(BL_PC, bl)->job & MAPID_UPPERMASK) == MAPID_MONK && (sc->data[SC_EXTREMITYFIST] != NULL || (sc->data[SC_EXPLOSIONSPIRITS] != NULL && (sc->data[SC_SOULLINK] == NULL || sc->data[SC_SOULLINK]->val2 != SL_MONK) @@ -3584,6 +3627,10 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str regen->rate.hp += regen->rate.hp * sc->data[SC_BUCHEDENOEL]->val1 / 100; regen->rate.sp += regen->rate.sp * sc->data[SC_BUCHEDENOEL]->val2 / 100; } + if (sc->data[SC_CATNIPPOWDER]) { + regen->rate.hp *= 2; + regen->rate.sp *= 2; + } } #define status_get_homstr(st, hd) ((st)->str + (hd)->homunculus.str_value) @@ -3806,13 +3853,15 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) } if(flag&SCB_CRI && bst->cri) { - if (st->luk == bst->luk) + if (st->luk == bst->luk) { st->cri = status->calc_critical(bl, sc, bst->cri, true); - else + } else { st->cri = status->calc_critical(bl, sc, bst->cri + 3*(st->luk - bst->luk), true); + } + if (battle_config.show_katar_crit_bonus && bl->type == BL_PC && BL_UCAST(BL_PC, bl)->status.weapon == W_KATAR) { + st->cri *= 2; + } } - if (battle_config.show_katar_crit_bonus && bl->type == BL_PC && BL_UCAST(BL_PC, bl)->status.weapon == W_KATAR) - st->cri <<= 1; if(flag&SCB_FLEE2 && bst->flee2) { if (st->luk == bst->luk) @@ -3960,7 +4009,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag) #endif amotion = status->calc_fix_aspd(bl, sc, amotion); if (sd != NULL) { - st->amotion = cap_value(amotion, ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd), 2000); + st->amotion = cap_value(amotion, ((sd->job & JOBL_THIRD) != 0 ? battle_config.max_third_aspd : battle_config.max_aspd), 2000); } else { st->amotion = cap_value(amotion, battle_config.max_aspd, 2000); } @@ -4239,11 +4288,11 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) nullpo_ret(sd); nullpo_ret(st); - amotion = status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1]; + amotion = status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype1]; if ( sd->status.weapon > MAX_SINGLE_WEAPON_TYPE) - amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2] / 4; + amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype2] / 4; if ( sd->status.shield ) - amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class_)][MAX_SINGLE_WEAPON_TYPE]; + amotion += status->dbs->aspd_base[pc->class2idx(sd->status.class)][MAX_SINGLE_WEAPON_TYPE]; switch ( sd->status.weapon ) { case W_BOW: case W_MUSICAL: @@ -4267,8 +4316,8 @@ int status_base_amotion_pc(struct map_session_data *sd, struct status_data *st) #else // base weapon delay amotion = (sd->status.weapon < MAX_SINGLE_WEAPON_TYPE) - ? (status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->status.weapon]) // single weapon - : (status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype1] + status->dbs->aspd_base[pc->class2idx(sd->status.class_)][sd->weapontype2]) * 7 / 10; // dual-wield + ? (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->status.weapon]) // single weapon + : (status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype1] + status->dbs->aspd_base[pc->class2idx(sd->status.class)][sd->weapontype2]) * 7 / 10; // dual-wield // percentual delay reduction from stats amotion -= amotion * (4 * st->agi + st->dex) / 1000; @@ -4579,9 +4628,12 @@ unsigned short status_calc_agi(struct block_list *bl, struct status_change *sc, if (sc->data[SC_2011RWC]) agi += sc->data[SC_2011RWC]->val1; - if(sc->data[SC_MARSHOFABYSS]) + if (sc->data[SC_MARSHOFABYSS]) agi -= agi * sc->data[SC_MARSHOFABYSS]->val2 / 100; + if (sc->data[SC_ARCLOUSEDASH]) + agi += sc->data[SC_ARCLOUSEDASH]->val2; + return (unsigned short)cap_value(agi,0,USHRT_MAX); } @@ -4914,6 +4966,9 @@ unsigned short status_calc_batk(struct block_list *bl, struct status_change *sc, if (sc->data[SC_STEAMPACK]) batk += sc->data[SC_STEAMPACK]->val1; + if (sc->data[SC_SHRIMP]) + batk += batk * sc->data[SC_SHRIMP]->val2 / 100; + return (unsigned short)cap_value(batk,0,USHRT_MAX); } @@ -5006,6 +5061,8 @@ unsigned short status_calc_watk(struct block_list *bl, struct status_change *sc, watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100; if( sc->data[SC_FLASHCOMBO] ) watk += sc->data[SC_FLASHCOMBO]->val2; + if (sc->data[SC_CATNIPPOWDER]) + watk -= watk * sc->data[SC_CATNIPPOWDER]->val2 / 100; return (unsigned short)cap_value(watk,0,USHRT_MAX); } @@ -5033,6 +5090,8 @@ unsigned short status_calc_ematk(struct block_list *bl, struct status_change *sc matk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1; //70 lvl1, 100lvl2 if(sc->data[SC_IZAYOI]) matk += 25 * sc->data[SC_IZAYOI]->val1; + if (sc->data[SC_SHRIMP]) + matk += matk * sc->data[SC_SHRIMP]->val2 / 100; return (unsigned short)cap_value(matk,0,USHRT_MAX); #else return 0; @@ -5719,6 +5778,8 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc if (sc->data[SC_DEC_AGI] || sc->data[SC_QUAGMIRE] || sc->data[SC_DONTFORGETME]) return 0; } + if (sc->data[SC_CATNIPPOWDER]) + val = max(val, sc->data[SC_CATNIPPOWDER]->val3); if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // permanent item-based speedup val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate ); @@ -5741,7 +5802,7 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc val = max( val, 2 * sc->data[SC_WINDWALK]->val1 ); if( sc->data[SC_CARTBOOST] ) val = max( val, 20 ); - if( sd && (sd->class_&MAPID_UPPERMASK) == MAPID_ASSASSIN && pc->checkskill(sd,TF_MISS) > 0 ) + if (sd != NULL && (sd->job & MAPID_UPPERMASK) == MAPID_ASSASSIN && pc->checkskill(sd,TF_MISS) > 0) val = max( val, 1 * pc->checkskill(sd,TF_MISS) ); if( sc->data[SC_CLOAKING] && (sc->data[SC_CLOAKING]->val4&1) == 1 ) val = max( val, sc->data[SC_CLOAKING]->val1 >= 10 ? 25 : 3 * sc->data[SC_CLOAKING]->val1 - 3 ); @@ -5769,6 +5830,8 @@ unsigned short status_calc_speed(struct block_list *bl, struct status_change *sc val = max(val, sc->data[SC_MOVHASTE_HORSE]->val1); if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate < 0 ) // permanent item-based speedup val = max( val, -(sd->bonus.speed_rate + sd->bonus.speed_add_rate) ); + if (sc->data[SC_ARCLOUSEDASH]) + val = max(val, sc->data[SC_ARCLOUSEDASH]->val3); speed_rate -= val; } @@ -6368,8 +6431,8 @@ int status_get_class(const struct block_list *bl) { nullpo_ret(bl); switch (bl->type) { - case BL_PC: return BL_UCCAST(BL_PC, bl)->status.class_; - case BL_MOB: return BL_UCCAST(BL_MOB, bl)->vd->class_; //Class used on all code should be the view class of the mob. + case BL_PC: return BL_UCCAST(BL_PC, bl)->status.class; + case BL_MOB: return BL_UCCAST(BL_MOB, bl)->vd->class; //Class used on all code should be the view class of the mob. case BL_PET: return BL_UCCAST(BL_PET, bl)->pet.class_; case BL_HOM: return BL_UCCAST(BL_HOM, bl)->homunculus.class_; case BL_MER: return BL_UCCAST(BL_MER, bl)->mercenary.class_; @@ -6764,7 +6827,7 @@ void status_set_viewdata(struct block_list *bl, int class_) break; } } - sd->vd.class_ = class_; + sd->vd.class = class_; clif->get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield); sd->vd.head_top = sd->status.head_top; sd->vd.head_mid = sd->status.head_mid; @@ -6816,7 +6879,7 @@ void status_set_viewdata(struct block_list *bl, int class_) struct pet_data *pd = BL_UCAST(BL_PET, bl); if (vd != NULL) { memcpy(&pd->vd, vd, sizeof(struct view_data)); - if (!pc->db_checkid(vd->class_)) { + if (!pc->db_checkid(vd->class)) { pd->vd.hair_style = battle_config.pet_hair_style; if(pd->pet.equip) { pd->vd.head_bottom = itemdb_viewid(pd->pet.equip); @@ -7505,6 +7568,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t return 0; break; case SC_KYRIE: + case SC_TUNAPARTY: if (bl->type == BL_MOB) return 0; break; @@ -7768,12 +7832,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t case SC_OBLIVIONCURSE: case SC_LEECHESEND: - // Ranger Effects + // Ranger Effects case SC_WUGBITE: case SC_ELECTRICSHOCKER: case SC_MAGNETICFIELD: - // Masquerades + // Masquerades case SC__ENERVATION: case SC__GROOMY: case SC__LAZINESS: @@ -7784,7 +7848,9 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t // Other Effects case SC_VACUUM_EXTREME: case SC_NETHERWORLD: - + case SC_FRESHSHRIMP: + case SC_SV_ROOTTWIST: + case SC_BITESCAR: return 0; } } @@ -8178,12 +8244,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t int i; for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } else if (bl->type == BL_MER) { struct mercenary_data *mc = BL_UCAST(BL_MER, bl); if (mc->devotion_flag && (tsd = mc->master) != NULL) { - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_ALL); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, val3, val4, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } } @@ -8282,12 +8348,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t int i; for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } else if (bl->type == BL_MER) { struct mercenary_data *mc = BL_UCAST(BL_MER, bl); if (mc->devotion_flag && (tsd = mc->master) != NULL) { - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } } @@ -8336,7 +8402,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t #endif break; case SC_NJ_SUITON: - if (!val2 || (sd && (sd->class_&MAPID_BASEMASK) == MAPID_NINJA)) { + if (val2 == 0 || (sd != NULL && (sd->job & MAPID_BASEMASK) == MAPID_NINJA)) { //No penalties. val2 = 0; //Agi penalty val3 = 0; //Walk speed penalty @@ -8546,12 +8612,12 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if( sd ) { for( i = 0; i < MAX_PC_DEVOTION; i++ ) { if (sd->devotion[i] && (tsd = map->id2sd(sd->devotion[i])) != NULL) - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } else if (bl->type == BL_MER) { struct mercenary_data *mc = BL_UCAST(BL_MER, bl); if (mc->devotion_flag && (tsd = mc->master) != NULL) { - status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_ALL); + status->change_start(bl, &tsd->bl, type, 10000, val1, val2, 0, 0, tick, SCFLAG_NOAVOID|SCFLAG_NOICON); } } } @@ -9742,6 +9808,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t if (!mob->db_checkid(val1)) val1 = MOBID_PORING; break; + case SC_SPRITEMABLE: case SC_ALL_RIDING: tick = INFINITE_DURATION; break; @@ -9752,6 +9819,36 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t **/ val2 = 20+(20*val1); break; + /** + * Summoner + */ + case SC_FRESHSHRIMP: + val4 = tick / (10000 - ((val1 - 1) * 1000)); + tick_time = 10000 - ((val1 - 1) * 1000); + if (val4 <= 0) // Prevents a negeative value from happening + val4 = 0; + break; + case SC_ARCLOUSEDASH: + val2 = 15 + 5 * val1; // AGI + val3 = 25; // Move speed increase + if (sd != NULL && (sd->job & MAPID_BASEMASK) == MAPID_SUMMONER) + val4 = 10; // Ranged ATK increase + break; + case SC_TUNAPARTY: + val2 = (st->max_hp * (val1 * 10) / 100); // %Max HP to absorb + break; + case SC_BITESCAR: + val2 = 2 * val1; // MHP% damage + val4 = tick / 1000; + tick_time = 1000; + break; + case SC_SHRIMP: + val2 = 10; // BATK%, MATK% + break; + case SC_CATNIPPOWDER: + val2 = 50; // WATK%, MATK% + val3 = 25 * val1; // Move speed reduction + break; default: if (calc_flag == SCB_NONE && status->dbs->SkillChangeTable[type] == 0 && status->dbs->IconChangeTable[type] == 0) { //Status change with no calc, no icon, and no skill associated...? @@ -9767,7 +9864,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t case SC_HANBOK: case SC_OKTOBERFEST: if( !vd ) break; - clif->changelook(bl,LOOK_BASE,vd->class_); + clif->changelook(bl, LOOK_BASE, vd->class); clif->changelook(bl,LOOK_WEAPON,0); clif->changelook(bl,LOOK_SHIELD,0); clif->changelook(bl,LOOK_CLOTHES_COLOR,vd->cloth_color); @@ -9964,6 +10061,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t case SC_NEEDLE_OF_PARALYZE: case SC_DEATHBOUND: case SC_NETHERWORLD: + case SC_SV_ROOTTWIST: unit->stop_walking(bl, STOPWALKING_FLAG_FIXPOS); break; case SC_ANKLESNARE: @@ -9978,6 +10076,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t case SC_CAMOUFLAGE: case SC_SIREN: case SC_ALL_RIDING: + case SC_SUHIDE: unit->stop_attack(bl); break; case SC_SILENCE: @@ -10165,7 +10264,7 @@ int status_change_start(struct block_list *src, struct block_list *bl, enum sc_t clif->changeoption(bl); if( sd && opt_flag&0x4 ) { if (vd) - clif->changelook(bl,LOOK_BASE,vd->class_); + clif->changelook(bl, LOOK_BASE, vd->class); clif->changelook(bl,LOOK_WEAPON,0); clif->changelook(bl,LOOK_SHIELD,0); if (vd) @@ -10821,10 +10920,11 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const break; case SC_NEUTRALBARRIER_MASTER: case SC_STEALTHFIELD_MASTER: - if( sce->val2 ) { + case SC_SV_ROOTTWIST: + if (sce->val2) { struct skill_unit_group* group = skill->id2group(sce->val2); sce->val2 = 0; - if( group ) /* might have been cleared before status ended, e.g. land protector */ + if (group) /* might have been cleared before status ended, e.g. land protector */ skill->del_unitgroup(group,ALC_MARK); } break; @@ -11102,7 +11202,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const else if(opt_flag) { clif->changeoption(bl); if( sd && opt_flag&0x4 ) { - clif->changelook(bl,LOOK_BASE,sd->vd.class_); + clif->changelook(bl, LOOK_BASE, sd->vd.class); clif->get_weapon_view(sd, &sd->vd.weapon, &sd->vd.shield); clif->changelook(bl,LOOK_WEAPON,sd->vd.weapon); clif->changelook(bl,LOOK_SHIELD,sd->vd.shield); @@ -12016,6 +12116,19 @@ int status_change_timer(int tid, int64 tick, int id, intptr_t data) return 0; } break; + case SC_FRESHSHRIMP: + if (--(sce->val4) >= 0) { + status_heal(bl, st->max_hp / 100, 0, 2); + sc_timer_next((10000 - ((sce->val1 - 1) * 1000)) + tick, status->change_timer, bl->id, data); + } + break; + case SC_BITESCAR: + if (--(sce->val4) >= 0) { + status_percent_damage(bl, bl, -(sce->val2), 0, 0); + sc_timer_next(1000 + tick, status->change_timer, bl->id, data); + return 0; + } + break; } // default for all non-handled control paths is to end the status @@ -12202,6 +12315,10 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m // Any +MATK you get from skills and cards, including cards in weapon, is added here. if ( sd && sd->bonus.ematk > 0 && flag != 3 ) *matk_min += sd->bonus.ematk; + if (sd && pc->checkskill(sd, SU_POWEROFLAND) > 0) { + if (pc->checkskill(sd, SU_SV_STEMSPEAR) == 5 && pc->checkskill(sd, SU_CN_POWDERING) == 5 && pc->checkskill(sd, SU_CN_METEOR) == 5 && pc->checkskill(sd, SU_SV_ROOTTWIST) == 5) + *matk_min += *matk_min * 20 / 100; + } if ( flag != 3 ) *matk_min = status->calc_ematk(bl, sc, *matk_min); @@ -12213,6 +12330,8 @@ void status_get_matk_sub(struct block_list *bl, int flag, unsigned short *matk_m if ( (st->rhw.matk + st->lhw.matk) > 0 ) { int wMatk = st->rhw.matk + st->lhw.matk; // Left and right matk stacks int variance = wMatk * st->rhw.wlv / 10; // Only use right hand weapon level + if (sc != NULL && sc->data[SC_CATNIPPOWDER]) + wMatk -= wMatk * sc->data[SC_CATNIPPOWDER]->val2 / 100; *matk_min += wMatk - variance; *matk_max += wMatk + variance; } @@ -12682,7 +12801,7 @@ int status_natural_heal(struct block_list* bl, va_list args) if ((rate = pc->checkskill(sd,TK_SPTIME))) sc_start(bl,bl,status->skill2sc(TK_SPTIME), 100,rate,skill->get_time(TK_SPTIME, rate)); - if ((sd->class_&MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR + if ((sd->job & MAPID_UPPERMASK) == MAPID_STAR_GLADIATOR &&rnd()%10000 < battle_config.sg_angel_skill_ratio ) { //Angel of the Sun/Moon/Star @@ -12952,15 +13071,15 @@ void status_read_job_db(void) /* [malufett/Hercules] */ return; while ( (jdb = libconfig->setting_get_elem(job_db_conf.root, i++)) ) { - int class_, idx; + int class, idx; const char *name = config_setting_name(jdb); - if ( (class_ = pc->check_job_name(name)) == -1 ) { + if ((class = pc->check_job_name(name)) == -1) { ShowWarning("pc_read_job_db: '%s' unknown job name!\n", name); continue; } - idx = pc->class2idx(class_); + idx = pc->class2idx(class); status->read_job_db_sub(idx, name, jdb); } ShowStatus("Done reading '"CL_WHITE"%d"CL_RESET"' entries in '"CL_WHITE"%s"CL_RESET"'.\n", i, config_filename); @@ -12969,17 +13088,16 @@ void status_read_job_db(void) /* [malufett/Hercules] */ bool status_readdb_job2(char* fields[], int columns, int current) { - int idx, class_, i; + int idx, class, i; nullpo_retr(false, fields); - class_ = atoi(fields[0]); + class = atoi(fields[0]); - if(!pc->db_checkid(class_)) - { - ShowWarning("status_readdb_job2: Invalid job class %d specified.\n", class_); + if (!pc->db_checkid(class)) { + ShowWarning("status_readdb_job2: Invalid job class %d specified.\n", class); return false; } - idx = pc->class2idx(class_); + idx = pc->class2idx(class); for(i = 1; i < columns; i++) { |