summaryrefslogtreecommitdiff
path: root/src/map/status.c
diff options
context:
space:
mode:
authorglighta <glighta@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-11-01 01:40:29 +0000
committerglighta <glighta@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-11-01 01:40:29 +0000
commit85ae075fd230f7e1d08a84dde6a2cfdce8280ecd (patch)
tree566de83b27be9f1c2449ddef90a8f7a041ab2ca8 /src/map/status.c
parenta0fb6bc388fb1d4f0fcfd7d3d8af71a9c8cf86ca (diff)
downloadhercules-85ae075fd230f7e1d08a84dde6a2cfdce8280ecd.tar.gz
hercules-85ae075fd230f7e1d08a84dde6a2cfdce8280ecd.tar.bz2
hercules-85ae075fd230f7e1d08a84dde6a2cfdce8280ecd.tar.xz
hercules-85ae075fd230f7e1d08a84dde6a2cfdce8280ecd.zip
-Fix bugreport:6547 (bloodylust) upd bloodylust effect to berserk
-Fix bugreport:6208, bugreport:6805 (chaos panic) fix range effect -Partial Fix bugreport:5275 (toxin now won't interupt unbreackable castskill) -Folllow up r16847 fix UNT_ZEPHYR get some unwanted bonus, fix Insignia unit range -Add UF_RANGEDSINGLEUNIT unit propriety thx to 3ceam, workaround to fix ranged unit without timer. -Prevent WM_SOUND_OF_DESTRUCTION, SC_MANHOLE, WM_LULLABY_DEEPSLEEP being cast in non pvp map -Fix SC_MAGICMUSHROOM shouldn't force skill if sit -Replace some hardcoded mobid by enum -add some mob_is definition for quicker search (gvg and treasure) -Remove some duplicate check for status_heal (if berserk already done in status heal) -Upd few documentation git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@16855 54d463be-8e91-2dee-dedb-b68131a5f0ec
Diffstat (limited to 'src/map/status.c')
-rw-r--r--src/map/status.c555
1 files changed, 289 insertions, 266 deletions
diff --git a/src/map/status.c b/src/map/status.c
index 695548e88..e8bc3bc5e 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -174,13 +174,13 @@ static void set_sc(int skill, sc_type sc, int icon, unsigned int flag)
void initChangeTables(void) {
int i;
-
+
for (i = 0; i < SC_MAX; i++)
StatusIconChangeTable[i] = SI_BLANK;
-
+
for (i = 0; i < MAX_SKILL; i++)
SkillStatusChangeTable[i] = SC_NONE;
-
+
for (i = 0; i < SI_MAX; i++)
StatusRelevantBLTypes[i] = BL_PC;
@@ -394,9 +394,9 @@ void initChangeTables(void) {
set_sc( TK_READYCOUNTER , SC_READYCOUNTER , SI_READYCOUNTER , SCB_NONE );
set_sc( TK_DODGE , SC_DODGE , SI_DODGE , SCB_NONE );
set_sc( TK_SPTIME , SC_EARTHSCROLL , SI_EARTHSCROLL , SCB_NONE );
- add_sc( TK_SEVENWIND , SC_SEVENWIND );
- set_sc( TK_SEVENWIND , SC_GHOSTWEAPON , SI_GHOSTWEAPON , SCB_ATK_ELE );
- set_sc( TK_SEVENWIND , SC_SHADOWWEAPON , SI_SHADOWWEAPON , SCB_ATK_ELE );
+ add_sc( TK_SEVENWIND , SC_SEVENWIND );
+ set_sc( TK_SEVENWIND , SC_GHOSTWEAPON , SI_GHOSTWEAPON , SCB_ATK_ELE );
+ set_sc( TK_SEVENWIND , SC_SHADOWWEAPON , SI_SHADOWWEAPON , SCB_ATK_ELE );
set_sc( SG_SUN_WARM , SC_WARM , SI_WARM , SCB_NONE );
add_sc( SG_MOON_WARM , SC_WARM );
add_sc( SG_STAR_WARM , SC_WARM );
@@ -521,7 +521,7 @@ void initChangeTables(void) {
set_sc( GD_BATTLEORDER , SC_BATTLEORDERS , SI_BLANK , SCB_STR|SCB_INT|SCB_DEX );
set_sc( GD_REGENERATION , SC_REGENERATION , SI_BLANK , SCB_REGEN );
-
+
/**
* Rune Knight
**/
@@ -624,7 +624,7 @@ void initChangeTables(void) {
set_sc( SC_STRIPACCESSARY , SC__STRIPACCESSORY , SI_STRIPACCESSARY , SCB_DEX|SCB_INT|SCB_LUK );
set_sc_with_vfx( SC_MANHOLE , SC__MANHOLE , SI_MANHOLE , SCB_NONE );
add_sc( SC_CHAOSPANIC , SC_CONFUSION );
- set_sc( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
+ set_sc_with_vfx( SC_BLOODYLUST , SC__BLOODYLUST , SI_BLOODYLUST , SCB_DEF | SCB_DEF2 | SCB_MDEF | SCB_MDEF2 | SCB_FLEE | SCB_SPEED | SCB_ASPD | SCB_MAXHP | SCB_REGEN );
/**
* Sura
**/
@@ -673,7 +673,7 @@ void initChangeTables(void) {
set_sc( SO_FIRE_INSIGNIA , SC_FIRE_INSIGNIA , SI_FIRE_INSIGNIA , SCB_MATK | SCB_BATK | SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
set_sc( SO_WATER_INSIGNIA , SC_WATER_INSIGNIA , SI_WATER_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
set_sc( SO_WIND_INSIGNIA , SC_WIND_INSIGNIA , SI_WIND_INSIGNIA , SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
- set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
+ set_sc( SO_EARTH_INSIGNIA , SC_EARTH_INSIGNIA , SI_EARTH_INSIGNIA , SCB_MDEF|SCB_DEF|SCB_MAXHP|SCB_MAXSP|SCB_WATK | SCB_ATK_ELE | SCB_REGEN );
/**
* Genetic
**/
@@ -727,14 +727,14 @@ void initChangeTables(void) {
set_sc( OB_ZANGETSU , SC_ZANGETSU , SI_ZANGETSU , SCB_MATK|SCB_BATK );
set_sc_with_vfx( OB_AKAITSUKI , SC_AKAITSUKI , SI_AKAITSUKI , SCB_NONE );
set_sc( OB_OBOROGENSOU , SC_GENSOU , SI_GENSOU , SCB_NONE );
-
+
add_sc( MH_STAHL_HORN , SC_STUN );
set_sc( MH_ANGRIFFS_MODUS , SC_ANGRIFFS_MODUS , SI_ANGRIFFS_MODUS , SCB_BATK|SCB_WATK|SCB_DEF|SCB_FLEE );
set_sc( MH_GOLDENE_FERSE , SC_GOLDENE_FERSE , SI_GOLDENE_FERSE , SCB_SPEED|SCB_FLEE|SCB_ATK_ELE );
add_sc( MH_LAVA_SLIDE , SC_BURNING );
add_sc( MH_POISON_MIST , SC_BLIND );
set_sc( MH_ERASER_CUTTER , SC_ERASER_CUTTER , SI_BLANK , SCB_NONE );
-
+
// Storing the target job rather than simply SC_SPIRIT simplifies code later on.
SkillStatusChangeTable[SL_ALCHEMIST] = (sc_type)MAPID_ALCHEMIST,
SkillStatusChangeTable[SL_MONK] = (sc_type)MAPID_MONK,
@@ -889,7 +889,7 @@ void initChangeTables(void) {
StatusIconChangeTable[SC_CURSED_SOIL] = SI_CURSED_SOIL;
StatusIconChangeTable[SC_UPHEAVAL] = SI_UPHEAVAL;
StatusIconChangeTable[SC_PUSH_CART] = SI_ON_PUSH_CART;
-
+
//Other SC which are not necessarily associated to skills.
StatusChangeFlagTable[SC_ASPDPOTION0] = SCB_ASPD;
StatusChangeFlagTable[SC_ASPDPOTION1] = SCB_ASPD;
@@ -968,16 +968,16 @@ void initChangeTables(void) {
StatusChangeFlagTable[SC_LIFE_FORCE_F] |= SCB_MAXSP;
StatusChangeFlagTable[SC_EXTRACT_WHITE_POTION_Z] |= SCB_REGEN;
StatusChangeFlagTable[SC_VITATA_500] |= SCB_REGEN;
- StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
+ StatusChangeFlagTable[SC_EXTRACT_SALAMINE_JUICE] |= SCB_ASPD;
#ifdef RENEWAL_EDP
// renewal EDP increases your weapon atk
StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
#endif
-
+
if( !battle_config.display_hallucination ) //Disable Hallucination.
StatusIconChangeTable[SC_HALLUCINATION] = SI_BLANK;
-
+
/* StatusChangeState (SCS_) NOMOVE */
StatusChangeStateTable[SC_ANKLE] |= SCS_NOMOVE;
StatusChangeStateTable[SC_AUTOCOUNTER] |= SCS_NOMOVE;
@@ -1004,7 +1004,7 @@ void initChangeTables(void) {
StatusChangeStateTable[SC_CAMOUFLAGE] |= SCS_NOMOVE|SCS_NOMOVECOND;
StatusChangeStateTable[SC_MEIKYOUSISUI] |= SCS_NOMOVE;
StatusChangeStateTable[SC_KAGEHUMI] |= SCS_NOMOVE;
-
+
/* StatusChangeState (SCS_) NOPICKUPITEMS */
StatusChangeStateTable[SC_HIDING] |= SCS_NOPICKITEM;
StatusChangeStateTable[SC_CLOAKING] |= SCS_NOPICKITEM;
@@ -1022,6 +1022,7 @@ void initChangeTables(void) {
StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
StatusChangeStateTable[SC_STEELBODY] |= SCS_NOCAST;
StatusChangeStateTable[SC_BERSERK] |= SCS_NOCAST;
+ StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCAST;
StatusChangeStateTable[SC_OBLIVIONCURSE] |= SCS_NOCAST;
StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOCAST;
StatusChangeStateTable[SC__INVISIBILITY] |= SCS_NOCAST;
@@ -1031,15 +1032,15 @@ void initChangeTables(void) {
StatusChangeStateTable[SC_SATURDAYNIGHTFEVER] |= SCS_NOCAST;
StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET] |= SCS_NOCAST;
StatusChangeStateTable[SC_SILENCE] |= SCS_NOCAST;
-
+
}
static void initDummyData(void)
{
memset(&dummy_status, 0, sizeof(dummy_status));
- dummy_status.hp =
- dummy_status.max_hp =
- dummy_status.max_sp =
+ dummy_status.hp =
+ dummy_status.max_hp =
+ dummy_status.max_sp =
dummy_status.str =
dummy_status.agi =
dummy_status.vit =
@@ -1063,7 +1064,7 @@ static inline void status_cpy(struct status_data* a, const struct status_data* b
}
//Sets HP to given value. Flag is the flag passed to status_heal in case
-//final value is higher than current (use 2 to make a healing effect display
+//final value is higher than current (use 2 to make a healing effect display
//on players) It will always succeed (overrides Berserk block), but it can't kill.
int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
{
@@ -1081,7 +1082,7 @@ int status_set_hp(struct block_list *bl, unsigned int hp, int flag)
}
//Sets SP to given value. Flag is the flag passed to status_heal in case
-//final value is higher than current (use 2 to make a healing effect display
+//final value is higher than current (use 2 to make a healing effect display
//on players)
int status_set_sp(struct block_list *bl, unsigned int sp, int flag)
{
@@ -1214,6 +1215,8 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
status_change_end(target, SC_RAISINGDRAGON, INVALID_TIMER);
if (sc->data[SC_SATURDAYNIGHTFEVER] && status->hp <= 100)
status_change_end(target, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
+ if (sc->data[SC__BLOODYLUST] && status->hp <= 100)
+ status_change_end(target, SC__BLOODYLUST, INVALID_TIMER);
}
switch (target->type) {
@@ -1272,7 +1275,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
memset(&regen->ssregen->tick, 0, sizeof(regen->ssregen->tick));
}
}
-
+
if( sc && sc->data[SC_KAIZEL] && !map_flag_gvg(target->m) )
{ //flag&8 = disable Kaizel
int time = skill_get_time2(SL_KAIZEL,sc->data[SC_KAIZEL]->val1);
@@ -1285,7 +1288,7 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
clif_skill_nodamage(target,target,ALL_RESURRECTION,1,1);
sc_start(target,status_skill2sc(PR_KYRIE),100,10,time);
- if( target->type == BL_MOB )
+ if( target->type == BL_MOB )
((TBL_MOB*)target)->state.rebirth = 1;
return hp+sp;
@@ -1343,7 +1346,7 @@ int status_heal(struct block_list *bl,int hp,int sp, int flag)
}
if(hp) {
- if( sc && sc->data[SC_BERSERK] ) {
+ if( sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) ) {
if( flag&1 )
flag &= ~2;
else
@@ -1405,7 +1408,7 @@ int status_percent_change(struct block_list *src,struct block_list *target,signe
//Change the equation when the values are high enough to discard the
//imprecision in exchange of overflow protection [Skotlex]
- //Also add 100% checks since those are the most used cases where we don't
+ //Also add 100% checks since those are the most used cases where we don't
//want aproximation errors.
if (hp_rate > 99)
hp = status->hp;
@@ -1476,7 +1479,7 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
hp = status->max_hp - status->hp;
else if (per_hp && !hp)
hp = 1;
-
+
if(sp > status->max_sp - status->sp)
sp = status->max_sp - status->sp;
else if (per_sp && !sp)
@@ -1503,7 +1506,7 @@ int status_revive(struct block_list *bl, unsigned char per_hp, unsigned char per
* 1 - Cast bar is done.
* 2 - Skill already pulled off, check is due to ground-based skills or splash-damage ones.
* src MAY be null to indicate we shouldn't check it, this is a ground-based skill attack.
- * target MAY Be null, in which case the checks are only to see
+ * target MAY Be null, in which case the checks are only to see
* whether the source can cast or not the skill on the ground.
*------------------------------------------*/
int status_check_skilluse(struct block_list *src, struct block_list *target, int skill_num, int flag)
@@ -1520,12 +1523,12 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
if (!skill_num) { //Normal attack checks.
if (!(status->mode&MD_CANATTACK))
return 0; //This mode is only needed for melee attacking.
- //Dead state is not checked for skills as some skills can be used
+ //Dead state is not checked for skills as some skills can be used
//on dead characters, said checks are left to skill.c [Skotlex]
if (target && status_isdead(target))
return 0;
if( src && (sc = status_get_sc(src)) && sc->data[SC_CRYSTALIZE] && src->type != BL_MOB)
- return 0;
+ return 0;
}
switch( skill_num ) {
@@ -1555,9 +1558,9 @@ 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 && (sc->opt1 != OPT1_CRYSTALIZE && src->type != BL_MOB) && sc->opt1 != OPT1_BURNING && skill_num != SR_GENTLETOUCH_CURE ) { //Stuned/Frozen/etc
- if (flag != 1) //Can't cast, casted stuff can't damage.
+ if (flag != 1) //Can't cast, casted stuff can't damage.
return 0;
if (!(skill_get_inf(skill_num)&INF_GROUND_SKILL))
return 0; //Targetted spells can't come off.
@@ -1676,7 +1679,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
return 1;
tsc = status_get_sc(target);
-
+
if(tsc && tsc->count) {
/* attacks in invincible are capped to 1 damage and handled in batte.c; allow spell break and eske for sealed shrine GDB when in INVINCIBLE state. */
if( tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF] && skill_num && !(skill_num&(SA_SPELLBREAKER|SL_SKE)) )
@@ -1692,11 +1695,11 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
//If targetting, cloak+hide protect you, otherwise only hiding does.
hide_flag = flag?OPTION_HIDE:(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK);
-
+
//You cannot hide from ground skills.
if( skill_get_ele(skill_num,1) == ELE_EARTH ) //TODO: Need Skill Lv here :/
hide_flag &= ~OPTION_HIDE;
-
+
switch( target->type ) {
case BL_PC: {
struct map_session_data *sd = (TBL_PC*) target;
@@ -1719,7 +1722,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
if (status->mode&MD_LOOTER)
return 1;
return 0;
- case BL_HOM:
+ case BL_HOM:
case BL_MER:
case BL_ELEM:
if( target->type == BL_HOM && skill_num && battle_config.hom_setting&0x1 && skill_get_inf(skill_num)&INF_SUPPORT_SKILL && battle_get_master(target) != src )
@@ -1734,7 +1737,7 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
if( tsc->option&hide_flag && !(status->mode&(MD_BOSS|MD_DETECTOR)))
return 0;
if( tsc->data[SC_STEALTHFIELD] && !(status->mode&MD_BOSS) )
- return 0;
+ return 0;
}
}
return 1;
@@ -1790,10 +1793,10 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat
switch( sd->weapontype2 ){ // adjustment for dual weilding
case W_DAGGER: mod = 0; break; // 0, 1, 1
- case W_1HSWORD:
+ case W_1HSWORD:
case W_1HAXE: mod = 1;
if( (sd->class_&MAPID_THIRDMASK) == MAPID_GUILLOTINE_CROSS ) // 0, 2, 3
- mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ;
+ mod = sd->weapontype2 / W_1HSWORD + W_1HSWORD / sd->weapontype2 ;
}
amotion = ( sd->status.weapon < MAX_WEAPON_TYPE && mod < 0 )
@@ -1801,7 +1804,7 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat
: ((aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2] // dual-wield
+ aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2]) * 6 / 10 + 10 * mod
- aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2]
- + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1]);
+ + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1]);
if ( sd->status.shield )
amotion += ( 2000 - aspd_base[pc_class2idx(sd->status.class_)][W_FIST] ) +
@@ -1812,7 +1815,7 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat
amotion = (sd->status.weapon < MAX_WEAPON_TYPE)
? (aspd_base[pc_class2idx(sd->status.class_)][sd->status.weapon]) // single weapon
: (aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype1] + aspd_base[pc_class2idx(sd->status.class_)][sd->weapontype2])*7/10; // dual-wield
-
+
// percentual delay reduction from stats
amotion -= amotion * (4*status->agi + status->dex)/1000;
#endif
@@ -1837,7 +1840,7 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
if (bl->type == BL_PC)
switch(((TBL_PC*)bl)->status.weapon){
case W_BOW:
- case W_MUSICAL:
+ case W_MUSICAL:
case W_WHIP:
case W_REVOLVER:
case W_RIFLE:
@@ -1866,7 +1869,7 @@ static unsigned short status_base_atk(const struct block_list *bl, const struct
str += dstr*dstr;
if (bl->type == BL_PC)
#ifdef RENEWAL
- str = (rstr*10 + dex*10/5 + status->luk*10/3 + ((TBL_PC*)bl)->status.base_level*10/4)/10;
+ str = (rstr*10 + dex*10/5 + status->luk*10/3 + ((TBL_PC*)bl)->status.base_level*10/4)/10;
#else
str+= dex/5 + status->luk/5;
#endif
@@ -1902,7 +1905,7 @@ void status_calc_misc(struct block_list *bl, struct status_data *status, int lev
{
//Non players get the value set, players need to stack with previous bonuses.
if( bl->type != BL_PC )
- status->batk =
+ status->batk =
status->hit = status->flee =
status->def2 = status->mdef2 =
status->cri = status->flee2 = 0;
@@ -1977,7 +1980,7 @@ int status_calc_mob_(struct mob_data* md, bool first)
//Check if we need custom base-status
if (battle_config.mobs_level_up && md->level > md->db->lv)
flag|=1;
-
+
if (md->special_state.size)
flag|=2;
@@ -2186,7 +2189,7 @@ int status_calc_pet_(struct pet_data *pd, bool first)
if (!battle_config.pet_lv_rate && pd->pet.level != pd->db->lv)
pd->pet.level = pd->db->lv;
}
-
+
//Support rate modifier (1000 = 100%)
pd->rate_fix = 1000*(pd->pet.intimate - battle_config.pet_support_min_friendly)/(1000- battle_config.pet_support_min_friendly) +500;
if(battle_config.pet_support_rate != 100)
@@ -2280,7 +2283,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
b_max_weight = sd->max_weight;
b_cart_weight_max = sd->cart_weight_max;
- pc_calc_skilltree(sd); // �X�L���c��?�̌v�Z
+ pc_calc_skilltree(sd); // SkillTree calculation
sd->max_weight = max_weight_base[pc_class2idx(sd->status.class_)]+sd->status.str*300;
@@ -2333,7 +2336,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
+ sizeof(sd->weapon_coma_race)
+ sizeof(sd->weapon_atk)
+ sizeof(sd->weapon_atk_rate)
- + sizeof(sd->arrow_addele)
+ + sizeof(sd->arrow_addele)
+ sizeof(sd->arrow_addrace)
+ sizeof(sd->arrow_addsize)
+ sizeof(sd->magic_addele)
@@ -2404,9 +2407,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
+ sizeof(sd->skillfixcast)
+ sizeof(sd->skillvarcast)
);
-
+
memset (&sd->bonus, 0,sizeof(sd->bonus));
-
+
// Autobonus
pc_delautobonus(sd,sd->autobonus,ARRAYLENGTH(sd->autobonus),true);
pc_delautobonus(sd,sd->autobonus2,ARRAYLENGTH(sd->autobonus2),true);
@@ -2447,7 +2450,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
int r,wlv = sd->inventory_data[index]->wlv;
struct weapon_data *wd;
struct weapon_atk *wa;
- if (wlv >= REFINE_TYPE_MAX)
+ if (wlv >= REFINE_TYPE_MAX)
wlv = REFINE_TYPE_MAX - 1;
if(i == EQI_HAND_L && sd->status.inventory[index].equip == EQP_HAND_L) {
wd = &sd->left_weapon; // Left-hand weapon
@@ -2468,7 +2471,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
{// renewal magic attack refine bonus
status->matk_max += refine_info[wlv].bonus[r-1] / 100;
}
-
+
// record the weapon level for future usage
status->wlv = wlv;
#endif
@@ -2495,7 +2498,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
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))
wd->star += 10;
-
+
if (!wa->ele) //Do not overwrite element from previous bonuses.
wa->ele = (sd->status.inventory[index].card[1]&0x0f);
}
@@ -2528,7 +2531,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
return 1;
}
}
-
+
/* we've got combos to process */
if( sd->combos.count ) {
for( i = 0; i < sd->combos.count; i++ ) {
@@ -2537,13 +2540,13 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
return 1;
}
}
-
- //Store equipment script bonuses
+
+ //Store equipment script bonuses
memcpy(sd->param_equip,sd->param_bonus,sizeof(sd->param_equip));
memset(sd->param_bonus, 0, sizeof(sd->param_bonus));
status->def += (refinedef+50)/100;
-
+
#ifdef RENEWAL
// increment the weapon ATK using the MATK max value
status->matk_max += sd->bonus.sp_weapon_matk;
@@ -2590,7 +2593,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
continue;
if(map[sd->bl.m].flag.pvp && data->flag.no_equip&2)
continue;
- if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4)
+ if(map_flag_gvg(sd->bl.m) && data->flag.no_equip&4)
continue;
if(map[sd->bl.m].flag.battleground && data->flag.no_equip&8)
continue;
@@ -2644,7 +2647,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if(pc_isriding(sd) &&
(sd->status.weapon==W_1HSPEAR || sd->status.weapon==W_2HSPEAR))
- { //When Riding with spear, damage modifier to mid-class becomes
+ { //When Riding with spear, damage modifier to mid-class becomes
//same as versus large size.
sd->right_weapon.atkmods[1] = sd->right_weapon.atkmods[2];
sd->left_weapon.atkmods[1] = sd->left_weapon.atkmods[2];
@@ -2772,23 +2775,23 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
status->max_sp = 1;
// ----- RESPAWN HP/SP -----
-//
+//
//Calc respawn hp and store it on base_status
if (sd->special_state.restart_full_recover)
{
status->hp = status->max_hp;
status->sp = status->max_sp;
} else {
- if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2)
- && battle_config.restart_hp_rate < 50)
+ if((sd->class_&MAPID_BASEMASK) == MAPID_NOVICE && !(sd->class_&JOBL_2)
+ && battle_config.restart_hp_rate < 50)
status->hp=status->max_hp>>1;
- else
+ else
status->hp=status->max_hp * battle_config.restart_hp_rate/100;
if(!status->hp)
status->hp = 1;
status->sp = status->max_sp * battle_config.restart_sp_rate /100;
-
+
if( !status->sp ) /* the minimum for the respawn setting is SP:1 */
status->sp = 1;
}
@@ -2825,7 +2828,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if(sd->mdef2_rate != 100)
status->mdef2 = status->mdef2 * sd->mdef2_rate/100;
- if(sd->critical_rate < 0)
+ if(sd->critical_rate < 0)
sd->critical_rate = 0;
if(sd->critical_rate != 100)
status->cri = status->cri * sd->critical_rate/100;
@@ -2958,7 +2961,7 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
sd->max_weight += 2000*skill;
sd->cart_weight_max = battle_config.max_cart_weight + (pc_checkskill(sd, GN_REMODELING_CART)*5000);
-
+
if (pc_checkskill(sd,SM_MOVINGRECOVERY)>0)
sd->regen.state.walk = 1;
else
@@ -3082,9 +3085,9 @@ int status_calc_pc_(struct map_session_data* sd, bool first)
if( b_cart_weight_max != sd->cart_weight_max ) {
clif_updatestatus(sd,SP_CARTINFO);
}
-
+
calculating = 0;
-
+
return 0;
}
@@ -3192,17 +3195,17 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) {
struct status_data *status = &ed->base_status;
struct s_elemental *ele = &ed->elemental;
struct map_session_data *sd = ed->master;
-
+
if( !sd )
return 0;
-
+
status->str = ele->str;
status->agi = ele->agi;
status->vit = ele->vit;
status->dex = ele->dex;
status->int_ = ele->int_;
status->luk = ele->luk;
-
+
if( first ) {
memcpy(status, &ed->db->status, sizeof(struct status_data));
status->mode = MD_CANMOVE|MD_CANATTACK;
@@ -3216,14 +3219,14 @@ int status_calc_elemental_(struct elemental_data *ed, bool first) {
status->int_ += sd->base_status.int_ * 25 / 100;
status->def += sd->base_status.dex * 25 / 100;
status->luk += sd->base_status.luk * 25 / 100;
-
+
status_calc_misc(&ed->bl, status, ed->db->lv);
memcpy(&ed->battle_status,status,sizeof(struct status_data));
} else {
status_calc_misc(&ed->bl, status, ed->db->lv);
status_cpy(&ed->battle_status, status);
}
-
+
return 0;
}
@@ -3350,7 +3353,7 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
} else if( bl->type == BL_ELEM ) {
val = (status->max_hp * status->vit / 10000 + 1) * 6;
regen->hp = cap_value(val, 1, SHRT_MAX);
-
+
val = (status->max_sp * (status->int_ + 10) / 750) + 1;
regen->sp = cap_value(val, 1, SHRT_MAX);
}
@@ -3389,7 +3392,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
if (
(sc->data[SC_POISON] && !sc->data[SC_SLOWPOISON])
|| (sc->data[SC_DPOISON] && !sc->data[SC_SLOWPOISON])
- || sc->data[SC_BERSERK]
+ || sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]
|| sc->data[SC_TRICKDEAD]
|| sc->data[SC_BLEEDING]
|| sc->data[SC_MAGICMUSHROOM]
@@ -3441,13 +3444,13 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
}
void status_calc_state( struct block_list *bl, struct status_change *sc, enum scs_flag flag, bool start ) {
-
+
/* no sc at all, we can zero without any extra weight over our conciousness */
if( !sc->count ) {
memset(&sc->cant, 0, sizeof (sc->cant));
return;
}
-
+
/* can move? */
if( flag&SCS_NOMOVE ) {
if( !(flag&SCS_NOMOVECOND) ) {
@@ -3457,13 +3460,13 @@ void status_calc_state( struct block_list *bl, struct status_change *sc, enum sc
|| (sc->data[SC_BASILICA] && sc->data[SC_BASILICA]->val4 == bl->id) // Basilica caster cannot move
|| (sc->data[SC_GRAVITATION] && sc->data[SC_GRAVITATION]->val3 == BCT_SELF)
|| (sc->data[SC_CRYSTALIZE] && bl->type != BL_MOB)
- || (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3
+ || (sc->data[SC_CAMOUFLAGE] && sc->data[SC_CAMOUFLAGE]->val1 < 3
&& !(sc->data[SC_CAMOUFLAGE]->val3&1))
) {
sc->cant.move += ( start ? 1 : -1 );
}
}
-
+
/* can't use skills */
if( flag&SCS_NOCAST ) {
if( !(flag&SCS_NOCASTCOND) ) {
@@ -3472,10 +3475,10 @@ void status_calc_state( struct block_list *bl, struct status_change *sc, enum sc
sc->cant.cast += ( start ? 1 : -1 );
}
}
-
+
/* player-only states */
if( bl->type == BL_PC ) {
-
+
/* can pick items? */
if( flag&SCS_NOPICKITEM ) {
if( !(flag&SCS_NOPICKITEMCOND) ) {
@@ -3484,7 +3487,7 @@ void status_calc_state( struct block_list *bl, struct status_change *sc, enum sc
sc->cant.pickup += ( start ? 1 : -1 );
}
}
-
+
/* can drop items? */
if( flag&SCS_NODROPITEM ) {
if( !(flag&SCS_NODROPITEMCOND) ) {
@@ -3494,7 +3497,7 @@ void status_calc_state( struct block_list *bl, struct status_change *sc, enum sc
}
}
}
-
+
return;
}
/// Recalculates parts of an object's battle status according to the specified flags.
@@ -3630,11 +3633,11 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
if(flag&SCB_MDEF)
{
status->mdef = status_calc_mdef(bl, sc, b_status->mdef);
-
+
if( bl->type&BL_HOM )
status->mdef += (status->int_/5 - b_status->int_/5);
}
-
+
if(flag&SCB_MDEF2) {
if (status->int_ == b_status->int_ && status->vit == b_status->vit)
status->mdef2 = status_calc_mdef2(bl, sc, b_status->mdef2);
@@ -3772,7 +3775,7 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
#endif
status->matk_min = status->matk_min * sd->matk_rate/100;
}
-
+
status->matk_min = status_calc_matk(bl, sc, status->matk_min);
#ifndef RENEWAL // only changed in non-renewal [Ind]
@@ -3797,20 +3800,20 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
#else
// aspd = baseaspd + floor(sqrt((agi^2/2) + (dex^2/5))/4 + (potskillbonus*agi/200))
amotion -= (int)(sqrt( (pow(status->agi, 2) / 2) + (pow(status->dex, 2) / 5) ) / 4 + (status_calc_aspd(bl, sc, 1) * status->agi / 200)) * 10;
-
+
if( (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) != 0 ) // RE ASPD percertage modifier
- amotion -= ( amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd) )
+ amotion -= ( amotion - ((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd) )
* (status_calc_aspd(bl, sc, 2) + status->aspd_rate2) / 100;
if(status->aspd_rate != 1000) // absolute percentage modifier
amotion = ( 200 - (200-amotion/10) * status->aspd_rate / 1000 ) * 10;
-#endif
+#endif
//fixed value added
if( sc && sc->data[SC_FIGHTINGSPIRIT] && sc->data[SC_FIGHTINGSPIRIT]->val2 )
amotion -= (sd?pc_checkskill(sd, RK_RUNEMASTERY):10) / 10 * 40;
status->amotion = cap_value(amotion,((sd->class_&JOBL_THIRD) ? battle_config.max_third_aspd : battle_config.max_aspd),2000);
-
+
status->adelay = 2*status->amotion;
}
else
@@ -3818,24 +3821,24 @@ void status_calc_bl_main(struct block_list *bl, /*enum scb_flag*/int flag)
{
amotion = (1000 -4*status->agi -status->dex) * ((TBL_HOM*)bl)->homunculusDB->baseASPD/1000;
status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
-
+
if(status->aspd_rate != 1000)
amotion = amotion*status->aspd_rate/1000;
-
+
status->amotion = cap_value(amotion,battle_config.max_aspd,2000);
-
+
status->adelay = status->amotion;
}
else // mercenary and mobs
{
amotion = b_status->amotion;
status->aspd_rate = status_calc_aspd_rate(bl, sc, b_status->aspd_rate);
-
+
if(status->aspd_rate != 1000)
amotion = amotion*status->aspd_rate/1000;
-
+
status->amotion = cap_value(amotion, battle_config.monster_max_aspd, 2000);
-
+
temp = b_status->adelay*status->aspd_rate/1000;
status->adelay = cap_value(temp, battle_config.monster_max_aspd*2, 4000);
}
@@ -4032,7 +4035,7 @@ void status_calc_bl_(struct block_list* bl, enum scb_flag flag, bool first)
clif_elemental_updatestatus(ed->master, SP_HP);
if( b_status.sp != status->sp )
clif_mercenary_updatestatus(ed->master, SP_SP);
- }
+ }
}
/*==========================================
@@ -4382,8 +4385,6 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
batk += 100;
if(sc->data[SC__ENERVATION])
batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
- if(sc->data[SC__BLOODYLUST])
- batk += batk * 32 / 100;
if(sc->data[SC_RUSHWINDMILL])
batk += batk * sc->data[SC_RUSHWINDMILL]->val2/100;
if(sc->data[SC_SATURDAYNIGHTFEVER])
@@ -4400,7 +4401,7 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 1)
|| (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 1))
)
- batk += batk / 5;
+ batk += batk / 5;
if(sc->data[SC_FULL_SWING_K])
batk += sc->data[SC_FULL_SWING_K]->val1;
if(sc->data[SC_ODINS_POWER])
@@ -4447,8 +4448,6 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
}
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
- if(sc->data[SC__BLOODYLUST])
- watk += watk * 32 / 100;
if(sc->data[SC_FLEET])
watk += watk * sc->data[SC_FLEET]->val3/100;
if(sc->data[SC_CURSE])
@@ -4461,8 +4460,6 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
watk += sc->data[SC_FIGHTINGSPIRIT]->val1;
if(sc->data[SC__ENERVATION])
watk -= watk * sc->data[SC__ENERVATION]->val2 / 100;
- if(sc->data[SC__BLOODYLUST])
- watk += watk * 32 / 100;
if(sc->data[SC_STRIKING])
watk += sc->data[SC_STRIKING]->val2;
if(sc->data[SC_SHIELDSPELL_DEF] && sc->data[SC_SHIELDSPELL_DEF]->val1 == 3)
@@ -4527,9 +4524,9 @@ static unsigned short status_calc_matk(struct block_list *bl, struct status_chan
if(sc->data[SC_WATER_BARRIER])
matk -= sc->data[SC_WATER_BARRIER]->val3;
if(sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 3)
- matk += 50;
+ matk += 50;
if(sc->data[SC_ODINS_POWER])
- matk += 70;
+ matk += 70;
if(sc->data[SC_IZAYOI])
matk += 50 * sc->data[SC_IZAYOI]->val1;
if( sc->data[SC_ZANGETSU] )
@@ -4569,7 +4566,7 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
static signed short status_calc_hit(struct block_list *bl, struct status_change *sc, int hit)
{
-
+
if(!sc || !sc->count)
return cap_value(hit,1,SHRT_MAX);
@@ -4634,7 +4631,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
flee += 10;
if(sc->data[SC_SPIDERWEB] && sc->data[SC_SPIDERWEB]->val1)
flee -= flee * 50/100;
- if(sc->data[SC_BERSERK])
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
flee -= flee * 50/100;
if(sc->data[SC_BLIND])
flee -= flee * 25/100;
@@ -4697,11 +4694,11 @@ static signed short status_calc_flee2(struct block_list *bl, struct status_chang
return (short)cap_value(flee2,10,SHRT_MAX);
}
static defType status_calc_def(struct block_list *bl, struct status_change *sc, int def) {
-
+
if(!sc || !sc->count)
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
- if(sc->data[SC_BERSERK])
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
return 0;
if(sc->data[SC_SKA])
return sc->data[SC_SKA]->val3;
@@ -4750,8 +4747,6 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
def -= def * ( 6 + 6 * sc->data[SC_MARSHOFABYSS]->val3/10 + (bl->type == BL_MOB ? 5 : 3) * sc->data[SC_MARSHOFABYSS]->val2/36 ) / 100;
if( sc->data[SC_ANALYZE] )
def -= def * ( 14 * sc->data[SC_ANALYZE]->val1 ) / 100;
- if( sc->data[SC__BLOODYLUST] )
- def -= def * 55 / 100;
if( sc->data[SC_FORCEOFVANGUARD] )
def += def * 2 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
if(sc->data[SC_SATURDAYNIGHTFEVER])
@@ -4765,12 +4760,12 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
if( sc->data[SC_PRESTIGE] )
def += def * sc->data[SC_PRESTIGE]->val1 / 100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
- def += 50;
+ def += 50;
if(sc->data[SC_ODINS_POWER])
def -= 20;
if( sc->data[SC_ANGRIFFS_MODUS] )
def -= def * sc->data[SC_ANGRIFFS_MODUS]->val4 / 100;
-
+
return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);;
}
@@ -4782,8 +4777,8 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
#else
return (short)cap_value(def2,1,SHRT_MAX);
#endif
-
- if(sc->data[SC_BERSERK])
+
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
return 0;
if(sc->data[SC_ETERNALCHAOS])
return 0;
@@ -4837,11 +4832,11 @@ static signed short status_calc_def2(struct block_list *bl, struct status_change
static defType status_calc_mdef(struct block_list *bl, struct status_change *sc, int mdef) {
-
+
if(!sc || !sc->count)
return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
- if(sc->data[SC_BERSERK])
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
return 0;
if(sc->data[SC_BARRIER])
return 100;
@@ -4878,7 +4873,7 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
if(sc->data[SC_WATER_BARRIER])
mdef += sc->data[SC_WATER_BARRIER]->val2;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
- mdef += 50;
+ mdef += 50;
if(sc->data[SC_ODINS_POWER])
mdef -= 20;
@@ -4895,7 +4890,7 @@ static signed short status_calc_mdef2(struct block_list *bl, struct status_chang
#endif
- if(sc->data[SC_BERSERK])
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
return 0;
if(sc->data[SC_SKA])
return 90;
@@ -5041,7 +5036,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
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 );
- if( sc->data[SC_BERSERK] )
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
val = max( val, 25 );
if( sc->data[SC_RUN] )
val = max( val, 55 );
@@ -5054,7 +5049,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
if( sc->data[SC_HOVERING] )
val = max( val, 10 );
if( sc->data[SC_GN_CARTBOOST] )
- val = max( val, sc->data[SC_GN_CARTBOOST]->val2 );
+ val = max( val, sc->data[SC_GN_CARTBOOST]->val2 );
if( sc->data[SC_SWINGDANCE] )
val = max( val, sc->data[SC_SWINGDANCE]->val2 );
if( sc->data[SC_WIND_STEP_OPTION] )
@@ -5122,16 +5117,16 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
if(sc->data[SC_ADRENALINE2] && skills1 < 6)
skills1 = 6;
-
+
if(sc->data[SC_ADRENALINE] && skills1 < 7)
skills1 = 7;
-
+
if(sc->data[SC_SPEARQUICKEN] && skills1 < 7)
skills1 = 7;
if(sc->data[SC_GATLINGFEVER] && skills1 < 9) // needs more info
skills1 = 9;
-
+
if(sc->data[SC_FLEET] && skills1 < 5)
skills1 = 5;
@@ -5156,7 +5151,7 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, s
}
}
- if(sc->data[SC_BERSERK] && skills1 < 15)
+ if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]) && skills1 < 15)
skills1 = 15;
else if(sc->data[SC_MADNESSCANCEL] && skills1 < 15) // needs more info
skills1 = 15;
@@ -5249,7 +5244,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
if(sc->data[SC_ADRENALINE] &&
max < sc->data[SC_ADRENALINE]->val3)
max = sc->data[SC_ADRENALINE]->val3;
-
+
if(sc->data[SC_SPEARQUICKEN] &&
max < sc->data[SC_SPEARQUICKEN]->val2)
max = sc->data[SC_SPEARQUICKEN]->val2;
@@ -5257,14 +5252,14 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
if(sc->data[SC_GATLINGFEVER] &&
max < sc->data[SC_GATLINGFEVER]->val2)
max = sc->data[SC_GATLINGFEVER]->val2;
-
+
if(sc->data[SC_FLEET] &&
max < sc->data[SC_FLEET]->val2)
max = sc->data[SC_FLEET]->val2;
-
+
if( sc->data[SC_GOLDENE_FERSE] && max < sc->data[SC_GOLDENE_FERSE]->val3 )
max = sc->data[SC_GOLDENE_FERSE]->val3;
-
+
if(sc->data[SC_ASSNCROS] &&
max < sc->data[SC_ASSNCROS]->val2)
{
@@ -5286,7 +5281,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
}
aspd_rate -= max;
- if(sc->data[SC_BERSERK])
+ if((sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
aspd_rate -= 300;
else if(sc->data[SC_MADNESSCANCEL])
aspd_rate -= 200;
@@ -5384,7 +5379,7 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp += maxhp * sc->data[SC_APPLEIDUN]->val2/100;
if(sc->data[SC_DELUGE])
maxhp += maxhp * sc->data[SC_DELUGE]->val2/100;
- if(sc->data[SC_BERSERK])
+ if (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST])
maxhp += maxhp * 2;
if(sc->data[SC_MARIONETTE])
maxhp -= 1000;
@@ -5420,7 +5415,7 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
maxhp -= sc->data[SC_MYSTERIOUS_POWDER]->val1 / 100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
maxhp += 500;
-
+
return cap_value(maxhp,1,UINT_MAX);
}
@@ -5442,7 +5437,7 @@ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_chang
if(sc->data[SC_LIFE_FORCE_F])
maxsp += maxsp * sc->data[SC_LIFE_FORCE_F]->val1/100;
if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 3)
- maxsp += 50;
+ maxsp += 50;
return cap_value(maxsp,1,UINT_MAX);
}
@@ -5501,13 +5496,13 @@ unsigned char status_calc_attack_element(struct block_list *bl, struct status_ch
if(sc->data[SC_WATERWEAPON]
|| (sc->data[SC_WATER_INSIGNIA] && sc->data[SC_WATER_INSIGNIA]->val1 == 2) )
return ELE_WATER;
- if(sc->data[SC_EARTHWEAPON]
+ if(sc->data[SC_EARTHWEAPON]
|| (sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2) )
return ELE_EARTH;
- if(sc->data[SC_FIREWEAPON]
+ if(sc->data[SC_FIREWEAPON]
|| (sc->data[SC_FIRE_INSIGNIA] && sc->data[SC_FIRE_INSIGNIA]->val1 == 2) )
return ELE_FIRE;
- if(sc->data[SC_WINDWEAPON]
+ if(sc->data[SC_WINDWEAPON]
|| (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2) )
return ELE_WIND;
if(sc->data[SC_ENCPOISON])
@@ -5553,8 +5548,10 @@ const char* status_get_name(struct block_list *bl) {
}
/*==========================================
- * �Ώۂ�Class��Ԃ�(�ėp)
- * �߂�͐�����0�ȏ�
+ * Get the class of the current bl
+ * return
+ * 0 = fail
+ * class_id = success
*------------------------------------------*/
int status_get_class(struct block_list *bl) {
nullpo_ret(bl);
@@ -5570,8 +5567,10 @@ int status_get_class(struct block_list *bl) {
return 0;
}
/*==========================================
- * �Ώۂ̃��x����Ԃ�(�ėp)
- * �߂�͐�����0�ȏ�
+ * Get the base level of the current bl
+ * return
+ * 1 = fail
+ * level = success
*------------------------------------------*/
int status_get_lv(struct block_list *bl) {
nullpo_ret(bl);
@@ -5830,7 +5829,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
else if (merc_class(class_))
vd = merc_get_viewdata(class_);
else if (elemental_class(class_))
- vd = elemental_get_viewdata(class_);
+ vd = elemental_get_viewdata(class_);
else
vd = NULL;
@@ -5943,7 +5942,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
else
ShowError("status_set_viewdata (ELEMENTAL): No view data for class %d\n", class_);
}
- break;
+ break;
}
vd = status_get_viewdata(bl);
if (vd && vd->cloth_color && (
@@ -6019,9 +6018,10 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
case SC__LAZINESS:
case SC__UNLUCKY:
case SC__WEAKNESS:
+ case SC__BLOODYLUST:
return 0;
}
-
+
sd = BL_CAST(BL_PC,bl);
status = status_get_status_data(bl);
sc = status_get_sc(bl);
@@ -6083,9 +6083,9 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
if( tick == 5000 ) // 100% on caster
break;
if( bl->type == BL_PC )
- tick -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100;
+ tick -= (status_get_lv(bl) / 5 + status->vit / 4 + status->agi / 10)*100;
else
- tick -= (status->vit + status->luk) / 20 * 1000;
+ tick -= (status->vit + status->luk) / 20 * 1000;
break;
case SC_BURNING:
// From iROwiki : http://forums.irowiki.org/showpost.php?p=577240&postcount=583
@@ -6097,9 +6097,9 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
tick = max(tick,10000); // Minimum Duration 10s.
break;
case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
- sc_def = 100 - ( 100 - status->int_* 8 / 10 );
+ sc_def = 100 - ( 100 - status->int_* 8 / 10 );
sc_def = max(sc_def, 5); // minimum of 5%
- break;
+ break;
case SC_BITE: // {(Base Success chance) - (Target's AGI / 4)}
rate -= status->agi*1000/4;
rate = max(rate,50000); // minimum of 50%
@@ -6123,7 +6123,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
return 0;
return tick?tick:1;
}
-
+
if (sd) {
if (battle_config.pc_sc_def_rate != 100)
@@ -6156,7 +6156,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
tick_def = tick_def*battle_config.mob_sc_def_rate/100;
}
}
-
+
if (sc) {
if (sc->data[SC_SCRESIST])
sc_def += sc->data[SC_SCRESIST]->val1; //Status resist
@@ -6184,7 +6184,7 @@ int status_get_sc_def(struct block_list *bl, enum sc_type type, int rate, int ti
if (!(rnd()%10000 < rate))
return 0;
- //Why would a status start with no duration? Presume it has
+ //Why would a status start with no duration? Presume it has
//duration defined elsewhere.
if (!tick) return 1;
@@ -6232,15 +6232,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if( !sc )
return 0; //Unable to receive status changes
-
+
if( status_isdead(bl) && type != SC_NOCHAT ) // SC_NOCHAT should work even on dead characters
return 0;
- if( bl->type == BL_MOB && type != SC_SAFETYWALL && type != SC_PNEUMA )
+ if( bl->type == BL_MOB)
{
struct mob_data *md = BL_CAST(BL_MOB,bl);
- if( md->class_ == MOBID_EMPERIUM || mob_is_battleground(md) )
+ if(md && (md->class_ == MOBID_EMPERIUM || mob_is_battleground(md)) && type != SC_SAFETYWALL && type != SC_PNEUMA)
return 0; //Emperium/BG Monsters can't be afflicted by status changes
+ // if(md && mob_is_gvg(md) && status_sc2scb_flag(type)&SCB_MAXHP)
+ // return 0; //prevent status addinh hp to gvg mob (like bloodylust=hp*3 etc...
}
if( sc->data[SC_REFRESH] ) {
@@ -6320,7 +6322,17 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if((type == SC_FREEZE || type == SC_FREEZING || type == SC_CRYSTALIZE) && sc->data[SC_WARMER])
return 0; //Immune to Frozen and Freezing status if under Warmer status. [Jobbie]
break;
-
+
+ //There all like berserk, do not everlap each other
+ case SC__BLOODYLUST:
+ if(!sd) return 0; //should only affect player
+ case SC_BERSERK:
+ if (((type == SC_BERSERK) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC__BLOODYLUST]))
+ || ((type == SC__BLOODYLUST) && (sc->data[SC_SATURDAYNIGHTFEVER] || sc->data[SC_BERSERK]))
+ )
+ return 0;
+ break;
+
case SC_BURNING:
if(sc->opt1 || sc->data[SC_FREEZING])
return 0;
@@ -6372,12 +6384,12 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_TWOHANDQUICKEN:
if(sc->data[SC_DECREASEAGI])
return 0;
-
+
case SC_INCREASEAGI:
- if(sd && pc_issit(sd)){
+ if(sd && pc_issit(sd)){
pc_setstand(sd);
}
-
+
case SC_CONCENTRATE:
case SC_SPEARQUICKEN:
case SC_TRUESIGHT:
@@ -6569,6 +6581,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if(sc->data[i]) return 0;
}
break;
+ case SC_SATURDAYNIGHTFEVER:
+ if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION] || sc->data[SC__BLOODYLUST])
+ return 0;
+ break;
case SC_INTRAVISION:
if(sd && sd->special_state.intravision) return 0; //we already have the status by maya P
break;
@@ -6671,6 +6687,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
status_change_end(bl, SC_CLOSECONFINE, INVALID_TIMER);
status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
break;
+ case SC__BLOODYLUST:
case SC_BERSERK:
if(battle_config.berserk_cancels_buffs) {
status_change_end(bl, SC_ONEHAND, INVALID_TIMER);
@@ -6789,7 +6806,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_BEYONDOFWARCRY:
case SC_UNLIMITEDHUMMINGVOICE:
if( sc->data[type] ) // Don't remove same sc.
- break;
+ break; //FIXME this is wrong as it'll prevent other being remove as well
status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
@@ -6803,7 +6820,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_REFLECTDAMAGE:
status_change_end(bl, SC_REFLECTSHIELD, INVALID_TIMER);
break;
- case SC_SHIELDSPELL_DEF:
+ case SC_SHIELDSPELL_DEF:
case SC_SHIELDSPELL_MDEF:
case SC_SHIELDSPELL_REF:
status_change_end(bl, SC_MAGNIFICAT, INVALID_TIMER);
@@ -6873,9 +6890,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC__IGNORANCE:
case SC__LAZINESS:
case SC__WEAKNESS:
- case SC__UNLUCKY:
+ case SC__UNLUCKY:
return 0;
- case SC_COMBO:
+ case SC_COMBO:
case SC_DANCING:
case SC_DEVOTION:
case SC_ASPDPOTION0:
@@ -6916,7 +6933,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val4 = sce->val4;
break;
case SC_LERADSDEW:
- if( sc && sc->data[SC_BERSERK] )
+ if (sc && (sc->data[SC_BERSERK] || sc->data[SC__BLOODYLUST]))
return 0;
case SC_SHAPESHIFT:
case SC_PROPERTYWALK:
@@ -7095,7 +7112,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
#ifndef RENEWAL
if(status->def_ele != ELE_WATER)
val2 = 0;
-#endif
+#endif
break;
case SC_SUITON:
if (!val2 || (sd && (sd->class_&MAPID_UPPERMASK) == MAPID_NINJA)) {
@@ -7175,10 +7192,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_STONE:
val3 = tick/1000; //Petrified HP-damage iterations.
- if(val3 < 1) val3 = 1;
+ if(val3 < 1) val3 = 1;
tick = val4; //Petrifying time.
- if (tick < 1000)
- tick = 1000; //Min time
+ tick = max(tick, 1000); //Min time
calc_flag = 0; //Actual status changes take effect on petrified state.
break;
@@ -7189,14 +7205,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (status->hp - diff < status->max_hp>>2)
diff = status->hp - (status->max_hp>>2);
if( val2 && bl->type == BL_MOB ) {
- struct block_list* src = map_id2bl(val2);
- if( src )
- mob_log_damage((TBL_MOB*)bl,src,diff);
- }
+ struct block_list* src = map_id2bl(val2);
+ if( src )
+ mob_log_damage((TBL_MOB*)bl,src,diff);
+ }
status_zap(bl, diff, 0);
}
// fall through
- case SC_POISON: /* �� */
+ case SC_POISON:
val3 = tick/1000; //Damage iterations
if(val3 < 1) val3 = 1;
tick_time = 1000; // [GodLesZ] tick time
@@ -7205,7 +7221,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val4 = (type == SC_DPOISON) ? 3 + status->max_hp/50 : 3 + status->max_hp*3/200;
else
val4 = (type == SC_DPOISON) ? 3 + status->max_hp/100 : 3 + status->max_hp/200;
-
+
break;
case SC_CONFUSION:
clif_emotion(bl,E_WHAT);
@@ -7269,7 +7285,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
else
val4 |= battle_config.monster_cloak_check_type&7;
break;
- case SC_SIGHT: /* �T�C�g/���A�t */
+ case SC_SIGHT: /* splash status */
case SC_RUWACH:
case SC_SIGHTBLASTER:
val3 = skill_get_splash(val2, val1); //Val2 should bring the skill-id.
@@ -7325,7 +7341,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
{
val2 = 5 + 15*val1; //Damage reduction
val3 = 0; // unused, previously speed adjustment
- val4 = 250 - 50*val1; //Aspd adjustment
+ val4 = 250 - 50*val1; //Aspd adjustment
if (sd)
{
@@ -7364,6 +7380,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
sc_start(bl,SC_BLEEDING,100,val1,skill_get_time2(status_sc2skill(type),val1));
break;
+ case SC__BLOODYLUST:
case SC_BERSERK:
if (!sc->data[SC_ENDURE] || !sc->data[SC_ENDURE]->val4)
sc_start4(bl, SC_ENDURE, 100,10,0,0,2, tick);
@@ -7536,7 +7553,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
case SC_KAAHI:
val2 = 200*val1; //HP heal
- val3 = 5*val1; //SP cost
+ val3 = 5*val1; //SP cost
val4 = INVALID_TIMER; //Kaahi Timer.
break;
case SC_BLESSING:
@@ -7645,7 +7662,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 20 + 10*val1; //flee
val3 = 10 + 4*val1; //aspd
val4 = 2 + 2*val1; //chance to issue holy-ele attack
- break;
+ break;
case SC_FLEET:
val2 = 30*val1; //Aspd change
val3 = 5+5*val1; //bAtk/wAtk rate change
@@ -7654,11 +7671,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val2 = 20*val1; //matk increase.
val3 = 12*val1; //mdef2 reduction.
break;
- case SC_SKA:
- val2 = tick/1000;
- val3 = rnd()%100; //Def changes randomly every second...
+ case SC_SKA:
+ val2 = tick/1000;
+ val3 = rnd()%100; //Def changes randomly every second...
tick_time = 1000; // [GodLesZ] tick time
- break;
+ break;
case SC_JAILED:
//Val1 is duration in minutes. Use INT_MAX to specify 'unlimited' time.
tick = val1>0?1000:250;
@@ -7987,12 +8004,10 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC__WEAKNESS:
val2 = 10 * val1;
val_flag |= 1|2;
- // bypasses coating protection and MADO
+ // bypasses coating protection and MADO
sc_start(bl,SC_STRIPWEAPON,100,val1,tick);
sc_start(bl,SC_STRIPSHIELD,100,val1,tick);
break;
- case SC__BLOODYLUST:
- val_flag |= 1|2;
break;
case SC_GN_CARTBOOST:
if( val1 < 3 )
@@ -8071,7 +8086,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val3 = 15 + 5 * val1; // ASPD reduction.
if( rand()%100 < val1 ){ // (Skill Lv) %
val4 = 1; // reduce walk speed by half.
- if( pc_isriding(sd) ) pc_setriding(sd, 0);
+ if( pc_isriding(sd) ) pc_setriding(sd, 0);
if( pc_isridingdragon(sd) ) pc_setoption(sd, sd->sc.option&~OPTION_DRAGON);
}
break;
@@ -8128,7 +8143,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
val1 += 15 * (sd ? sd->status.job_level:50) + 100;
}
else // Mobs
- val1 += (400 * status_get_lv(bl) / 100) + (15 * (status_get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil]
+ val1 += (400 * status_get_lv(bl) / 100) + (15 * (status_get_lv(bl) / 2)); // About 1138% at mob_lvl 99. Is an aproximation to a standard weapon. [pakpil]
break;
case SC_PRESTIGE: // Bassed on suggested formula in iRO Wiki and some test, still need more test. [pakpil]
val2 = ((status->int_ + status->luk) / 6) + 5; // Chance to evade magic damage.
@@ -8179,9 +8194,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_GT_CHANGE:
{// take note there is no def increase as skill desc says. [malufett]
struct block_list * src;
- val3 = status->agi * val1 / 60; // ASPD increase: [(Target�s AGI x Skill Level) / 60] %
+ val3 = status->agi * val1 / 60; // ASPD increase: [(Target AGI x Skill Level) / 60] %
if( (src = map_id2bl(val2)) )
- val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster�s INT) x Skill Level]
+ val4 = ( 200/status_get_int(src) ) * val1;// MDEF decrease: MDEF [(200 / Caster INT) x Skill Level]
}
break;
case SC_GT_REVITALIZE:
@@ -8189,7 +8204,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
struct block_list * src;
val3 = val1 * 30 + 150; // Natural HP recovery increase: [(Skill Level x 30) + 50] %
if( (src = map_id2bl(val2)) ) // the stat def is not shown in the status window and it is process differently
- val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster�s VIT / 4) x Skill Level]
+ val4 = ( status_get_vit(src)/4 ) * val1; // STAT DEF increase: [(Caster VIT / 4) x Skill Level]
}
break;
case SC_PYROTECHNIC_OPTION:
@@ -8276,7 +8291,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
tick_time = 2000; // [GodLesZ] tick time
break;
case SC_WATER_BARRIER:
- val2 = 40; // Increasement. Mdef1 ???
+ val2 = 40; // Increasement. Mdef1 ???
val3 = 20; // Reductions. Atk2, Flee1, Matk1 ????
val_flag |= 1|2|4;
break;
@@ -8321,7 +8336,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
break;
default:
if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == 0 && StatusIconChangeTable[type] == 0 )
- { //Status change with no calc, no icon, and no skill associated...?
+ { //Status change with no calc, no icon, and no skill associated...?
ShowError("UnknownStatusChange [%d]\n", type);
return 0;
}
@@ -8408,11 +8423,11 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
case SC_POISON: sc->opt2 |= OPT2_POISON; break;
case SC_CURSE: sc->opt2 |= OPT2_CURSE; break;
case SC_SILENCE: sc->opt2 |= OPT2_SILENCE; break;
-
+
case SC_SIGNUMCRUCIS:
sc->opt2 |= OPT2_SIGNUMCRUCIS;
break;
-
+
case SC_BLIND: sc->opt2 |= OPT2_BLIND; break;
case SC_ANGELUS: sc->opt2 |= OPT2_ANGELUS; break;
case SC_BLEEDING: sc->opt2 |= OPT2_BLEEDING; break;
@@ -8460,6 +8475,7 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
sc->opt3 |= OPT3_AURABLADE;
opt_flag = 0;
break;
+// case SC__BLOODYLUST:
case SC_BERSERK:
sc->opt3 |= OPT3_BERSERK;
opt_flag = 0;
@@ -8588,20 +8604,22 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
if (calc_flag)
status_calc_bl(bl,calc_flag);
-
+
if ( sc_isnew && StatusChangeStateTable[type] ) /* non-zero */
status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],true);
-
+
if(sd && sd->pd)
pet_sc_check(sd, type); //Skotlex: Pet Status Effect Healing
- switch( type )
- {
+ switch (type) {
+ case SC__BLOODYLUST:
case SC_BERSERK:
- sce->val2 = 5*status->max_hp/100;
- status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
- status_set_sp(bl, 0, 0); //Damage all SP
+ if (!(sce->val2)) { //don't heal if already set
+ status_heal(bl, status->max_hp, 0, 1); //Do not use percent_heal as this healing must override BERSERK's block.
+ status_set_sp(bl, 0, 0); //Damage all SP
+ }
+ sce->val2 = 5 * status->max_hp / 100;
break;
case SC_CHANGE:
status_percent_heal(bl, 100, 100);
@@ -8678,12 +8696,14 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
return 1;
}
+
/*==========================================
- * �X�e�[�^�X�ُ�S����
+ * Ending all status except those listed.
+ * @TODO maybe usefull for dispel instead reseting a liste there.
* type:
- * 0 - ???
- * 1 - ???
- * 2 - ???
+ * 0 - PC killed -> Place here statuses that do not dispel on death.
+ * 1 - If for some reason status_change_end decides to still keep the status when quitting.
+ * 2 - Do clif
*------------------------------------------*/
int status_change_clear(struct block_list* bl, int type)
{
@@ -8778,7 +8798,7 @@ int status_change_clear(struct block_list* bl, int type)
}
/*==========================================
- * �X�e�[�^�X�ُ�I��
+ * Special condition we want to effectuate, check before ending a status.
*------------------------------------------*/
int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const char* file, int line)
{
@@ -8790,7 +8810,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
int opt_flag=0, calc_flag;
nullpo_ret(bl);
-
+
sc = status_get_sc(bl);
status = status_get_status_data(bl);
@@ -8811,7 +8831,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if (sc->opt1)
switch (type) {
//"Ugly workaround" [Skotlex]
- //delays status change ending so that a skill that sets opt1 fails to
+ //delays status change ending so that a skill that sets opt1 fails to
//trigger when it also removed one
case SC_STONE:
sce->val3 = 0; //Petrify time counter.
@@ -8832,8 +8852,8 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
(sc->count)--;
if ( StatusChangeStateTable[type] )
- status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],false);
-
+ status_calc_state(bl,sc,( enum scs_flag ) StatusChangeStateTable[type],false);
+
sc->data[type] = NULL;
vd = status_get_viewdata(bl);
@@ -8967,9 +8987,9 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
if(sce->val4 && sce->val4 != BCT_SELF && (dsd=map_id2sd(sce->val4)))
{// end status on partner as well
dsc = dsd->sc.data[SC_DANCING];
- if(dsc) {
+ if(dsc) {
- //This will prevent recursive loops.
+ //This will prevent recursive loops.
dsc->val2 = dsc->val4 = 0;
status_change_end(&dsd->bl, SC_DANCING, INVALID_TIMER);
@@ -9033,7 +9053,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
int range = 1
+skill_get_range2(bl, status_sc2skill(type), sce->val1)
+skill_get_range2(bl, TF_BACKSLIDING, 1); //Since most people use this to escape the hold....
- map_foreachinarea(status_change_timer_sub,
+ map_foreachinarea(status_change_timer_sub,
bl->m, bl->x-range, bl->y-range, bl->x+range,bl->y+range,BL_CHAR,bl,sce,type,gettick());
}
break;
@@ -9066,7 +9086,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
enum sc_type type2 = (type == SC_MARIONETTE) ? SC_MARIONETTE2 : SC_MARIONETTE;
struct block_list *pbl = map_id2bl(sce->val1);
struct status_change* sc2 = pbl?status_get_sc(pbl):NULL;
-
+
if (sc2 && sc2->data[type2])
{
sc2->data[type2]->val1 = 0;
@@ -9075,11 +9095,12 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
}
break;
+ case SC__BLOODYLUST:
case SC_BERSERK:
case SC_SATURDAYNIGHTFEVER:
//If val2 is removed, no HP penalty (dispelled?) [Skotlex]
- if(status->hp > 100 && sce->val2)
- status_set_hp(bl, 100, 0);
+ if (status->hp > 100 && sce->val2 && type != SC__BLOODYLUST)
+ status_set_hp(bl, 100, 0);
if(sc->data[SC_ENDURE] && sc->data[SC_ENDURE]->val4 == 2)
{
sc->data[SC_ENDURE]->val4 = 0;
@@ -9096,7 +9117,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
skill_delunitgroup(group);
}
break;
- case SC_HERMODE:
+ case SC_HERMODE:
if(sce->val3 == BCT_SELF)
skill_clear_unitgroup(bl);
break;
@@ -9212,7 +9233,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
break;
case SC_CURSEDCIRCLE_ATKER:
if( sce->val2 ) // used the default area size cause there is a chance the caster could knock back and can't clear the target.
- map_foreachinrange(status_change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
+ map_foreachinrange(status_change_timer_sub, bl, battle_config.area_size,BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
break;
case SC_RAISINGDRAGON:
if( sd && sce->val2 && !pc_isdead(sd) ) {
@@ -9362,6 +9383,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
sc->opt3 &= ~OPT3_AURABLADE;
opt_flag = 0;
break;
+// case SC__BLOODYLUST:
case SC_BERSERK:
sc->opt3 &= ~OPT3_BERSERK;
opt_flag = 0;
@@ -9475,7 +9497,8 @@ int kaahi_heal_timer(int tid, unsigned int tick, int id, intptr_t data)
}
/*==========================================
- * �X�e�[�^�X�ُ�I���^�C�}�[
+ * For recusive status, like for each 5s we drop sp etc.
+ * Reseting the end timer.
*------------------------------------------*/
int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
{
@@ -9494,7 +9517,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
sc = status_get_sc(bl);
status = status_get_status_data(bl);
-
+
if(!(sc && (sce = sc->data[type])))
{
ShowDebug("status_change_timer: Null pointer id: %d data: %d bl-type: %d\n", id, data, bl->type);
@@ -9528,7 +9551,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
case SC_CHASEWALK:
if(!status_charge(bl, 0, sce->val4))
break; //Not enough SP to continue.
-
+
if (!sc->data[SC_INCSTR]) {
sc_start(bl, SC_INCSTR,100,1<<(sce->val1-1),
(sc->data[SC_SPIRIT] && sc->data[SC_SPIRIT]->val2 == SL_ROGUE?10:1) //SL bonus -> x10 duration
@@ -9538,20 +9561,20 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
break;
- case SC_SKA:
- if(--(sce->val2)>0){
- sce->val3 = rnd()%100; //Random defense.
- sc_timer_next(1000+tick, status_change_timer,bl->id, data);
- return 0;
- }
+ case SC_SKA:
+ if(--(sce->val2)>0){
+ sce->val3 = rnd()%100; //Random defense.
+ sc_timer_next(1000+tick, status_change_timer,bl->id, data);
+ return 0;
+ }
break;
case SC_HIDING:
if(--(sce->val2)>0){
-
+
if(sce->val2 % sce->val4 == 0 && !status_charge(bl, 0, 1))
break; //Fail if it's time to substract SP and there isn't.
-
+
sc_timer_next(1000+tick, status_change_timer,bl->id, data);
return 0;
}
@@ -9563,12 +9586,12 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
map_foreachinrange( status_change_timer_sub, bl, sce->val3, BL_CHAR, bl, sce, type, tick);
if( --(sce->val2)>0 ){
- sce->val4 += 250; // use for Shadow Form 2 seconds checking.
+ sce->val4 += 250; // use for Shadow Form 2 seconds checking.
sc_timer_next(250+tick, status_change_timer, bl->id, data);
return 0;
}
break;
-
+
case SC_PROVOKE:
if(sce->val2) { //Auto-provoke (it is ended in status_heal)
sc_timer_next(1000*60+tick,status_change_timer, bl->id, data );
@@ -9602,9 +9625,9 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
if (--(sce->val3) > 0) {
if (!sc->data[SC_SLOWPOISON]) {
if( sce->val2 && bl->type == BL_MOB ) {
- struct block_list* src = map_id2bl(sce->val2);
- if( src )
- mob_log_damage((TBL_MOB*)bl,src,sce->val4);
+ struct block_list* src = map_id2bl(sce->val2);
+ if( src )
+ mob_log_damage((TBL_MOB*)bl,src,sce->val4);
}
map_freeblock_lock();
status_zap(bl, sce->val4, 0);
@@ -9681,7 +9704,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
- case SC_DANCING: //�_���X�X�L���̎���SP����
+ case SC_DANCING: //SP consumption by time of dancing skills
{
int s = 0;
int sp = 1;
@@ -9737,7 +9760,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
}
break;
-
+ case SC__BLOODYLUST:
case SC_BERSERK:
// 5% every 10 seconds [DracoRPG]
if( --( sce->val3 ) > 0 && status_charge(bl, sce->val2, 0) && status->hp > 100 )
@@ -9797,7 +9820,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
}
break;
-
+
case SC_JAILED:
if(sce->val1 == INT_MAX || --(sce->val1) > 0)
{
@@ -9807,7 +9830,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_BLIND:
- if(sc->data[SC_FOGWALL])
+ if(sc->data[SC_FOGWALL])
{ //Blind lasts forever while you are standing on the fog.
sc_timer_next(5000+tick, status_change_timer, bl->id, data);
return 0;
@@ -9815,8 +9838,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
break;
case SC_ABUNDANCE:
if(--(sce->val4) > 0) {
- if( !sc->data[SC_BERSERK] )
- status_heal(bl,0,60,0);
+ status_heal(bl,0,60,0);
sc_timer_next(10000+tick, status_change_timer, bl->id, data);
}
break;
@@ -9838,7 +9860,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
if( --(sce->val4) >= 0 ) {
int damage = status->max_hp/100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
damage += status->vit * (sce->val1 - 3);
- unit_skillcastcancel(bl,2);
+ unit_skillcastcancel(bl,2);
map_freeblock_lock();
status_damage(bl, bl, damage, 0, clif_damage(bl,bl,tick,status_get_amotion(bl),status_get_dmotion(bl)+500,damage,1,0,0), 1);
if( sc->data[type] ) {
@@ -9864,7 +9886,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
if( !flag ) { // Random Skill Cast
- if( sd ) {
+ if (sd && !pc_issit(sd)) { //can't cast if sit
int mushroom_skillid = 0, i;
unit_stop_attack(bl);
unit_skillcastcancel(bl,1);
@@ -9899,7 +9921,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
{ //Damage is every 10 seconds including 3%sp drain.
map_freeblock_lock();
clif_damage(bl,bl,tick,status_get_amotion(bl),1,1,0,0,0);
- status_damage(NULL,bl,1,status->max_sp*3/100,0,16);
+ status_damage(NULL, bl, 1, status->max_sp * 3 / 100, 0, 0); //cancel dmg only if cancelable
if( sc->data[type] ) {
sc_timer_next(10000 + tick, status_change_timer, bl->id, data );
}
@@ -9949,7 +9971,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
if( --(sce->val4) >= 0 )
{
struct block_list *src = map_id2bl(sce->val3);
- int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP)
+ int damage = 1000 + 3 * status_get_max_hp(bl) / 100; // Deals fixed (1000 + 3%*MaxHP)
map_freeblock_lock();
clif_damage(bl,bl,tick,0,0,damage,1,9,0); //damage is like endure effect with no walk delay
@@ -10116,7 +10138,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
break;
-
+
case SC_SATURDAYNIGHTFEVER:
// 1% HP/SP drain every val4 seconds [Jobbie]
if( --(sce->val3) >= 0 )
@@ -10154,7 +10176,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
}
break;
-
+
case SC_REFLECTDAMAGE:
if( --(sce->val4) >= 0 ) {
if( !status_charge(bl,0,sce->val3) )
@@ -10208,9 +10230,9 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
{
int hp = status->max_hp * (7-sce->val1) / 100;
int sp = status->max_sp * (9-sce->val1) / 100;
-
+
if( !status_charge(bl,hp,sp) ) break;
-
+
sc_timer_next(1000+tick,status_change_timer,bl->id, data);
return 0;
}
@@ -10269,7 +10291,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
return 0;
case SC_MEIKYOUSISUI:
if( --(sce->val4) > 0 )
- {
+ {
status_heal(bl, status->max_hp * (sce->val1+1) / 100, status->max_sp * sce->val1 / 100, 0);
sc_timer_next(1000 + tick, status_change_timer, bl->id, data);
return 0;
@@ -10278,7 +10300,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
case SC_IZAYOI:
case SC_KAGEMUSYA:
if( --(sce->val2) > 0 )
- {
+ {
if(!status_charge(bl, 0, 1))
break;
sc_timer_next(1000+tick, status_change_timer, bl->id, data);
@@ -10293,7 +10315,7 @@ int status_change_timer(int tid, unsigned int tick, int id, intptr_t data)
}
/*==========================================
- * �X�e�[�^�X�ُ�^�C�}�[�͈͏���
+ * Foreach iteration of repetitive status
*------------------------------------------*/
int status_change_timer_sub(struct block_list* bl, va_list ap)
{
@@ -10310,7 +10332,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
tsc = status_get_sc(bl);
switch( type ) {
- case SC_SIGHT: /* �T�C�g */
+ case SC_SIGHT: /* Reveal hidden ennemy on 3*3 range */
if( tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 >0 && sce->val4%2000 == 0) && // for every 2 seconds do the checking
rnd()%100 < 100-tsc->data[SC__SHADOWFORM]->val1*10 ) // [100 - (Skill Level x 10)] %
status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
@@ -10321,7 +10343,7 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
status_change_end(bl, SC__INVISIBILITY, INVALID_TIMER);
break;
- case SC_RUWACH: /* ���A�t */
+ case SC_RUWACH: /* Reveal hidden target and deal little dammages if ennemy */
if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED] ||
tsc->data[SC__INVISIBILITY])) {
@@ -10384,7 +10406,7 @@ int status_change_clear_buffs (struct block_list* bl, int type)
{
if(!sc->data[i])
continue;
-
+
switch (i) {
//Stuff that cannot be removed
case SC_WEIGHT50:
@@ -10439,7 +10461,7 @@ int status_change_clear_buffs (struct block_list* bl, int type)
case SC_CURSEDCIRCLE_ATKER:
case SC_CURSEDCIRCLE_TARGET:
continue;
-
+
//Debuffs that can be removed.
case SC_HALLUCINATION:
case SC_QUAGMIRE:
@@ -10465,11 +10487,12 @@ int status_change_clear_buffs (struct block_list* bl, int type)
continue;
break;
//The rest are buffs that can be removed.
+ case SC__BLOODYLUST:
case SC_BERSERK:
case SC_SATURDAYNIGHTFEVER:
if (!(type&1))
continue;
- sc->data[i]->val2 = 0;
+ sc->data[i]->val2 = 0;
break;
default:
if (!(type&1))
@@ -10490,14 +10513,14 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) {
if( !sc || !sc->count )
return 0;
-
+
tick = gettick();
for( i = SC_COMMON_MIN; i < SC_MAX; i++ ) {
if( !sc->data[i] || i == SC_COMMON_MAX )
continue;
-
- switch( i ) {
+
+ switch( i ) {
//Debuffs that can be spreaded.
// NOTE: We'll add/delte SCs when we are able to confirm it.
case SC_CURSE:
@@ -10567,7 +10590,7 @@ int status_change_spread( struct block_list *src, struct block_list *bl ) {
flag = 1;
}
}
-
+
return flag;
}
@@ -10679,11 +10702,11 @@ static int status_natural_heal(struct block_list* bl, va_list args)
rate = natural_heal_diff_tick*(regen->rate.hp+bonus);
if (ud && ud->walktimer != INVALID_TIMER)
rate/=2;
- // Homun HP regen fix (they should regen as if they were sitting (twice as fast)
+ // Homun HP regen fix (they should regen as if they were sitting (twice as fast)
if(bl->type==BL_HOM) rate *=2;
regen->tick.hp += rate;
-
+
if(regen->tick.hp >= (unsigned int)battle_config.natural_healhp_interval)
{
val = 0;
@@ -10700,11 +10723,11 @@ static int status_natural_heal(struct block_list* bl, va_list args)
if(flag&RGN_SP)
{
rate = natural_heal_diff_tick*(regen->rate.sp+bonus);
- // Homun SP regen fix (they should regen as if they were sitting (twice as fast)
+ // Homun SP regen fix (they should regen as if they were sitting (twice as fast)
if(bl->type==BL_HOM) rate *=2;
regen->tick.sp += rate;
-
+
if(regen->tick.sp >= (unsigned int)battle_config.natural_healsp_interval)
{
val = 0;
@@ -10726,7 +10749,7 @@ static int status_natural_heal(struct block_list* bl, va_list args)
if(flag&RGN_SHP)
{ //Skill HP regen
sregen->tick.hp += natural_heal_diff_tick * sregen->rate.hp;
-
+
while(sregen->tick.hp >= (unsigned int)battle_config.natural_heal_skill_interval)
{
sregen->tick.hp -= battle_config.natural_heal_skill_interval;
@@ -10779,7 +10802,7 @@ static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_
* @return The chance to refine the item, in percent (0~100)
**/
int status_get_refine_chance(enum refine_type wlv, int refine) {
-
+
if ( refine < 0 || refine >= MAX_REFINE)
return 0;
@@ -10930,7 +10953,7 @@ int status_readdb(void)
// read databases
//
-
+
#ifdef RENEWAL_ASPD
sv_readdb(db_path, "re/job_db1.txt", ',', 6+MAX_WEAPON_TYPE, 6+MAX_WEAPON_TYPE, -1, &status_readdb_job1);
#else