summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
authorFlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-01-03 05:07:58 +0000
committerFlavioJS <FlavioJS@54d463be-8e91-2dee-dedb-b68131a5f0ec>2007-01-03 05:07:58 +0000
commite0afeaacc4f25cc8f1dbdb0939ed7d262711d62b (patch)
treeea1cca8d2e15b69f57a78bc784971506dd6d9ecb /src/map/status.c
parentf68bd7c915dc631d452b6ea2ac21cdf75bc26fe4 (diff)
downloadhercules-e0afeaacc4f25cc8f1dbdb0939ed7d262711d62b.tar.gz
hercules-e0afeaacc4f25cc8f1dbdb0939ed7d262711d62b.tar.bz2
hercules-e0afeaacc4f25cc8f1dbdb0939ed7d262711d62b.tar.xz
hercules-e0afeaacc4f25cc8f1dbdb0939ed7d262711d62b.zip
- JK_JOINTBEAT as described in:
http://www.ragnainfo.net/wiki/index.php/Vital_Strike Although not clear, it's being assumed that the 2x damage is only for the break neck ailment. Reported by zaibach in http://www.eathena.ws/board/index.php?s=&showtopic=93873&view=findpost&p=727844 Note: this should be reviewed by Skotlex or someone that knows this part of the code. git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@9609 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c192
1 files changed, 96 insertions, 96 deletions
diff --git a/src/map/status.c b/src/map/status.c
index 72a506e8e..a941d265e 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -528,7 +528,7 @@ int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
{
struct status_data *status;
-
+
status = status_get_status_data(bl);
if (status == &dummy_status)
return 0;
@@ -551,7 +551,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
if(sp && !(target->type&BL_CONSUME))
sp = 0; //Not a valid SP target.
-
+
if (hp < 0) { //Assume absorbed damage.
status_heal(target, -hp, 0, 1);
hp = 0;
@@ -561,16 +561,16 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
status_heal(target, 0, -sp, 1);
sp = 0;
}
-
+
if (!hp && !sp)
return 0;
-
+
if (target->type == BL_SKILL)
return skill_unit_ondamaged((struct skill_unit *)target, src, hp, gettick());
-
+
status = status_get_status_data(target);
-
+
if (status == &dummy_status || !status->hp)
return 0; //Invalid targets: no damage or dead
@@ -646,10 +646,10 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
if (flag&2) return 0;
sp = status->sp;
}
-
+
status->hp-= hp;
status->sp-= sp;
-
+
if (sc && hp && status->hp) {
if (sc->data[SC_AUTOBERSERK].timer != -1 &&
(sc->data[SC_PROVOKE].timer==-1 || !sc->data[SC_PROVOKE].val2) &&
@@ -659,7 +659,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
status->hp <= 100)
status_change_end(target, SC_BERSERK, -1);
}
-
+
switch (target->type)
{
case BL_MOB:
@@ -703,7 +703,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
if(!flag) //Death cancelled.
return hp+sp;
-
+
//Normal death
status->hp = 0;
if (battle_config.clear_unit_ondeath &&
@@ -736,7 +736,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
skill_unit_move(target,gettick(),4);
skill_cleartimerskill(target);
}
-
+
return hp+sp;
}
@@ -751,7 +751,7 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
if (status == &dummy_status || !status->hp)
return 0;
-
+
sc = status_get_sc(bl);
if (sc && !sc->count)
sc = NULL;
@@ -760,12 +760,11 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
status_damage(NULL, bl, -hp, 0, 0, 1);
hp = 0;
}
-
+
if(hp) {
if (!(flag&1) && sc && sc->data[SC_BERSERK].timer!=-1)
hp = 0;
-
if((unsigned int)hp > status->max_hp - status->hp)
hp = status->max_hp - status->hp;
}
@@ -880,7 +879,7 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
status = status_get_status_data(bl);
if (status == &dummy_status)
return 0; //Invalid target.
-
+
hp = status->max_hp * per_hp/100;
sp = status->max_sp * per_sp/100;
@@ -889,7 +888,7 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
if(sp > status->max_sp - status->sp)
sp = status->max_sp - status->sp;
-
+
status->hp += hp;
status->sp += sp;
@@ -930,7 +929,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
if (src && status_isdead(src))
return 0;
-
+
if (!skill_num) { //Normal attack checks.
if (!(status->mode&MD_CANATTACK))
return 0; //This mode is only needed for melee attacking.
@@ -961,7 +960,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
}
if (src) sc = status_get_sc(src);
-
+
if(sc && sc->count)
{
if(sc->opt1 >0)
@@ -986,7 +985,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
clif_emotion(src, 3);
return 0;
}
-
+
if (sc->data[SC_BLADESTOP].timer != -1) {
switch (sc->data[SC_BLADESTOP].val1)
{
@@ -1079,7 +1078,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
//You cannot hide from ground skills.
if(skill_get_pl(skill_num) == ELE_EARTH)
hide_flag &= ~OPTION_HIDE;
-
+
switch (target->type)
{
case BL_PC:
@@ -1132,7 +1131,7 @@ int status_check_visibility(struct block_list *src, struct block_list *target)
if (src->m != target->m || !check_distance_bl(src, target, view_range))
return 0;
-
+
switch (target->type)
{ //Check for chase-walk/hiding/cloaking opponents.
case BL_PC:
@@ -1271,13 +1270,13 @@ int status_calc_mob(struct mob_data* md, int first)
if (md->guardian_data && md->guardian_data->guardup_lv)
flag|=4;
-
+
if (battle_config.slaves_inherit_speed && md->master_id)
flag|=8;
-
+
if (md->master_id && md->special_state.ai>1)
flag|=16;
-
+
if (!flag)
{ //No special status required.
if (md->base_status) {
@@ -1290,10 +1289,10 @@ int status_calc_mob(struct mob_data* md, int first)
}
if (!md->base_status)
md->base_status = aCalloc(1, sizeof(struct status_data));
-
+
status = md->base_status;
memcpy(status, &md->db->status, sizeof(struct status_data));
-
+
if (flag&(8|16))
mbl = map_id2bl(md->master_id);
@@ -1304,7 +1303,7 @@ int status_calc_mob(struct mob_data* md, int first)
battle_config.slaves_inherit_speed&(mstatus->mode&MD_CANMOVE?1:2))
status->speed = mstatus->speed;
}
-
+
if (flag&16 && mbl)
{ //Max HP setting from Summon Flora/marine Sphere
struct unit_data *ud = unit_bl2ud(mbl);
@@ -1338,8 +1337,8 @@ int status_calc_mob(struct mob_data* md, int first)
status->sp = status->max_sp;
status->speed -= diff;
}
-
-
+
+
if (flag&2)
{ // change for sized monsters [Valaris]
if (md->special_state.size==1) {
@@ -1409,7 +1408,7 @@ int status_calc_mob(struct mob_data* md, int first)
//Skotlex: Calculates the stats of the given pet.
int status_calc_pet(struct pet_data *pd, int first)
{
-
+
nullpo_retr(0, pd);
if (first) {
@@ -1439,7 +1438,7 @@ int status_calc_pet(struct pet_data *pd, int first)
status->int_ = (bstat->int_*lv)/pd->db->lv;
status->dex = (bstat->dex*lv)/pd->db->lv;
status->luk = (bstat->luk*lv)/pd->db->lv;
-
+
status->rhw.atk = cap_value(status->rhw.atk, 1, battle_config.pet_max_atk1);
status->rhw.atk2 = cap_value(status->rhw.atk2, 2, battle_config.pet_max_atk2);
status->str = cap_value(status->str,1,battle_config.pet_max_stats);
@@ -1502,7 +1501,7 @@ static unsigned int status_base_pc_maxsp(struct map_session_data* sd, struct sta
val -= val * 30/100;
if ((sd->class_&MAPID_UPPERMASK) == MAPID_TAEKWON && sd->status.base_level >= 90 && pc_famerank(sd->status.char_id, MAPID_TAEKWON))
val *= 3; //Triple max SP for top ranking Taekwons over level 90.
-
+
return val;
}
@@ -1529,13 +1528,13 @@ int status_calc_pc(struct map_session_data* sd,int first)
memcpy(&b_status, &sd->battle_status, sizeof(struct status_data));
memcpy(&b_lhw, &sd->battle_lhw, sizeof(struct weapon_atk));
b_status.lhw = &b_lhw;
-
+
memcpy(b_skill,&sd->status.skill,sizeof(b_skill));
b_weight = sd->weight;
b_max_weight = sd->max_weight;
-
+
pc_calc_skilltree(sd); // スキルツリ?の計算
-
+
sd->max_weight = max_weight_base[sd->status.class_]+sd->status.str*300;
if(first&1) {
@@ -1578,7 +1577,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
sd->critical_rate = sd->hit_rate = sd->flee_rate = sd->flee2_rate = 100;
sd->def_rate = sd->def2_rate = sd->mdef_rate = sd->mdef2_rate = 100;
sd->regen.state.block = 0;
-
+
// zeroed arays, order follows the order in map.h.
// add new arrays to the end of zeroed area in map.h (see comments) and size here. [zzo]
malloc_set (sd->param_bonus, 0, sizeof(sd->param_bonus)
@@ -1643,7 +1642,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
+ sizeof(sd->add_drop)
+ sizeof(sd->itemhealrate)
);
-
+
// vars zeroing. ints, shorts, chars. in that order.
malloc_set (&sd->arrow_atk, 0,sizeof(sd->arrow_atk)
+ sizeof(sd->arrow_ele)
@@ -1714,7 +1713,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
continue;
if(!sd->inventory_data[index])
continue;
-
+
status->def += sd->inventory_data[index]->def;
if(first&1 && sd->inventory_data[index]->equip_script)
@@ -1787,11 +1786,11 @@ int status_calc_pc(struct map_session_data* sd,int first)
return 1;
}
}
-
+
//Store equipment script bonuses
memcpy(sd->param_equip,sd->param_bonus,sizeof(sd->param_equip));
malloc_set(sd->param_bonus, 0, sizeof(sd->param_bonus));
-
+
status->def += (refinedef+50)/100;
//Parse Cards
@@ -1809,7 +1808,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
if(sd->inventory_data[index]) {
int j,c;
struct item_data *data;
-
+
//Card script execution.
if(itemdb_isspecial(sd->status.inventory[index].card[0]))
continue;
@@ -1848,7 +1847,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
}
}
}
-
+
if(sd->pd && battle_config.pet_status_support)
{ // Pet
struct pet_data *pd=sd->pd;
@@ -1858,7 +1857,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
pc_bonus(sd,pd->bonus->type, pd->bonus->val);
}
//param_bonus now holds card bonuses.
-
+
if(status->rhw.range < 1) status->rhw.range = 1;
if(status->lhw->range < 1) status->lhw->range = 1;
if(status->rhw.range < status->lhw->range)
@@ -1947,7 +1946,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
status->dex = cap_value(i,0,USHRT_MAX);
i = status->luk + sd->status.luk + sd->param_bonus[5] + sd->param_equip[5];
status->luk = cap_value(i,0,USHRT_MAX);
-
+
// ------ BASE ATTACK CALCULATION ------
// Base batk value is set on status_calc_misc
@@ -1981,7 +1980,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
status->max_hp = battle_config.max_hp;
else if(!status->max_hp)
status->max_hp = 1;
-
+
// ----- SP MAX CALCULATION -----
// Basic MaxSP value
@@ -2058,7 +2057,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
sd->mdef2_rate = 0;
if(sd->mdef2_rate != 100)
status->mdef2 = status->mdef2 * sd->mdef2_rate/100;
-
+
if(sd->critical_rate < 0)
sd->critical_rate = 0;
if(sd->critical_rate != 100)
@@ -2128,7 +2127,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
status->mdef2 += battle_config.over_def_bonus*(status->mdef -battle_config.max_def);
status->mdef = (signed char)battle_config.max_def;
}
-
+
// ----- WALKING SPEED CALCULATION -----
if(sd->speed_rate < 0)
@@ -2175,9 +2174,9 @@ int status_calc_pc(struct map_session_data* sd,int first)
status->aspd_rate -= ((skill+1)/2) * 10;
if(pc_isriding(sd))
status->aspd_rate += 500-100*pc_checkskill(sd,KN_CAVALIERMASTERY);
-
+
status->adelay = 2*status->amotion;
-
+
// ----- DMOTION -----
//
@@ -2263,7 +2262,7 @@ int status_calc_pc(struct map_session_data* sd,int first)
status_cpy(&sd->battle_status, status);
status_calc_bl(&sd->bl, SCB_ALL); //Status related changes.
status = &sd->battle_status; //Need to compare versus this.
-
+
// ----- CLIENT-SIDE REFRESH -----
if(memcmp(b_skill,sd->status.skill,sizeof(sd->status.skill)))
clif_skillinfoblock(sd);
@@ -2336,12 +2335,12 @@ int status_calc_homunculus(struct homun_data *hd, int first)
struct status_data b_status, *status;
struct s_homunculus *hom;
int skill;
-
+
memcpy(&b_status, &hd->base_status, sizeof(struct status_data));
hom = &hd->homunculus;
status = &hd->base_status;
-
+
status->str = hom->str / 10;
status->agi = hom->agi / 10;
status->vit = hom->vit / 10;
@@ -2377,7 +2376,7 @@ int status_calc_homunculus(struct homun_data *hd, int first)
if((skill=merc_hom_checkskill(hd,HAMI_SKIN)) > 0)
status->def += skill * 4;
-
+
if((skill = merc_hom_checkskill(hd,HVAN_INSTRUCT)) > 0)
{
status->int_ += 1 +skill/2 +skill/4 +skill/5;
@@ -2402,7 +2401,7 @@ int status_calc_homunculus(struct homun_data *hd, int first)
skill = (1000 -4*status->agi -status->dex)
*hd->homunculusDB->baseASPD/1000;
-
+
status->amotion = cap_value(skill,battle_config.max_aspd,2000);
status->adelay = status->amotion; //It seems adelay = amotion for Homunculus.
@@ -2446,11 +2445,11 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
{
struct map_session_data *sd;
int val, skill;
-
+
if (!(bl->type&BL_REGEN) || !regen)
return;
BL_CAST(BL_PC,bl,sd);
-
+
val = 1 + (status->vit/5) + (status->max_hp/200);
if (sd && sd->hprecov_rate != 100)
@@ -2466,7 +2465,7 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
val = val*sd->sprecov_rate/100;
regen->sp = cap_value(val, 1, SHRT_MAX);
-
+
if(sd)
{
struct regen_data_sub *sregen;
@@ -2489,10 +2488,10 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
if((skill=pc_checkskill(sd,NJ_NINPOU)) > 0)
val += skill*3 + (status->max_sp*skill/500);
sregen->sp = cap_value(val, 0, SHRT_MAX);
-
+
// Skill-related recovery (only when sit)
sregen = regen->ssregen;
-
+
val = 0;
if((skill=pc_checkskill(sd,MO_SPIRITSRECOVERY)) > 0)
val += skill*4 + (status->max_hp*skill/500);
@@ -2512,7 +2511,7 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
val += skill*2 + (status->max_sp*skill/500);
sregen->sp = cap_value(val, 0, SHRT_MAX);
}
-
+
if(bl->type==BL_HOM)
{
struct homun_data *hd = (TBL_HOM*)bl;
@@ -2534,7 +2533,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
{
if (!(bl->type&BL_REGEN) || !regen)
return;
-
+
regen->flag = RGN_HP|RGN_SP;
if(regen->sregen)
{
@@ -2555,7 +2554,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
regen->ssregen->rate.hp = regen->ssregen->rate.sp = 1;
}
regen->rate.hp = regen->rate.sp = 1;
-
+
if (!sc || !sc->count)
return;
@@ -2608,17 +2607,17 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
if(flag&(SCB_MAXHP|SCB_VIT))
{
flag|=SCB_MAXHP; //Ensures client-side refresh
-
+
status->max_hp = status_base_pc_maxhp(sd,status);
status->max_hp += b_status->max_hp - sd->status.max_hp;
-
+
status->max_hp = status_calc_maxhp(&sd->bl, &sd->sc, status->max_hp);
-
+
if(status->max_hp > (unsigned int)battle_config.max_hp)
status->max_hp = battle_config.max_hp;
else if(!status->max_hp)
status->max_hp = 1;
-
+
if(status->hp > status->max_hp) {
status->hp = status->max_hp;
clif_updatestatus(sd,SP_HP);
@@ -2628,17 +2627,17 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
if(flag&(SCB_MAXSP|SCB_INT))
{
flag|=SCB_MAXSP;
-
+
status->max_sp = status_base_pc_maxsp(sd,status);
status->max_sp += b_status->max_sp - sd->status.max_sp;
-
+
status->max_sp = status_calc_maxsp(&sd->bl, &sd->sc, status->max_sp);
-
+
if(status->max_sp > (unsigned int)battle_config.max_sp)
status->max_sp = battle_config.max_sp;
else if(!status->max_sp)
status->max_sp = 1;
-
+
if(status->sp > status->max_sp) {
status->sp = status->max_sp;
clif_updatestatus(sd,SP_SP);
@@ -2692,7 +2691,7 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
)) *2/3;
status->aspd_rate = status_calc_aspd_rate(&sd->bl, &sd->sc , b_status->aspd_rate);
-
+
// Apply all relative modifiers
if(status->aspd_rate != 1000)
skill = skill *status->aspd_rate/1000;
@@ -2711,7 +2710,7 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
}
}
-
+
if(flag&(SCB_AGI|SCB_DSPD)) {
if (b_status->agi == status->agi)
status->dmotion = status_calc_dmotion(&sd->bl, &sd->sc, b_status->dmotion);
@@ -2733,13 +2732,13 @@ void status_calc_bl_sub_pc(struct map_session_data *sd, unsigned long flag)
if(flag&(SCB_INT|SCB_MAXSP|SCB_VIT|SCB_MAXHP))
status_calc_regen(&sd->bl, status, &sd->regen);
-
+
if(flag&SCB_REGEN)
status_calc_regen_rate(&sd->bl, &sd->regen, &sd->sc);
-
+
if (flag == SCB_ALL)
return; //Refresh is done on invoking function (status_calc_pc)
-
+
if(flag&SCB_STR)
clif_updatestatus(sd,SP_STR);
if(flag&SCB_AGI)
@@ -2859,7 +2858,7 @@ void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
status->amotion = cap_value(skill,battle_config.max_aspd,2000);
status->adelay = 2*status->amotion;
}
-
+
if(flag&(SCB_AGI|SCB_DSPD)) {
skill = 800-status->agi*4;
status->dmotion = cap_value(skill, 400, 800);
@@ -2868,7 +2867,7 @@ void status_calc_bl_sub_hom(struct homun_data *hd, unsigned long flag) //[orn]
if(flag&(SCB_INT|SCB_MAXSP|SCB_VIT|SCB_MAXHP) && flag != SCB_ALL)
status_calc_regen(&hd->bl, status, &hd->regen);
-
+
if(flag&SCB_REGEN)
status_calc_regen_rate(&hd->bl, &hd->regen, sc);
@@ -2894,7 +2893,7 @@ void status_calc_bl(struct block_list *bl, unsigned long flag)
b_status = status_get_base_status(bl);
status = status_get_status_data(bl);
sc = status_get_sc(bl);
-
+
if (!b_status || !status)
return;
@@ -2905,12 +2904,12 @@ void status_calc_bl(struct block_list *bl, unsigned long flag)
status_calc_pc(sd,0);
return;
}
-
+
if((!bl->type&(BL_REGEN)) && (!sc || !sc->count)) { //No difference.
status_cpy(status, b_status);
return;
}
-
+
if(flag&SCB_STR) {
status->str = status_calc_str(bl, sc, b_status->str);
flag|=SCB_BATK;
@@ -3113,7 +3112,7 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
{
if(!sc || !sc->count)
return cap_value(str,1,USHRT_MAX);
-
+
if(sc->data[SC_INCALLSTATUS].timer!=-1)
str += sc->data[SC_INCALLSTATUS].val1;
if(sc->data[SC_INCSTR].timer!=-1)
@@ -3341,7 +3340,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += batk * 3;
if(sc->data[SC_BLOODLUST].timer!=-1)
batk += batk * sc->data[SC_BLOODLUST].val2/100;
- if(sc->data[SC_JOINTBEAT].timer!=-1 && sc->data[SC_JOINTBEAT].val2==4)
+ if(sc->data[SC_JOINTBEAT].timer!=-1 && sc->data[SC_JOINTBEAT].val2&BREAK_WAIST)
batk -= batk * 25/100;
if(sc->data[SC_CURSE].timer!=-1)
batk -= batk * 25/100;
@@ -3580,10 +3579,9 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
if(sc->data[SC_PROVOKE].timer!=-1)
def2 -= def2 * sc->data[SC_PROVOKE].val4/100;
if(sc->data[SC_JOINTBEAT].timer!=-1){
- if(sc->data[SC_JOINTBEAT].val2==3)
- def2 -= def2 * 50/100;
- else if(sc->data[SC_JOINTBEAT].val2==4)
- def2 -= def2 * 25/100;
+ def2 -= def2 *
+ ( ( sc->data[SC_JOINTBEAT].val2&BREAK_SHOULDER ? 50 : 0 )
+ + ( sc->data[SC_JOINTBEAT].val2&BREAK_WAIST ? 25 : 0 ) );
}
if(sc->data[SC_FLING].timer!=-1)
def2 -= def2 * (sc->data[SC_FLING].val3)/100;
@@ -3679,11 +3677,9 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
if(sc->data[SC_GOSPEL].timer!=-1 && sc->data[SC_GOSPEL].val4 == BCT_ENEMY)
speed = speed * 100/75;
if(sc->data[SC_JOINTBEAT].timer!=-1) {
- if (sc->data[SC_JOINTBEAT].val2 == 0)
- speed = speed * 100/50;
- else
- if (sc->data[SC_JOINTBEAT].val2 == 2)
- speed = speed * 100/70;
+ speed = speed * ( 100
+ - ( sc->data[SC_JOINTBEAT].val2&BREAK_ANKLE ? 50 : 0 )
+ - ( sc->data[SC_JOINTBEAT].val2&BREAK_KNEE ? 30 : 0 ));
}
if(sc->data[SC_CLOAKING].timer!=-1)
speed = speed * 100 /(
@@ -3794,9 +3790,9 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
// if(sc->data[SC_BLEEDING].timer != -1)
// aspd_rate += 250;
if(sc->data[SC_JOINTBEAT].timer!=-1) {
- if (sc->data[SC_JOINTBEAT].val2 == 1)
+ if( sc->data[SC_JOINTBEAT].val2&BREAK_WRIST )
aspd_rate += 250;
- else if (sc->data[SC_JOINTBEAT].val2 == 2)
+ if( sc->data[SC_JOINTBEAT].val2&BREAK_KNEE )
aspd_rate += 100;
}
@@ -5250,9 +5246,10 @@ int status_change_start(struct block_list *bl,int type,int rate,int val1,int val
val3 = 4*val2; //movement speed % increase is 4 times that
break;
- case SC_JOINTBEAT: // Random break [DracoRPG]
- val2 = rand()%6; //Type of break -> [0,5]
- if (val2 == 5) sc_start(bl,SC_BLEEDING,100,val1,skill_get_time2(StatusSkillChangeTable[type],val1));
+ case SC_JOINTBEAT:
+ val2 |= sc->data[SC_JOINTBEAT].val2; // stackable ailments
+ if( val2&BREAK_NECK )
+ sc_start(bl,SC_BLEEDING,100,val1,skill_get_time2(StatusSkillChangeTable[type],val1));
break;
case SC_BERSERK:
@@ -6309,6 +6306,9 @@ int status_change_end( struct block_list* bl , int type,int tid )
status_set_hp(bl, 10, 0);
status_set_sp(bl, 10, 0);
break;
+ case SC_JOINTBEAT:
+ sc->data[type].val2 = 0; // Clear stackable ailments
+ break;
}
opt_flag = 1;