summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c248
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++)
{