Job Improvement Project - Guillotine Cross (#4705)
* Fixes #4704. * kRO Changelog: http://ro.gnjoy.com/news/update/View.asp?seq=243&curpage=1 Thanks to @Angelic234, @nehpetskie, @ecdarreola, @Haydrich, @Badarosk0, and @LordWhiplash!
This commit is contained in:
parent
341d093802
commit
a23c84d345
@ -10360,62 +10360,21 @@ Body:
|
||||
Name: ASC_BREAKER
|
||||
Description: Soul Destroyer
|
||||
MaxLevel: 10
|
||||
Type: Misc
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
IgnoreAtkCard: true
|
||||
IgnoreDefense: true
|
||||
IgnoreFlee: true
|
||||
Critical: true
|
||||
Range: 9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Weapon
|
||||
CastCancel: true
|
||||
CastTime: 250
|
||||
AfterCastActDelay:
|
||||
- Level: 1
|
||||
Time: 1000
|
||||
- Level: 2
|
||||
Time: 1200
|
||||
- Level: 3
|
||||
Time: 1400
|
||||
- Level: 4
|
||||
Time: 1600
|
||||
- Level: 5
|
||||
Time: 1800
|
||||
- Level: 6
|
||||
Time: 2000
|
||||
- Level: 7
|
||||
Time: 2200
|
||||
- Level: 8
|
||||
Time: 2400
|
||||
- Level: 9
|
||||
Time: 2600
|
||||
- Level: 10
|
||||
Time: 2800
|
||||
AfterCastActDelay: 2000
|
||||
Cooldown: 150
|
||||
FixedCastTime: 250
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 20
|
||||
- Level: 2
|
||||
Amount: 20
|
||||
- Level: 3
|
||||
Amount: 20
|
||||
- Level: 4
|
||||
Amount: 20
|
||||
- Level: 5
|
||||
Amount: 20
|
||||
- Level: 6
|
||||
Amount: 30
|
||||
- Level: 7
|
||||
Amount: 30
|
||||
- Level: 8
|
||||
Amount: 30
|
||||
- Level: 9
|
||||
Amount: 30
|
||||
- Level: 10
|
||||
Amount: 30
|
||||
SpCost: 20
|
||||
- Id: 380
|
||||
Name: SN_SIGHT
|
||||
Description: Falcon Eyes
|
||||
@ -19091,7 +19050,9 @@ Body:
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
Range: 3
|
||||
DamageFlags:
|
||||
Critical: true
|
||||
Range: 7
|
||||
Hit: Multi_Hit
|
||||
HitCount: -7
|
||||
Element: Weapon
|
||||
@ -19109,11 +19070,12 @@ Body:
|
||||
Time: 1000
|
||||
- Level: 5
|
||||
Time: 500
|
||||
Cooldown: 700
|
||||
FixedCastTime: -1
|
||||
CastDelayFlags:
|
||||
IgnoreStatus: true
|
||||
Requires:
|
||||
SpCost: 25
|
||||
SpCost: 40
|
||||
State: Move_Enable
|
||||
- Id: 2023
|
||||
Name: GC_DARKILLUSION
|
||||
@ -19463,13 +19425,13 @@ Body:
|
||||
- Level: 2
|
||||
Area: 1
|
||||
- Level: 3
|
||||
Area: 1
|
||||
- Level: 4
|
||||
Area: 1
|
||||
- Level: 5
|
||||
Area: 2
|
||||
- Level: 4
|
||||
Area: 2
|
||||
- Level: 5
|
||||
Area: 3
|
||||
AfterCastActDelay: 200
|
||||
Duration1: 3000
|
||||
Duration1: 5000
|
||||
FixedCastTime: -1
|
||||
Requires:
|
||||
SpCost: 5
|
||||
@ -19495,7 +19457,8 @@ Body:
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Weapon
|
||||
AfterCastActDelay: 1000
|
||||
AfterCastActDelay: 500
|
||||
Cooldown: 500
|
||||
FixedCastTime: -1
|
||||
Requires:
|
||||
SpCost:
|
||||
@ -31587,7 +31550,7 @@ Body:
|
||||
CopyFlags:
|
||||
Skill:
|
||||
Reproduce: true
|
||||
Duration1: 5000
|
||||
Duration1: 10000
|
||||
Cooldown: 60000
|
||||
FixedCastTime: -1
|
||||
Requires:
|
||||
|
@ -1342,6 +1342,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
|
||||
if (sc->data[SC_SOUNDOFDESTRUCTION])
|
||||
damage <<= 1;
|
||||
if (sc->data[SC_DARKCROW] && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT)
|
||||
damage += damage * sc->data[SC_DARKCROW]->val2 / 100;
|
||||
|
||||
// Damage reductions
|
||||
// Assumptio increases DEF on RE mode, otherwise gives a reduction on the final damage. [Igniz]
|
||||
@ -1438,9 +1440,6 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
damage = i64max(damage, 1);
|
||||
}
|
||||
|
||||
if( sc->data[SC_DARKCROW] && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT )
|
||||
damage += damage * sc->data[SC_DARKCROW]->val2 / 100;
|
||||
|
||||
if( (sce=sc->data[SC_MAGMA_FLOW]) && (rnd()%100 <= sce->val2) )
|
||||
skill_castend_damage_id(bl,src,MH_MAGMA_FLOW,sce->val1,gettick(),0);
|
||||
|
||||
@ -1609,10 +1608,11 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
status_change_end(src,SC_SHIELDSPELL_REF,INVALID_TIMER);
|
||||
}
|
||||
|
||||
if( sc->data[SC_POISONINGWEAPON]
|
||||
&& ((flag&BF_WEAPON) && (!skill_id || skill_id == GC_VENOMPRESSURE)) //check skill type poison_smoke is a unit
|
||||
&& (damage > 0 && rnd()%100 < sc->data[SC_POISONINGWEAPON]->val3 )) //did some damage and chance ok (why no additional effect ??)
|
||||
sc_start2(src,bl,(enum sc_type)sc->data[SC_POISONINGWEAPON]->val2,100,sc->data[SC_POISONINGWEAPON]->val1,sc->data[SC_POISONINGWEAPON]->val4,skill_get_time2(GC_POISONINGWEAPON, 1));
|
||||
if (sc->data[SC_POISONINGWEAPON] && flag&BF_SHORT && (skill_id == 0 || skill_id == GC_VENOMPRESSURE) && damage > 0) {
|
||||
damage += damage * 10 / 100;
|
||||
if (rnd() % 100 < sc->data[SC_POISONINGWEAPON]->val3)
|
||||
sc_start4(src, bl, (sc_type)sc->data[SC_POISONINGWEAPON]->val2, 100, sc->data[SC_POISONINGWEAPON]->val1, 0, 1, 0, skill_get_time2(GC_POISONINGWEAPON, 1));
|
||||
}
|
||||
|
||||
if( sc->data[SC__DEADLYINFECT] && (flag&(BF_SHORT|BF_MAGIC)) == BF_SHORT && damage > 0 && rnd()%100 < 30 + 10 * sc->data[SC__DEADLYINFECT]->val1 )
|
||||
status_change_spread(src, bl, 0);
|
||||
@ -2237,6 +2237,10 @@ static int battle_range_type(struct block_list *src, struct block_list *target,
|
||||
if (src->type == BL_MOB && (skill_id == AC_SHOWER || skill_id == AM_DEMONSTRATION))
|
||||
return BF_SHORT;
|
||||
|
||||
// Cast range is 7 cells and player jumps to target but skill is considered melee
|
||||
if (skill_id == GC_CROSSIMPACT)
|
||||
return BF_SHORT;
|
||||
|
||||
//Skill Range Criteria
|
||||
if (battle_config.skillrange_by_distance &&
|
||||
(src->type&battle_config.skillrange_by_distance)
|
||||
@ -2568,6 +2572,12 @@ static bool is_attack_critical(struct Damage* wd, struct block_list *src, struct
|
||||
case NJ_KIRIKAGE:
|
||||
cri += 250 + 50*skill_lv;
|
||||
break;
|
||||
#ifdef RENEWAL
|
||||
case ASC_BREAKER:
|
||||
#endif
|
||||
case GC_CROSSIMPACT:
|
||||
cri /= 2;
|
||||
break;
|
||||
}
|
||||
if(tsd && tsd->bonus.critical_def)
|
||||
cri = cri * ( 100 - tsd->bonus.critical_def ) / 100;
|
||||
@ -2592,13 +2602,12 @@ static int is_attack_piercing(struct Damage* wd, struct block_list *src, struct
|
||||
if(src != NULL) {
|
||||
struct map_session_data *sd = BL_CAST(BL_PC, src);
|
||||
struct status_data *tstatus = status_get_status_data(target);
|
||||
#ifdef RENEWAL
|
||||
if( skill_id != PA_SACRIFICE && skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS
|
||||
&& skill_id != PA_SHIELDCHAIN && skill_id != KO_HAPPOKUNAI && skill_id != ASC_BREAKER ) // Renewal: Soul Breaker no longer gains ice pick effect and ice pick effect gets crit benefit [helvetica]
|
||||
#else
|
||||
if( skill_id != PA_SACRIFICE && skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS
|
||||
&& skill_id != PA_SHIELDCHAIN && skill_id != KO_HAPPOKUNAI && !is_attack_critical(wd, src, target, skill_id, skill_lv, false) )
|
||||
|
||||
if( skill_id != PA_SACRIFICE && skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS && skill_id != PA_SHIELDCHAIN && skill_id != KO_HAPPOKUNAI
|
||||
#ifndef RENEWAL
|
||||
&& !is_attack_critical(wd, src, target, skill_id, skill_lv, false)
|
||||
#endif
|
||||
)
|
||||
{ //Elemental/Racial adjustments
|
||||
if( sd && (sd->right_weapon.def_ratio_atk_ele & (1<<tstatus->def_ele) || sd->right_weapon.def_ratio_atk_ele & (1<<ELE_ALL) ||
|
||||
sd->right_weapon.def_ratio_atk_race & (1<<tstatus->race) || sd->right_weapon.def_ratio_atk_race & (1<<RC_ALL) ||
|
||||
@ -2838,11 +2847,7 @@ static bool attack_ignores_def(struct Damage* wd, struct block_list *src, struct
|
||||
#endif
|
||||
if (sc && sc->data[SC_FUSION])
|
||||
return true;
|
||||
#ifdef RENEWAL
|
||||
else if (skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS && skill_id != ASC_BREAKER) // Renewal: Soul Breaker no longer gains ignore DEF from weapon [helvetica]
|
||||
#else
|
||||
else if (skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS)
|
||||
#endif
|
||||
{ //Ignore Defense?
|
||||
if (sd && (sd->right_weapon.ignore_def_ele & (1<<tstatus->def_ele) || sd->right_weapon.ignore_def_ele & (1<<ELE_ALL) ||
|
||||
sd->right_weapon.ignore_def_race & (1<<tstatus->race) || sd->right_weapon.ignore_def_race & (1<<RC_ALL) ||
|
||||
@ -3494,7 +3499,11 @@ static void battle_calc_multi_attack(struct Damage* wd, struct block_list *src,s
|
||||
if (sc && sc->data[SC_KAGEMUSYA])
|
||||
max_rate = sc->data[SC_KAGEMUSYA]->val1 * 10; // Same rate as even levels of TF_DOUBLE
|
||||
else
|
||||
#ifdef RENEWAL
|
||||
max_rate = max(7 * skill_lv, sd->bonus.double_rate);
|
||||
#else
|
||||
max_rate = max(5 * skill_lv, sd->bonus.double_rate);
|
||||
#endif
|
||||
|
||||
if( rnd()%100 < max_rate ) {
|
||||
wd->div_ = skill_get_num(TF_DOUBLE,skill_lv?skill_lv:1);
|
||||
@ -3933,12 +3942,15 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
|
||||
if(sd)
|
||||
skillratio += 20 * pc_checkskill(sd,AS_POISONREACT);
|
||||
break;
|
||||
#ifndef RENEWAL
|
||||
// Pre-Renewal: skill ratio for weapon part of damage [helvetica]
|
||||
case ASC_BREAKER:
|
||||
#ifdef RENEWAL
|
||||
skillratio += -100 + 140 * skill_lv + sstatus->str + sstatus->int_; // !TODO: Confirm stat modifier
|
||||
RE_LVL_DMOD(100);
|
||||
#else
|
||||
// Pre-Renewal: skill ratio for weapon part of damage [helvetica]
|
||||
skillratio += -100 + 100 * skill_lv;
|
||||
break;
|
||||
#endif
|
||||
break;
|
||||
case PA_SACRIFICE:
|
||||
skillratio += -10 + 10 * skill_lv;
|
||||
break;
|
||||
@ -4128,8 +4140,8 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
|
||||
RE_LVL_DMOD(150); // Base level bonus.
|
||||
break;
|
||||
case GC_CROSSIMPACT:
|
||||
skillratio += 900 + 100 * skill_lv;
|
||||
RE_LVL_DMOD(120);
|
||||
skillratio += -100 + 1000 + 150 * skill_lv;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case GC_COUNTERSLASH:
|
||||
//ATK [{(Skill Level x 150) + 300} x Caster's Base Level / 120]% + ATK [(AGI x 2) + (Caster's Job Level x 4)]%
|
||||
@ -4143,14 +4155,14 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
|
||||
skillratio += 200;
|
||||
break;
|
||||
case GC_ROLLINGCUTTER:
|
||||
skillratio += -50 + 50 * skill_lv;
|
||||
skillratio += -100 + 50 + 80 * skill_lv;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case GC_CROSSRIPPERSLASHER:
|
||||
skillratio += 300 + 80 * skill_lv;
|
||||
skillratio += -100 + 80 * skill_lv + (sstatus->agi * 3);
|
||||
RE_LVL_DMOD(100);
|
||||
if (sc && sc->data[SC_ROLLINGCUTTER])
|
||||
skillratio += sc->data[SC_ROLLINGCUTTER]->val1 * status_get_agi(src);
|
||||
skillratio += sc->data[SC_ROLLINGCUTTER]->val1 * 200;
|
||||
break;
|
||||
case GC_DARKCROW:
|
||||
skillratio += 100 * (skill_lv - 1);
|
||||
@ -4909,6 +4921,11 @@ static void battle_attack_sc_bonus(struct Damage* wd, struct block_list *src, st
|
||||
RE_ALLATK_ADDRATE(wd, sc->data[SC_GVG_GIANT]->val3);
|
||||
}
|
||||
|
||||
if (sc->data[SC_PYREXIA] && sc->data[SC_PYREXIA]->val3 == 0) {
|
||||
ATK_ADDRATE(wd->damage, wd->damage2, sc->data[SC_PYREXIA]->val2);
|
||||
RE_ALLATK_ADDRATE(wd, sc->data[SC_PYREXIA]->val2);
|
||||
}
|
||||
|
||||
if (sc->data[SC_MIRACLE])
|
||||
anger_id = 2; // Always treat all monsters as star flagged monster when in miracle state
|
||||
}
|
||||
@ -5859,7 +5876,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
#ifdef RENEWAL
|
||||
switch(skill_id) {
|
||||
case NJ_ISSEN:
|
||||
case ASC_BREAKER:
|
||||
break; //These skills will do a card fix later
|
||||
default:
|
||||
#endif
|
||||
@ -5938,7 +5954,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
#ifdef RENEWAL
|
||||
switch (skill_id) {
|
||||
case NJ_ISSEN:
|
||||
case ASC_BREAKER:
|
||||
return wd; //These skills will do a GVG fix later
|
||||
default:
|
||||
#endif
|
||||
@ -6602,13 +6617,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
}
|
||||
}
|
||||
#ifdef RENEWAL
|
||||
switch(skill_id) { // These skills will do a card fix later
|
||||
case ASC_BREAKER:
|
||||
break;
|
||||
default:
|
||||
ad.damage += battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
|
||||
break;
|
||||
}
|
||||
ad.damage += battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
|
||||
#endif
|
||||
|
||||
if(sd) {
|
||||
@ -6704,7 +6713,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
}
|
||||
}
|
||||
|
||||
if (!nk[NK_IGNOREELEMENT] && skill_id != ASC_BREAKER) // Soul Breaker's magic portion is non-elemental. [Secret]
|
||||
if (!nk[NK_IGNOREELEMENT])
|
||||
ad.damage = battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
|
||||
|
||||
//Apply the physical part of the skill's damage. [Skotlex]
|
||||
@ -6737,13 +6746,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
//Apply DAMAGE_DIV_FIX and check for min damage
|
||||
battle_apply_div_fix(&ad, skill_id);
|
||||
|
||||
#ifdef RENEWAL
|
||||
switch(skill_id) {
|
||||
case ASC_BREAKER:
|
||||
return ad; //These skills will do a GVG fix later
|
||||
}
|
||||
#endif
|
||||
|
||||
struct map_data *mapdata = map_getmapdata(target->m);
|
||||
|
||||
ad.damage = battle_calc_damage(src,target,&ad,ad.damage,skill_id,skill_lv);
|
||||
@ -6887,35 +6889,12 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
case NPC_EVILLAND:
|
||||
md.damage = skill_calc_heal(src,target,skill_id,skill_lv,false);
|
||||
break;
|
||||
#ifndef RENEWAL
|
||||
case ASC_BREAKER:
|
||||
#ifdef RENEWAL
|
||||
// Official Renewal formula [helvetica]
|
||||
// damage = ((atk + matk) * (3 + (.5 * skill level))) - (edef + sdef + emdef + smdef)
|
||||
// atk part takes weapon element, matk part is non-elemental
|
||||
// modified def formula
|
||||
{
|
||||
short totaldef, totalmdef;
|
||||
struct Damage atk, matk;
|
||||
|
||||
atk = battle_calc_weapon_attack(src, target, skill_id, skill_lv, 0);
|
||||
nk.set(NK_IGNOREELEMENT); // atk part takes on weapon element, matk part is non-elemental
|
||||
matk = battle_calc_magic_attack(src, target, skill_id, skill_lv, 0);
|
||||
|
||||
// (atk + matk) * (3 + (.5 * skill level))
|
||||
md.damage = ((30 + (5 * skill_lv)) * (atk.damage + matk.damage)) / 10;
|
||||
|
||||
// modified def reduction, final damage = base damage - (edef + sdef + emdef + smdef)
|
||||
totaldef = tstatus->def2 + (short)status_get_def(target);
|
||||
totalmdef = tstatus->mdef + tstatus->mdef2;
|
||||
md.damage -= totaldef + totalmdef;
|
||||
}
|
||||
#else
|
||||
md.damage = 500 + rnd()%500 + 5 * skill_lv * sstatus->int_;
|
||||
nk.set(NK_IGNOREFLEE);
|
||||
nk.set(NK_IGNOREELEMENT); //These two are not properties of the weapon based part.
|
||||
#endif
|
||||
break;
|
||||
#ifndef RENEWAL
|
||||
case HW_GRAVITATION:
|
||||
md.damage = 200 + 200 * skill_lv;
|
||||
md.dmotion = 0; //No flinch animation
|
||||
@ -7251,8 +7230,11 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
|
||||
sc = status_get_sc(bl);
|
||||
ssc = status_get_sc(src);
|
||||
|
||||
if (sc && sc->data[SC_WHITEIMPRISON])
|
||||
return 0; // White Imprison does not reflect any damage
|
||||
if (sc) { // These statuses do not reflect any damage (off the target)
|
||||
if (sc->data[SC_WHITEIMPRISON] || sc->data[SC_DARKCROW] ||
|
||||
(sc->data[SC_KYOMU] && (!ssc || !ssc->data[SC_SHIELDSPELL_DEF]))) // Nullify reflecting ability except for Shield Spell - Def
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ssc && ssc->data[SC_REF_T_POTION])
|
||||
return 0;
|
||||
@ -7320,20 +7302,22 @@ int64 battle_calc_return_damage(struct block_list* bl, struct block_list *src, i
|
||||
}
|
||||
}
|
||||
|
||||
if (ssc && ssc->data[SC_INSPIRATION]) {
|
||||
rdamage += damage / 100;
|
||||
if (ssc) {
|
||||
if (ssc->data[SC_INSPIRATION]) {
|
||||
rdamage += damage / 100;
|
||||
#ifdef RENEWAL
|
||||
rdamage = cap_value(rdamage, 1, max_damage);
|
||||
rdamage = cap_value(rdamage, 1, max_damage);
|
||||
#else
|
||||
rdamage = i64max(rdamage,1);
|
||||
rdamage = i64max(rdamage, 1);
|
||||
#endif
|
||||
}
|
||||
if (ssc->data[SC_VENOMBLEED] && ssc->data[SC_VENOMBLEED]->val3 == 0)
|
||||
rdamage -= damage * ssc->data[SC_VENOMBLEED]->val2 / 100;
|
||||
}
|
||||
|
||||
if (sc && sc->data[SC_KYOMU] && (!ssc || !ssc->data[SC_SHIELDSPELL_DEF])) // Nullify reflecting ability except for Shield Spell - Def
|
||||
rdamage = 0;
|
||||
|
||||
if (sc && sc->data[SC_MAXPAIN]) {
|
||||
rdamage = damage * sc->data[SC_MAXPAIN]->val1 * 10 / 100;
|
||||
if (sc) {
|
||||
if (sc->data[SC_MAXPAIN])
|
||||
rdamage = damage * sc->data[SC_MAXPAIN]->val1 * 10 / 100;
|
||||
}
|
||||
|
||||
return cap_value(min(rdamage,max_damage),INT_MIN,INT_MAX);
|
||||
|
@ -8977,7 +8977,7 @@ int pc_itemheal(struct map_session_data *sd, int itemid, int hp, int sp)
|
||||
if (sd->sc.data[SC_CRITICALWOUND])
|
||||
penalty += sd->sc.data[SC_CRITICALWOUND]->val2;
|
||||
|
||||
if (sd->sc.data[SC_DEATHHURT])
|
||||
if (sd->sc.data[SC_DEATHHURT] && sd->sc.data[SC_DEATHHURT]->val3 == 1)
|
||||
penalty += 20;
|
||||
|
||||
if (sd->sc.data[SC_NORECOVER_STATE])
|
||||
|
@ -740,7 +740,7 @@ int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 sk
|
||||
|
||||
if (tsc->data[SC_CRITICALWOUND])
|
||||
penalty += tsc->data[SC_CRITICALWOUND]->val2;
|
||||
if (tsc->data[SC_DEATHHURT])
|
||||
if (tsc->data[SC_DEATHHURT] && tsc->data[SC_DEATHHURT]->val3 == 1)
|
||||
penalty += 20;
|
||||
if (tsc->data[SC_NORECOVER_STATE])
|
||||
penalty = 100;
|
||||
@ -1233,7 +1233,11 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
||||
|
||||
if( sd )
|
||||
{ // These statuses would be applied anyway even if the damage was blocked by some skills. [Inkfish]
|
||||
if( skill_id != WS_CARTTERMINATION && skill_id != AM_DEMONSTRATION && skill_id != CR_REFLECTSHIELD && skill_id != MS_REFLECTSHIELD && skill_id != ASC_BREAKER ) {
|
||||
if( skill_id != WS_CARTTERMINATION && skill_id != AM_DEMONSTRATION && skill_id != CR_REFLECTSHIELD && skill_id != MS_REFLECTSHIELD
|
||||
#ifndef RENEWAL
|
||||
&& skill_id != ASC_BREAKER
|
||||
#endif
|
||||
) {
|
||||
// Trigger status effects
|
||||
enum sc_type type;
|
||||
unsigned int time;
|
||||
@ -4818,9 +4822,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
case GS_FULLBUSTER:
|
||||
case NJ_SYURIKEN:
|
||||
case NJ_KUNAI:
|
||||
#ifndef RENEWAL
|
||||
case ASC_BREAKER:
|
||||
#endif
|
||||
case HFLI_MOON: //[orn]
|
||||
case HFLI_SBR44: //[orn]
|
||||
case NPC_BLEEDING:
|
||||
@ -4834,7 +4836,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
case NC_AXEBOOMERANG:
|
||||
case NC_POWERSWING:
|
||||
case NC_MAGMA_ERUPTION:
|
||||
case GC_CROSSIMPACT:
|
||||
case GC_WEAPONCRUSH:
|
||||
case GC_VENOMPRESSURE:
|
||||
case SC_TRIANGLESHOT:
|
||||
@ -5518,9 +5519,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
case CR_ACIDDEMONSTRATION:
|
||||
#endif
|
||||
case TF_THROWSTONE:
|
||||
#ifdef RENEWAL
|
||||
case ASC_BREAKER:
|
||||
#endif
|
||||
case NPC_SMOKING:
|
||||
case GS_FLING:
|
||||
case NJ_ZENYNAGE:
|
||||
@ -5675,7 +5673,14 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
else
|
||||
{
|
||||
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
|
||||
status_change_end(src,SC_ROLLINGCUTTER,INVALID_TIMER);
|
||||
}
|
||||
break;
|
||||
case GC_CROSSIMPACT: {
|
||||
uint8 dir = map_calc_dir(bl, src->x, src->y);
|
||||
|
||||
if (skill_check_unit_movepos(5, src, bl->x, bl->y, 1, 1))
|
||||
skill_blown(src, src, 1, (dir + 4) % 8, BLOWN_NONE); // Target position is actually one cell next to the target
|
||||
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
|
||||
}
|
||||
break;
|
||||
|
||||
@ -8301,7 +8306,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
}
|
||||
if (tsc->data[SC_CRITICALWOUND])
|
||||
penalty += tsc->data[SC_CRITICALWOUND]->val2;
|
||||
if (tsc->data[SC_DEATHHURT])
|
||||
if (tsc->data[SC_DEATHHURT] && tsc->data[SC_DEATHHURT]->val3)
|
||||
penalty += 20;
|
||||
if (tsc->data[SC_NORECOVER_STATE])
|
||||
penalty = 100;
|
||||
@ -8532,6 +8537,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
#ifdef RENEWAL
|
||||
clif_blown(src); // Always blow, otherwise it shows a casting animation. [Lemongrass]
|
||||
#endif
|
||||
status_change_end(src, SC_ROLLINGCUTTER, INVALID_TIMER);
|
||||
break;
|
||||
|
||||
case TK_HIGHJUMP:
|
||||
@ -9169,7 +9175,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
}
|
||||
if (tsc->data[SC_CRITICALWOUND])
|
||||
penalty += tsc->data[SC_CRITICALWOUND]->val2;
|
||||
if (tsc->data[SC_DEATHHURT])
|
||||
if (tsc->data[SC_DEATHHURT] && tsc->data[SC_DEATHHURT]->val3 == 1)
|
||||
penalty += 20;
|
||||
if (tsc->data[SC_NORECOVER_STATE])
|
||||
penalty = 100;
|
||||
@ -17468,16 +17474,18 @@ int skill_delayfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv)
|
||||
}
|
||||
}
|
||||
|
||||
if (sc && sc->data[SC_SPIRIT]) {
|
||||
switch (skill_id) {
|
||||
case CR_SHIELDBOOMERANG:
|
||||
if (sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
|
||||
time /= 2;
|
||||
break;
|
||||
case AS_SONICBLOW:
|
||||
if (!map_flag_gvg2(bl->m) && !map_getmapflag(bl->m, MF_BATTLEGROUND) && sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
|
||||
time /= 2;
|
||||
break;
|
||||
if (sc && sc->count) {
|
||||
if (sc->data[SC_SPIRIT]) {
|
||||
switch (skill_id) {
|
||||
case CR_SHIELDBOOMERANG:
|
||||
if (sc->data[SC_SPIRIT]->val2 == SL_CRUSADER)
|
||||
time /= 2;
|
||||
break;
|
||||
case AS_SONICBLOW:
|
||||
if (!map_flag_gvg2(bl->m) && !map_getmapflag(bl->m, MF_BATTLEGROUND) && sc->data[SC_SPIRIT]->val2 == SL_ASSASIN)
|
||||
time /= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -17487,6 +17495,8 @@ int skill_delayfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv)
|
||||
time -= time * sc->data[SC_POEMBRAGI]->val3 / 100;
|
||||
if (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 3 && skill_get_type(skill_id) == BF_MAGIC && skill_get_ele(skill_id, skill_lv) == ELE_WIND)
|
||||
time /= 2; // After Delay of Wind element spells reduced by 50%.
|
||||
if (sc->data[SC_MAGICMUSHROOM] && sc->data[SC_MAGICMUSHROOM]->val3 == 0)
|
||||
time -= time * sc->data[SC_MAGICMUSHROOM]->val2 / 100;
|
||||
}
|
||||
}
|
||||
|
||||
@ -20477,27 +20487,27 @@ bool skill_arrow_create(struct map_session_data *sd, unsigned short nameid)
|
||||
*/
|
||||
int skill_poisoningweapon(struct map_session_data *sd, unsigned short nameid)
|
||||
{
|
||||
sc_type type;
|
||||
int chance, i, val4 = 0;
|
||||
//uint16 msg = 1443; //Official is using msgstringtable.txt
|
||||
char output[CHAT_SIZE_MAX];
|
||||
const char *msg;
|
||||
|
||||
nullpo_ret(sd);
|
||||
|
||||
if( !nameid || (i = pc_search_inventory(sd,nameid)) < 0 || pc_delitem(sd,i,1,0,0,LOG_TYPE_CONSUME) ) {
|
||||
if( !nameid || pc_delitem(sd,pc_search_inventory(sd,nameid),1,0,0,LOG_TYPE_CONSUME) ) {
|
||||
clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
switch( nameid ) { // t_lv used to take duration from skill_get_time2
|
||||
sc_type type;
|
||||
int chance;
|
||||
//uint16 msg = 1443; //Official is using msgstringtable.txt
|
||||
char output[CHAT_SIZE_MAX];
|
||||
const char *msg;
|
||||
|
||||
switch( nameid ) {
|
||||
case ITEMID_PARALYSE: type = SC_PARALYSE; /*msg = 1444;*/ msg = "Paralyze"; break;
|
||||
case ITEMID_PYREXIA: type = SC_PYREXIA; /*msg = 1448;*/ msg = "Pyrexia"; break;
|
||||
case ITEMID_DEATHHURT: type = SC_DEATHHURT; /*msg = 1447;*/ msg = "Deathhurt"; break;
|
||||
case ITEMID_LEECHESEND: type = SC_LEECHESEND; /*msg = 1450;*/ msg = "Leech End"; val4 = sd->bl.id; break;
|
||||
case ITEMID_LEECHESEND: type = SC_LEECHESEND; /*msg = 1450;*/ msg = "Leech End"; break;
|
||||
case ITEMID_VENOMBLEED: type = SC_VENOMBLEED; /*msg = 1445;*/ msg = "Venom Bleed"; break;
|
||||
case ITEMID_TOXIN: type = SC_TOXIN; /*msg = 1443;*/ msg = "Toxin"; val4 = sd->bl.id; break;
|
||||
case ITEMID_MAGICMUSHROOM: type = SC_MAGICMUSHROOM; /*msg = 1446;*/ msg = "Magic Mushroom"; val4 = sd->bl.id; break;
|
||||
case ITEMID_TOXIN: type = SC_TOXIN; /*msg = 1443;*/ msg = "Toxin"; break;
|
||||
case ITEMID_MAGICMUSHROOM: type = SC_MAGICMUSHROOM; /*msg = 1446;*/ msg = "Magic Mushroom"; break;
|
||||
case ITEMID_OBLIVIONCURSE: type = SC_OBLIVIONCURSE; /*msg = 1449;*/ msg = "Oblivion Curse"; break;
|
||||
default:
|
||||
clif_skill_fail(sd,GC_POISONINGWEAPON,USESKILL_FAIL_LEVEL,0);
|
||||
@ -20507,7 +20517,8 @@ int skill_poisoningweapon(struct map_session_data *sd, unsigned short nameid)
|
||||
status_change_end(&sd->bl, SC_POISONINGWEAPON, INVALID_TIMER); // End the status so a new poison can be applied (if changed)
|
||||
chance = 2 + 2 * sd->menuskill_val; // 2 + 2 * skill_lv
|
||||
sc_start4(&sd->bl,&sd->bl, SC_POISONINGWEAPON, 100, pc_checkskill(sd, GC_RESEARCHNEWPOISON), //in Aegis it store the level of GC_RESEARCHNEWPOISON in val1
|
||||
type, chance, val4, skill_get_time(GC_POISONINGWEAPON, sd->menuskill_val));
|
||||
type, chance, 0, skill_get_time(GC_POISONINGWEAPON, sd->menuskill_val));
|
||||
status_change_start(&sd->bl, &sd->bl, type, 10000, sd->menuskill_val, 0, 0, 0, skill_get_time(GC_POISONINGWEAPON, sd->menuskill_val), SCSTART_NOAVOID | SCSTART_NOICON); // Apply bonus to caster
|
||||
|
||||
sprintf(output, msg_txt(sd,721), msg);
|
||||
clif_messagecolor(&sd->bl,color_table[COLOR_WHITE],output,false,SELF);
|
||||
|
@ -2294,7 +2294,7 @@ public:
|
||||
}
|
||||
|
||||
const std::string getDefaultLocation();
|
||||
uint64 parseBodyNode(const YAML::Node& node);
|
||||
uint64 parseBodyNode(const YAML::Node &node);
|
||||
};
|
||||
|
||||
extern MagicMushroomDatabase magic_mushroom_db;
|
||||
|
@ -1469,7 +1469,7 @@ void initChangeTables(void)
|
||||
StatusChangeFlagTable[SC_DEATHHURT] |= SCB_REGEN;
|
||||
StatusChangeFlagTable[SC_VENOMBLEED] |= SCB_MAXHP;
|
||||
StatusChangeFlagTable[SC_MAGICMUSHROOM] |= SCB_REGEN;
|
||||
StatusChangeFlagTable[SC_PYREXIA] |= SCB_HIT|SCB_FLEE;
|
||||
StatusChangeFlagTable[SC_PYREXIA] |= SCB_ALL;
|
||||
StatusChangeFlagTable[SC_OBLIVIONCURSE] |= SCB_REGEN;
|
||||
StatusChangeFlagTable[SC_BANDING_DEFENCE] |= SCB_SPEED;
|
||||
StatusChangeFlagTable[SC_SHIELDSPELL_DEF] |= SCB_WATK;
|
||||
@ -1694,7 +1694,7 @@ void initChangeTables(void)
|
||||
#endif
|
||||
StatusChangeStateTable[SC__BLOODYLUST] |= SCS_NOCAST;
|
||||
StatusChangeStateTable[SC_DEATHBOUND] |= SCS_NOCAST;
|
||||
StatusChangeStateTable[SC_OBLIVIONCURSE] |= SCS_NOCAST;
|
||||
StatusChangeStateTable[SC_OBLIVIONCURSE] |= SCS_NOCAST|SCS_NOCASTCOND;
|
||||
StatusChangeStateTable[SC_WHITEIMPRISON] |= SCS_NOCAST;
|
||||
StatusChangeStateTable[SC__SHADOWFORM] |= SCS_NOCAST;
|
||||
StatusChangeStateTable[SC__INVISIBILITY] |= SCS_NOCAST;
|
||||
@ -3415,7 +3415,7 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
|
||||
bonus += sc->data[SC_LUNARSTANCE]->val2;
|
||||
|
||||
//Decreasing
|
||||
if(sc->data[SC_VENOMBLEED])
|
||||
if (sc->data[SC_VENOMBLEED] && sc->data[SC_VENOMBLEED]->val3 == 1)
|
||||
bonus -= 15;
|
||||
if(sc->data[SC_BEYONDOFWARCRY])
|
||||
bonus -= sc->data[SC_BEYONDOFWARCRY]->val3;
|
||||
@ -4682,6 +4682,8 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt)
|
||||
sd->subele[ELE_GHOST] += sc->data[SC_SYMPHONYOFLOVER]->val1 * 3;
|
||||
sd->subele[ELE_HOLY] += sc->data[SC_SYMPHONYOFLOVER]->val1 * 3;
|
||||
}
|
||||
if (sc->data[SC_PYREXIA] && sc->data[SC_PYREXIA]->val3 == 0)
|
||||
sd->bonus.crit_atk_rate += sc->data[SC_PYREXIA]->val2;
|
||||
}
|
||||
status_cpy(&sd->battle_status, base_status);
|
||||
|
||||
@ -5098,7 +5100,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
|
||||
|| sc->data[SC_BERSERK]
|
||||
|| sc->data[SC_TRICKDEAD]
|
||||
|| sc->data[SC_BLEEDING]
|
||||
|| sc->data[SC_MAGICMUSHROOM]
|
||||
|| (sc->data[SC_MAGICMUSHROOM] && sc->data[SC_MAGICMUSHROOM]->val3 == 1)
|
||||
|| sc->data[SC_SATURDAYNIGHTFEVER]
|
||||
|| sc->data[SC_REBOUND])
|
||||
regen->flag = RGN_NONE;
|
||||
@ -5115,7 +5117,7 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
|
||||
(bl->type == BL_PC && (((TBL_PC*)bl)->class_&MAPID_UPPERMASK) == MAPID_MONK &&
|
||||
sc->data[SC_EXTREMITYFIST] && (!sc->data[SC_SPIRIT] || sc->data[SC_SPIRIT]->val2 != SL_MONK)) ||
|
||||
#endif
|
||||
sc->data[SC_OBLIVIONCURSE] || sc->data[SC_VITALITYACTIVATION])
|
||||
(sc->data[SC_OBLIVIONCURSE] && sc->data[SC_OBLIVIONCURSE]->val3 == 1) || sc->data[SC_VITALITYACTIVATION])
|
||||
regen->flag &= ~RGN_SP;
|
||||
|
||||
if (sc->data[SC_TENSIONRELAX]) {
|
||||
@ -5233,6 +5235,8 @@ void status_calc_state( struct block_list *bl, struct status_change *sc, enum sc
|
||||
if( flag&SCS_NOCAST ) {
|
||||
if( !(flag&SCS_NOCASTCOND) )
|
||||
sc->cant.cast += ( start ? 1 : -1 );
|
||||
else if (sc->data[SC_OBLIVIONCURSE] && sc->data[SC_OBLIVIONCURSE]->val3 == 1)
|
||||
sc->cant.cast += (start ? 1 : -1);
|
||||
}
|
||||
|
||||
// Can't chat
|
||||
@ -6931,7 +6935,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
|
||||
flee -= flee * 25/100;
|
||||
if(sc->data[SC_FEAR])
|
||||
flee -= flee * 20 / 100;
|
||||
if(sc->data[SC_PARALYSE])
|
||||
if(sc->data[SC_PARALYSE] && sc->data[SC_PARALYSE]->val3 == 1)
|
||||
flee -= flee * 10 / 100;
|
||||
if(sc->data[SC_INFRAREDSCAN])
|
||||
flee -= flee * 30 / 100;
|
||||
@ -7409,6 +7413,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
|
||||
val = max( val, 75 );
|
||||
if( sc->data[SC_CLOAKINGEXCEED] )
|
||||
val = max( val, sc->data[SC_CLOAKINGEXCEED]->val3);
|
||||
if (sc->data[SC_PARALYSE] && sc->data[SC_PARALYSE]->val3 == 0)
|
||||
val = max(val, 50);
|
||||
if( sc->data[SC_HOVERING] )
|
||||
val = max( val, 10 );
|
||||
if( sc->data[SC_GN_CARTBOOST] )
|
||||
@ -7441,7 +7447,7 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
|
||||
// GetSpeed()
|
||||
if( sd && pc_iscarton(sd) )
|
||||
speed += speed * (50 - 5 * pc_checkskill(sd,MC_PUSHCART)) / 100;
|
||||
if( sc->data[SC_PARALYSE] )
|
||||
if( sc->data[SC_PARALYSE] && sc->data[SC_PARALYSE]->val3 == 1 )
|
||||
speed += speed * 50 / 100;
|
||||
if( speed_rate != 100 )
|
||||
speed = speed * speed_rate / 100;
|
||||
@ -7542,7 +7548,7 @@ static short status_calc_aspd(struct block_list *bl, struct status_change *sc, b
|
||||
bonus -= 30;
|
||||
if (sc->data[SC_HALLUCINATIONWALK_POSTDELAY])
|
||||
bonus -= 50;
|
||||
if (sc->data[SC_PARALYSE])
|
||||
if (sc->data[SC_PARALYSE] && sc->data[SC_PARALYSE]->val3 == 1)
|
||||
bonus -= 10;
|
||||
if (sc->data[SC__BODYPAINT])
|
||||
bonus -= 5 * sc->data[SC__BODYPAINT]->val1;
|
||||
@ -7742,7 +7748,7 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
|
||||
aspd_rate += 300;
|
||||
if( sc->data[SC_HALLUCINATIONWALK_POSTDELAY] )
|
||||
aspd_rate += 500;
|
||||
if( sc->data[SC_PARALYSE] )
|
||||
if( sc->data[SC_PARALYSE] && sc->data[SC_PARALYSE]->val3 == 1 )
|
||||
aspd_rate += 100;
|
||||
if( sc->data[SC__BODYPAINT] )
|
||||
aspd_rate += 50 * sc->data[SC__BODYPAINT]->val1;
|
||||
@ -8549,8 +8555,9 @@ static int status_get_sc_interval(enum sc_type type)
|
||||
{
|
||||
switch (type) {
|
||||
case SC_POISON:
|
||||
case SC_DPOISON:
|
||||
case SC_LEECHESEND:
|
||||
case SC_DPOISON:
|
||||
case SC_DEATHHURT:
|
||||
return 1000;
|
||||
case SC_BURNING:
|
||||
case SC_PYREXIA:
|
||||
@ -8765,10 +8772,11 @@ t_tick status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_
|
||||
tick_def2 = (status->vit + status->dex)*50;
|
||||
break;
|
||||
case SC_OBLIVIONCURSE: // 100% - (100 - 0.8 x INT)
|
||||
sc_def = status->int_*80;
|
||||
sc_def = status->int_ * 80;
|
||||
sc_def = max(sc_def, 500); // minimum of 5% resist
|
||||
tick_def = 0;
|
||||
//Fall through
|
||||
tick_def2 = (status->vit + status->luk) * 500;
|
||||
break;
|
||||
case SC_TOXIN:
|
||||
case SC_PARALYSE:
|
||||
case SC_VENOMBLEED:
|
||||
@ -8853,6 +8861,19 @@ t_tick status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_
|
||||
#endif
|
||||
else if (sc->data[SC_SHIELDSPELL_REF] && sc->data[SC_SHIELDSPELL_REF]->val1 == 2)
|
||||
sc_def += sc->data[SC_SHIELDSPELL_REF]->val3*100;
|
||||
else if (sc->data[SC_LEECHESEND] && sc->data[SC_LEECHESEND]->val3 == 0) {
|
||||
switch (type) {
|
||||
case SC_BLIND:
|
||||
case SC_STUN:
|
||||
return 0; // Immune
|
||||
}
|
||||
} else if (sc->data[SC_OBLIVIONCURSE] && sc->data[SC_OBLIVIONCURSE]->val3 == 0) {
|
||||
switch (type) {
|
||||
case SC_SILENCE:
|
||||
case SC_CURSE:
|
||||
return 0; // Immune
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// When tick def not set, reduction is the same for both.
|
||||
@ -9497,12 +9518,13 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_PYREXIA:
|
||||
case SC_OBLIVIONCURSE:
|
||||
case SC_LEECHESEND:
|
||||
{ // It doesn't stack or even renew
|
||||
int i = SC_TOXIN;
|
||||
for(; i<= SC_LEECHESEND; i++)
|
||||
if(sc->data[i]) return 0;
|
||||
for (int32 i = SC_TOXIN; i <= SC_LEECHESEND; i++) {
|
||||
if (sc->data[i] && sc->data[i]->val3 == 1) // It doesn't stack or even renew on the target
|
||||
return 0;
|
||||
else if (sc->data[i] && sc->data[i]->val3 == 0)
|
||||
status_change_end(bl, static_cast<sc_type>(i), INVALID_TIMER); // End the bonus part on the caster
|
||||
}
|
||||
break;
|
||||
break;
|
||||
case SC_SATURDAYNIGHTFEVER:
|
||||
if (sc->data[SC_BERSERK] || sc->data[SC_INSPIRATION])
|
||||
return 0;
|
||||
@ -10248,8 +10270,14 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
#ifndef RENEWAL
|
||||
val3 = 50*(val1+1); // Damage increase (+50 +50*lv%)
|
||||
#endif
|
||||
if( sd )// [Ind] - iROwiki says each level increases its duration by 3 seconds
|
||||
tick += pc_checkskill(sd,GC_RESEARCHNEWPOISON)*3000;
|
||||
if (sd) {
|
||||
uint16 poison_level = pc_checkskill(sd, GC_RESEARCHNEWPOISON);
|
||||
|
||||
if (poison_level > 0) {
|
||||
tick += 30000; // Base of 30 seconds
|
||||
tick += poison_level * 15 * 1000; // Additional 15 seconds per level
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_POISONREACT:
|
||||
val2=(val1+1)/2 + val1/10; // Number of counters [Skotlex]
|
||||
@ -10522,18 +10550,46 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_POISON:
|
||||
case SC_BLEEDING:
|
||||
case SC_BURNING:
|
||||
case SC_TOXIN:
|
||||
case SC_MAGICMUSHROOM:
|
||||
case SC_LEECHESEND:
|
||||
tick_time = status_get_sc_interval(type);
|
||||
val4 = tick-tick_time; // Remaining time
|
||||
val4 = tick - tick_time; // Remaining time
|
||||
break;
|
||||
|
||||
case SC_PYREXIA:
|
||||
//Causes blind for duration of pyrexia, unreducable and unavoidable, but can be healed with e.g. green potion
|
||||
status_change_start(src,bl,SC_BLIND,10000,val1,0,0,0,tick,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF);
|
||||
case SC_TOXIN:
|
||||
if (val3 == 1) // Target
|
||||
tick_time = status_get_sc_interval(type);
|
||||
else // Caster
|
||||
tick_time = 1000;
|
||||
val4 = tick - tick_time; // Remaining time
|
||||
break;
|
||||
case SC_DEATHHURT:
|
||||
if (val3 == 1)
|
||||
break;
|
||||
tick_time = status_get_sc_interval(type);
|
||||
val4 = tick-tick_time; // Remaining time
|
||||
val4 = tick - tick_time; // Remaining time
|
||||
case SC_LEECHESEND:
|
||||
if (val3 == 0)
|
||||
break;
|
||||
tick_time = status_get_sc_interval(type);
|
||||
val4 = tick - tick_time; // Remaining time
|
||||
break;
|
||||
case SC_PYREXIA:
|
||||
if (val3 == 1) { // Target
|
||||
// Causes blind for duration of pyrexia, unreducable and unavoidable, but can be healed with e.g. green potion
|
||||
status_change_start(src, bl, SC_BLIND, 10000, val1, 0, 0, 0, tick, SCSTART_NOAVOID | SCSTART_NOTICKDEF | SCSTART_NORATEDEF);
|
||||
tick_time = status_get_sc_interval(type);
|
||||
val4 = tick - tick_time; // Remaining time
|
||||
} else // Caster
|
||||
val2 = 15; // CRIT % and ATK % increase
|
||||
break;
|
||||
case SC_VENOMBLEED:
|
||||
if (val3 == 0) // Caster
|
||||
val2 = 30; // Reflect damage % reduction
|
||||
break;
|
||||
case SC_MAGICMUSHROOM:
|
||||
if (val3 == 1) { // Target
|
||||
tick_time = status_get_sc_interval(type);
|
||||
val4 = tick - tick_time; // Remaining time
|
||||
} else // Caster
|
||||
val2 = 10; // After-cast delay % reduction
|
||||
break;
|
||||
|
||||
case SC_CONFUSION:
|
||||
@ -11175,6 +11231,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
tick_time = 5000; // [GodLesZ] tick time
|
||||
break;
|
||||
case SC_OBLIVIONCURSE:
|
||||
if (val3 == 0)
|
||||
break;
|
||||
val4 = tick / 3000;
|
||||
tick_time = 3000; // [GodLesZ] tick time
|
||||
break;
|
||||
@ -11759,7 +11817,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
val2 = 20 * val1 + 20; // atk bonus
|
||||
break;
|
||||
case SC_DARKCROW:
|
||||
val2 = 30 * val1;
|
||||
val2 = 30 * val1; // ATK bonus
|
||||
break;
|
||||
case SC_UNLIMIT:
|
||||
val2 = 50 * val1;
|
||||
@ -12098,11 +12156,21 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_BLEEDING:
|
||||
case SC_BURNING:
|
||||
case SC_TOXIN:
|
||||
tick_time = tick;
|
||||
tick = tick_time + max(val4, 0);
|
||||
break;
|
||||
case SC_DEATHHURT:
|
||||
if (val3 == 1)
|
||||
break;
|
||||
tick_time = tick;
|
||||
tick = tick_time + max(val4, 0);
|
||||
case SC_MAGICMUSHROOM:
|
||||
case SC_PYREXIA:
|
||||
case SC_LEECHESEND:
|
||||
if (val3 == 0)
|
||||
break;
|
||||
tick_time = tick;
|
||||
tick = tick_time + max(val4,0);
|
||||
tick = tick_time + max(val4, 0);
|
||||
break;
|
||||
case SC_SWORDCLAN:
|
||||
case SC_ARCWANDCLAN:
|
||||
@ -13861,12 +13929,19 @@ TIMER_FUNC(status_change_timer){
|
||||
status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, 0, 1, damage, 1, DMG_NORMAL, 0, false),0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SC_TOXIN:
|
||||
if (sce->val4 >= 0) { // Damage is every 10 seconds including 3%sp drain.
|
||||
map_freeblock_lock();
|
||||
dounlock = true;
|
||||
status_damage(bl, bl, 1, status->max_sp * 3 / 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 1, 1, DMG_NORMAL, 0, false), 0, 0);
|
||||
if (sce->val3 == 1) { // Target
|
||||
map_freeblock_lock();
|
||||
dounlock = true;
|
||||
status_damage(bl, bl, 1, status->max_sp * 3 / 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 1, 1, DMG_NORMAL, 0, false), 0, 0);
|
||||
} else { // Caster
|
||||
interval = 1000; // Assign here since status_get_sc_internval() contains the target interval.
|
||||
|
||||
if (status->sp < status->max_sp)
|
||||
status_heal(bl, 0, (int)status->max_sp * 1 / 100, 1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
@ -13914,7 +13989,7 @@ TIMER_FUNC(status_change_timer){
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SC_PYREXIA:
|
||||
if (sce->val4 >= 0) {
|
||||
map_freeblock_lock();
|
||||
@ -13922,7 +13997,7 @@ TIMER_FUNC(status_change_timer){
|
||||
status_fix_damage(bl, bl, 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 100, 1, DMG_NORMAL, 0, false),0);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SC_LEECHESEND:
|
||||
if (sce->val4 >= 0) {
|
||||
int64 damage = status->vit * (sce->val1 - 3) + (int)status->max_hp / 100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
|
||||
@ -13933,6 +14008,13 @@ TIMER_FUNC(status_change_timer){
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_DEATHHURT:
|
||||
if (sce->val4 >= 0) {
|
||||
if (status->hp < status->max_hp)
|
||||
status_heal(bl, (int)status->max_hp * 1 / 100, 0, 1);
|
||||
}
|
||||
break;
|
||||
|
||||
case SC_TENSIONRELAX:
|
||||
if(status->max_hp > status->hp && --(sce->val3) >= 0) {
|
||||
sc_timer_next(10000 + tick);
|
||||
@ -14116,7 +14198,7 @@ TIMER_FUNC(status_change_timer){
|
||||
sc_timer_next(10000+tick);
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
case SC_OBLIVIONCURSE:
|
||||
if( --(sce->val4) >= 0 ) {
|
||||
clif_emotion(bl,ET_QUESTION);
|
||||
|
@ -89,7 +89,7 @@ std::unordered_map<uint16, s_skill_db> skill_nearnpc;
|
||||
// Forward declaration of conversion functions
|
||||
static bool guild_read_guildskill_tree_db( char* split[], int columns, int current );
|
||||
static bool pet_read_db( const char* file );
|
||||
static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current);
|
||||
static bool skill_parse_row_magicmushroomdb(char *split[], int column, int current);
|
||||
static bool skill_parse_row_abradb(char* split[], int columns, int current);
|
||||
static bool skill_parse_row_spellbookdb(char* split[], int columns, int current);
|
||||
static bool mob_readdb_mobavail(char *str[], int columns, int current);
|
||||
@ -312,7 +312,7 @@ int do_init( int argc, char** argv ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!process("MAGIC_MUSHROOM_DB", 1, root_paths, "magicmushroom_db", [](const std::string& path, const std::string& name_ext) -> bool {
|
||||
if (!process("MAGIC_MUSHROOM_DB", 1, root_paths, "magicmushroom_db", [](const std::string &path, const std::string &name_ext) -> bool {
|
||||
return sv_readdb(path.c_str(), name_ext.c_str(), ',', 1, 1, -1, &skill_parse_row_magicmushroomdb, false);
|
||||
})) {
|
||||
return 0;
|
||||
@ -865,7 +865,7 @@ static bool pet_read_db( const char* file ){
|
||||
}
|
||||
|
||||
// Copied and adjusted from skill.cpp
|
||||
static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current)
|
||||
static bool skill_parse_row_magicmushroomdb(char *split[], int column, int current)
|
||||
{
|
||||
uint16 skill_id = atoi(split[0]);
|
||||
std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
|
||||
|
Loading…
x
Reference in New Issue
Block a user