Mercenary, Regen and Frenzy Improvements (#8185)
- When a Mercenary gains a bonus, there will now be an animation - Mercenary bonuses now last for 5 minutes instead of 10 minutes - Fixed HP/SP recovery values of Mercenaries (and Elementals) - Mercenaries now recover HP when walking - Homunculi no longer recover SP when walking - Mercenary natural recovery interval is 8s for HP and 6s for SP - Homunculus natural recovery interval is 2s for HP and 4s for SP - MER_CRASH now only deals 1 hit and can be cast-cancelled - Frenzy now drains HP every 10 seconds instead of every 15 in pre-renewal - Fixed SP cost Mercenary Frenzy (100 -> 200 SP) - Killing monsters exactly 2 times below you base level now still counts as mercenary kill - Fixes #8184 - Fixes #7663
This commit is contained in:
parent
ed2d03d811
commit
1a004f0164
@ -9641,7 +9641,7 @@ Body:
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Duration1: 300000
|
||||
Duration2: 15000
|
||||
Duration2: 10000
|
||||
Requires:
|
||||
SpCost: 200
|
||||
Status: Berserk
|
||||
@ -32467,9 +32467,9 @@ Body:
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Duration1: 300000
|
||||
Duration2: 15000
|
||||
Duration2: 10000
|
||||
Requires:
|
||||
SpCost: 100
|
||||
SpCost: 200
|
||||
Status: Berserk
|
||||
- Id: 8207
|
||||
Name: MA_DOUBLE
|
||||
@ -33068,9 +33068,10 @@ Body:
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
Range: 1
|
||||
Hit: Multi_Hit
|
||||
HitCount: 3
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Weapon
|
||||
CastCancel: true
|
||||
CastTime: 1000
|
||||
AfterCastActDelay: 2000
|
||||
Duration2: 5000
|
||||
|
@ -2712,6 +2712,7 @@ Body:
|
||||
CalcFlags:
|
||||
Flee: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
@ -2720,6 +2721,7 @@ Body:
|
||||
CalcFlags:
|
||||
Watk: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
@ -2728,6 +2730,7 @@ Body:
|
||||
CalcFlags:
|
||||
MaxHp: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
@ -2736,6 +2739,7 @@ Body:
|
||||
CalcFlags:
|
||||
MaxSp: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
@ -2744,6 +2748,7 @@ Body:
|
||||
CalcFlags:
|
||||
Hit: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
|
@ -46490,9 +46490,10 @@ Body:
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
Range: 1
|
||||
Hit: Multi_Hit
|
||||
HitCount: 3
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Weapon
|
||||
CastCancel: true
|
||||
CastTime: 1000
|
||||
AfterCastActDelay: 2000
|
||||
Duration2: 4500
|
||||
|
@ -2822,6 +2822,7 @@ Body:
|
||||
CalcFlags:
|
||||
Flee: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
@ -2830,6 +2831,7 @@ Body:
|
||||
CalcFlags:
|
||||
Watk: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
@ -2838,6 +2840,7 @@ Body:
|
||||
CalcFlags:
|
||||
MaxHp: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
@ -2846,6 +2849,7 @@ Body:
|
||||
CalcFlags:
|
||||
MaxSp: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
@ -2854,6 +2858,7 @@ Body:
|
||||
CalcFlags:
|
||||
Hit: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
|
@ -6579,7 +6579,8 @@ void clif_status_change(struct block_list *bl, int type, int flag, t_tick tick,
|
||||
|
||||
sd = BL_CAST(BL_PC, bl);
|
||||
|
||||
if (!(status_efst_get_bl_type((efst_type)type)&bl->type)) // only send status changes that actually matter to the client
|
||||
// Check if current bl type is in the returned bitmask and only send status changes that actually matter to the client
|
||||
if (!(status_efst_get_bl_type(static_cast<efst_type>(type)) & bl->type))
|
||||
return;
|
||||
|
||||
clif_status_change_sub(bl, bl->id, type, flag, tick, val1, val2, val3, ((sd ? (pc_isinvisible(sd) ? SELF : AREA) : AREA_WOS)));
|
||||
|
@ -421,7 +421,7 @@ bool mercenary_dead(s_mercenary_data *md) {
|
||||
void mercenary_killbonus(s_mercenary_data *md) {
|
||||
std::vector<sc_type> scs = { SC_MERC_FLEEUP, SC_MERC_ATKUP, SC_MERC_HPUP, SC_MERC_SPUP, SC_MERC_HITUP };
|
||||
|
||||
sc_start(&md->bl,&md->bl, util::vector_random(scs), 100, rnd_value(1, 5), 600000);
|
||||
sc_start(&md->bl,&md->bl, util::vector_random(scs), 100, rnd_value(1, 5), 300000); //Bonus lasts for 5 minutes
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -3109,8 +3109,8 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
achievement_update_objective(sd, AG_BATTLE, 1, md->mob_id);
|
||||
}
|
||||
|
||||
// The master or Mercenary can increase the kill count
|
||||
if (sd->md && src && (src->type == BL_PC || src->type == BL_MER) && mob->lv > sd->status.base_level / 2)
|
||||
// The master or Mercenary can increase the kill count, if the monster level is greater or equal than half the baselevel of the master
|
||||
if (sd->md && src && (src->type == BL_PC || src->type == BL_MER) && mob->lv >= sd->status.base_level / 2)
|
||||
mercenary_kills(sd->md);
|
||||
}
|
||||
|
||||
|
@ -5261,16 +5261,16 @@ void status_calc_regen(struct block_list *bl, struct status_data *status, struct
|
||||
regen->sp = cap_value(val, 1, SHRT_MAX);
|
||||
}
|
||||
} else if( bl->type == BL_MER ) {
|
||||
val = (status->max_hp * status->vit / 10000 + 1) * 6;
|
||||
val = static_cast<decltype(val)>((status->max_hp * status->vit / 10000.0 + 1.0) * 6.0);
|
||||
regen->hp = cap_value(val, 1, SHRT_MAX);
|
||||
|
||||
val = (status->max_sp * (status->int_ + 10) / 750) + 1;
|
||||
val = static_cast<decltype(val)>((status->max_sp * (status->int_ + 10.0) / 750.0) + 1.0);
|
||||
regen->sp = cap_value(val, 1, SHRT_MAX);
|
||||
} else if( bl->type == BL_ELEM ) {
|
||||
val = (status->max_hp * status->vit / 10000 + 1) * 6;
|
||||
val = static_cast<decltype(val)>((status->max_hp * status->vit / 10000.0 + 1.0) * 6.0);
|
||||
regen->hp = cap_value(val, 1, SHRT_MAX);
|
||||
|
||||
val = (status->max_sp * (status->int_ + 10) / 750) + 1;
|
||||
val = static_cast<decltype(val)>((status->max_sp * (status->int_ + 10.0) / 750.0) + 1.0);
|
||||
regen->sp = cap_value(val, 1, SHRT_MAX);
|
||||
}
|
||||
}
|
||||
@ -15237,10 +15237,14 @@ static int status_natural_heal(struct block_list* bl, va_list args)
|
||||
|
||||
ud = unit_bl2ud(bl);
|
||||
|
||||
if (flag&(RGN_HP|RGN_SHP|RGN_SSP) && ud && ud->walktimer != INVALID_TIMER) {
|
||||
if (ud && ud->walktimer != INVALID_TIMER) {
|
||||
flag &= ~(RGN_SHP|RGN_SSP);
|
||||
if(!regen->state.walk)
|
||||
//Mercenaries recover HP even while walking
|
||||
if(bl->type != BL_MER && !regen->state.walk)
|
||||
flag &= ~RGN_HP;
|
||||
//Homunculus don't recover SP while walking
|
||||
if (bl->type == BL_HOM && !regen->state.walk)
|
||||
flag &= ~RGN_SP;
|
||||
}
|
||||
|
||||
if (flag&(RGN_HP|RGN_SP)) {
|
||||
@ -15256,11 +15260,15 @@ static int status_natural_heal(struct block_list* bl, va_list args)
|
||||
if (flag&RGN_HP) {
|
||||
// Interval to next recovery tick
|
||||
rate = (int)(battle_config.natural_healhp_interval / (regen->rate.hp/100. * multi));
|
||||
if (ud && ud->walktimer != INVALID_TIMER)
|
||||
// Half recovery while moving only applies to players with certain traits
|
||||
if (sd && 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 (2 seconds instead of 6 seconds)
|
||||
if(bl->type == BL_HOM)
|
||||
rate /= 2;
|
||||
rate /= 3;
|
||||
// Mercenary HP regen fix (8 seconds instead of 6 seconds)
|
||||
if (bl->type == BL_MER)
|
||||
rate = (rate * 4) / 3;
|
||||
|
||||
// Our timer system isn't 100% accurate so make sure we use the closest interval
|
||||
rate -= NATURAL_HEAL_INTERVAL / 2;
|
||||
@ -15281,9 +15289,12 @@ static int status_natural_heal(struct block_list* bl, va_list args)
|
||||
if(flag&RGN_SP) {
|
||||
// Interval to next recovery tick
|
||||
rate = (int)(battle_config.natural_healsp_interval / (regen->rate.sp/100. * multi));
|
||||
// Homun SP regen fix (they should regen as if they were sitting (twice as fast)
|
||||
// Homun SP regen fix (4 seconds instead of 8 seconds)
|
||||
if(bl->type==BL_HOM)
|
||||
rate /= 2;
|
||||
// Mercenary SP regen fix (6 seconds instead of 8 seconds)
|
||||
if (bl->type == BL_MER)
|
||||
rate = (rate * 3) / 4;
|
||||
#ifdef RENEWAL
|
||||
if (sd && (sd->class_&MAPID_UPPERMASK) == MAPID_MONK &&
|
||||
sc && sc->getSCE(SC_EXPLOSIONSPIRITS) && (!sc->getSCE(SC_SPIRIT) || sc->getSCE(SC_SPIRIT)->val2 != SL_MONK))
|
||||
|
Loading…
x
Reference in New Issue
Block a user