Adjusts NPC_EARTHQUAKE behavior (#5017)
* Fixes #1679 and fixes #3176. * Converts the skill to a unit-based skill. * Damage is now properly calculated based on the caster's ATK. * Damage is considered magic with the element forced to Neutral. * Now ignores target's DEF and Land Protector. * Kaupe and Tumbling now can avoid the first attack only. * Removed old bits of the skill. Thanks to @poporing, @mrjnumber1, @Daegaladh, @malufett, and @exneval!
This commit is contained in:
parent
36b9b942c9
commit
53e7f59f48
@ -15307,10 +15307,12 @@ Body:
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
SplashSplit: true
|
||||
IgnoreDefense: true
|
||||
Flags:
|
||||
IsNpc: true
|
||||
TargetTrap: true
|
||||
ShowScale: true
|
||||
IgnoreLandProtector: true
|
||||
Hit: Multi_Hit
|
||||
HitCount: 1
|
||||
SplashArea:
|
||||
@ -15334,6 +15336,34 @@ Body:
|
||||
Area: 11
|
||||
- Level: 10
|
||||
Area: 13
|
||||
Duration1: 910
|
||||
Unit:
|
||||
Id: Earthquake
|
||||
Range:
|
||||
- Level: 1
|
||||
Size: 5
|
||||
- Level: 2
|
||||
Size: 7
|
||||
- Level: 3
|
||||
Size: 9
|
||||
- Level: 4
|
||||
Size: 11
|
||||
- Level: 5
|
||||
Size: 13
|
||||
- Level: 6
|
||||
Size: 5
|
||||
- Level: 7
|
||||
Size: 7
|
||||
- Level: 8
|
||||
Size: 9
|
||||
- Level: 9
|
||||
Size: 11
|
||||
- Level: 10
|
||||
Size: 13
|
||||
Interval: 300
|
||||
Target: Enemy
|
||||
Flag:
|
||||
PathCheck: true
|
||||
- Id: 654
|
||||
Name: NPC_FIREBREATH
|
||||
Description: Fire Breath
|
||||
|
@ -15705,10 +15705,12 @@ Body:
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
SplashSplit: true
|
||||
IgnoreDefense: true
|
||||
Flags:
|
||||
IsNpc: true
|
||||
TargetTrap: true
|
||||
ShowScale: true
|
||||
IgnoreLandProtector: true
|
||||
Hit: Multi_Hit
|
||||
HitCount: 1
|
||||
SplashArea:
|
||||
@ -15732,6 +15734,35 @@ Body:
|
||||
Area: 11
|
||||
- Level: 10
|
||||
Area: 13
|
||||
Duration1: 910
|
||||
FixedCastTime: -1
|
||||
Unit:
|
||||
Id: Earthquake
|
||||
Range:
|
||||
- Level: 1
|
||||
Size: 5
|
||||
- Level: 2
|
||||
Size: 7
|
||||
- Level: 3
|
||||
Size: 9
|
||||
- Level: 4
|
||||
Size: 11
|
||||
- Level: 5
|
||||
Size: 13
|
||||
- Level: 6
|
||||
Size: 5
|
||||
- Level: 7
|
||||
Size: 7
|
||||
- Level: 8
|
||||
Size: 9
|
||||
- Level: 9
|
||||
Size: 11
|
||||
- Level: 10
|
||||
Size: 13
|
||||
Interval: 300
|
||||
Target: Enemy
|
||||
Flag:
|
||||
PathCheck: true
|
||||
- Id: 654
|
||||
Name: NPC_FIREBREATH
|
||||
Description: Fire Breath
|
||||
|
@ -1283,7 +1283,7 @@ bool battle_status_block_damage(struct block_list *src, struct block_list *targe
|
||||
return false;
|
||||
}
|
||||
|
||||
if (sc->data[SC_DODGE] && (flag&BF_LONG || sc->data[SC_SPURT]) && rnd() % 100 < 20) {
|
||||
if (sc->data[SC_DODGE] && (flag&BF_LONG || sc->data[SC_SPURT]) && (skill_id != NPC_EARTHQUAKE || (skill_id == NPC_EARTHQUAKE && flag & NPC_EARTHQUAKE_FLAG)) && rnd() % 100 < 20) {
|
||||
map_session_data *sd = map_id2sd(target->id);
|
||||
|
||||
if (sd && pc_issit(sd))
|
||||
@ -1293,7 +1293,7 @@ bool battle_status_block_damage(struct block_list *src, struct block_list *targe
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((sce = sc->data[SC_KAUPE]) && rnd() % 100 < sce->val2) { //Kaupe blocks damage (skill or otherwise) from players, mobs, homuns, mercenaries.
|
||||
if ((sce = sc->data[SC_KAUPE]) && (skill_id != NPC_EARTHQUAKE || (skill_id == NPC_EARTHQUAKE && flag & NPC_EARTHQUAKE_FLAG)) && rnd() % 100 < sce->val2) { //Kaupe blocks damage (skill or otherwise) from players, mobs, homuns, mercenaries.
|
||||
clif_specialeffect(target, EF_STORMKICK4, AREA);
|
||||
//Shouldn't end until Breaker's non-weapon part connects.
|
||||
#ifndef RENEWAL
|
||||
@ -2782,6 +2782,7 @@ static bool is_attack_hitting(struct Damage* wd, struct block_list *src, struct
|
||||
case NPC_DARKNESSATTACK:
|
||||
case NPC_UNDEADATTACK:
|
||||
case NPC_TELEKINESISATTACK:
|
||||
case NPC_EARTHQUAKE:
|
||||
case NPC_BLEEDING:
|
||||
hitrate += hitrate * 20 / 100;
|
||||
break;
|
||||
@ -6103,6 +6104,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
s_ele = rnd()%ELE_ALL;
|
||||
|
||||
switch(skill_id) {
|
||||
case NPC_EARTHQUAKE:
|
||||
s_ele = ELE_NEUTRAL;
|
||||
break;
|
||||
case LG_SHIELDSPELL:
|
||||
if (skill_lv == 2)
|
||||
s_ele = ELE_HOLY;
|
||||
@ -6215,6 +6219,22 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
case AB_RENOVATIO:
|
||||
ad.damage = status_get_lv(src) * 10 + sstatus->int_;
|
||||
break;
|
||||
case NPC_EARTHQUAKE:
|
||||
if (mflag & NPC_EARTHQUAKE_FLAG) {
|
||||
ad.flag |= NPC_EARTHQUAKE_FLAG; // Pass flag to battle_calc_damage
|
||||
mflag &= ~NPC_EARTHQUAKE_FLAG; // Remove before NK_SPLASHSPLIT check
|
||||
}
|
||||
|
||||
if (src->type == BL_PC)
|
||||
ad.damage = sstatus->str * 2 + battle_calc_weapon_attack(src, target, skill_id, skill_lv, mflag).damage;
|
||||
else
|
||||
ad.damage = battle_calc_base_damage(src, sstatus, &sstatus->rhw, sc, tstatus->size, 0);
|
||||
|
||||
MATK_RATE(200 + 100 * skill_lv + 100 * (skill_lv / 2) + ((skill_lv > 4) ? 100 : 0));
|
||||
|
||||
if (nk[NK_SPLASHSPLIT] && mflag > 1)
|
||||
ad.damage /= mflag;
|
||||
break;
|
||||
case NPC_ICEMINE:
|
||||
case NPC_FLAMECROSS:
|
||||
ad.damage = sstatus->rhw.atk * 20 * skill_lv;
|
||||
@ -6381,9 +6401,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
case NPC_ENERGYDRAIN:
|
||||
skillratio += 100 * skill_lv;
|
||||
break;
|
||||
case NPC_EARTHQUAKE:
|
||||
skillratio += 100 + 100 * skill_lv + 100 * (skill_lv / 2) + ((skill_lv > 4) ? 100 : 0);
|
||||
break;
|
||||
#ifdef RENEWAL
|
||||
case WZ_HEAVENDRIVE:
|
||||
skillratio += 25;
|
||||
@ -6748,16 +6765,6 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
ad.damage = ad.damage * (100-mdef)/100 - mdef2;
|
||||
#endif
|
||||
}
|
||||
#if 0 // Doesn't seem to be official
|
||||
if (skill_id == NPC_EARTHQUAKE) {
|
||||
//Adds atk2 to the damage, should be influenced by number of hits and skill-ratio, but not mdef reductions. [Skotlex]
|
||||
//Also divide the extra bonuses from atk2 based on the number in range [Kevin]
|
||||
if(mflag>0)
|
||||
ad.damage+= (sstatus->rhw.atk2*skillratio/100)/mflag;
|
||||
else
|
||||
ShowError("Zero range by %d:%s, divide per 0 avoided!\n", skill_id, skill_get_name(skill_id));
|
||||
}
|
||||
#endif
|
||||
if(ad.damage<1)
|
||||
ad.damage=1;
|
||||
else if(sc) { //only applies when hit
|
||||
|
@ -7832,6 +7832,7 @@
|
||||
export_constant(UNT_GROUNDDRIFT_POISON);
|
||||
export_constant(UNT_GROUNDDRIFT_WATER);
|
||||
export_constant(UNT_GROUNDDRIFT_FIRE);
|
||||
export_constant(UNT_EARTHQUAKE);
|
||||
export_constant(UNT_EVILLAND);
|
||||
export_constant(UNT_EPICLESIS);
|
||||
export_constant(UNT_EARTHSTRAIN);
|
||||
|
@ -3579,6 +3579,9 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
||||
case LG_OVERBRAND_PLUSATK:
|
||||
dmg.dmotion = clif_skill_damage(dsrc,bl,tick,status_get_amotion(src),dmg.dmotion,damage,dmg.div_,skill_id,-1,DMG_SPLASH);
|
||||
break;
|
||||
case NPC_EARTHQUAKE:
|
||||
dmg.dmotion = clif_skill_damage(src, bl, tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -1, DMG_ENDURE);
|
||||
break;
|
||||
case NPC_DARKPIERCING:
|
||||
case EL_FIRE_BOMB:
|
||||
case EL_FIRE_BOMB_ATK:
|
||||
@ -4261,14 +4264,6 @@ static TIMER_FUNC(skill_timerskill){
|
||||
case BS_HAMMERFALL:
|
||||
sc_start(src, target, status_skill2sc(skl->skill_id), skl->type, skl->skill_lv, skill_get_time2(skl->skill_id, skl->skill_lv));
|
||||
break;
|
||||
case NPC_EARTHQUAKE:
|
||||
if( skl->type > 1 )
|
||||
skill_addtimerskill(src,tick+250,src->id,0,0,skl->skill_id,skl->skill_lv,skl->type-1,skl->flag);
|
||||
skill_area_temp[0] = map_foreachinallrange(skill_area_sub, src, skill_get_splash(skl->skill_id, skl->skill_lv), BL_CHAR, src, skl->skill_id, skl->skill_lv, tick, BCT_ENEMY, skill_area_sub_count);
|
||||
skill_area_temp[1] = src->id;
|
||||
skill_area_temp[2] = 0;
|
||||
map_foreachinallrange(skill_area_sub, src, skill_get_splash(skl->skill_id, skl->skill_lv), splash_target(src), src, skl->skill_id, skl->skill_lv, tick, skl->flag, skill_castend_damage_id);
|
||||
break;
|
||||
case WZ_WATERBALL:
|
||||
{
|
||||
//Get the next waterball cell to consume
|
||||
@ -5110,7 +5105,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
case NJ_HUUMA:
|
||||
case ASC_METEORASSAULT:
|
||||
case GS_SPREADATTACK:
|
||||
case NPC_EARTHQUAKE:
|
||||
case NPC_PULSESTRIKE:
|
||||
case NPC_HELLJUDGEMENT:
|
||||
case NPC_VAMPIRE_GIFT:
|
||||
@ -5225,9 +5219,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
||||
case MH_XENO_SLASHER:
|
||||
clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, DMG_SINGLE);
|
||||
break;
|
||||
case NPC_EARTHQUAKE: //FIXME: Isn't EarthQuake a ground skill after all?
|
||||
skill_addtimerskill(src,tick+250,src->id,0,0,skill_id,skill_lv,2,flag|BCT_ENEMY|SD_SPLASH|1);
|
||||
break;
|
||||
case NPC_REVERBERATION_ATK:
|
||||
case NC_ARMSCANNON:
|
||||
skill_area_temp[1] = 0;
|
||||
@ -7584,7 +7575,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
|
||||
case SR_EARTHSHAKER:
|
||||
case NC_INFRAREDSCAN:
|
||||
case NPC_EARTHQUAKE:
|
||||
case NPC_VAMPIRE_GIFT:
|
||||
case NPC_HELLJUDGEMENT:
|
||||
case NPC_PULSESTRIKE:
|
||||
@ -12445,6 +12435,10 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
||||
skill_unitsetting(src,skill_id,skill_lv,x,y,0);
|
||||
flag|=1;
|
||||
break;
|
||||
case NPC_EARTHQUAKE:
|
||||
clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, DMG_SINGLE);
|
||||
skill_unitsetting(src, skill_id, skill_lv, x, y, 0);
|
||||
break;
|
||||
#ifndef RENEWAL
|
||||
case HP_BASILICA:
|
||||
if( sc->data[SC_BASILICA] ) {
|
||||
@ -14445,6 +14439,11 @@ int skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t_t
|
||||
}
|
||||
break;
|
||||
|
||||
case UNT_EARTHQUAKE:
|
||||
sg->val1++; // Hit count
|
||||
skill_attack(skill_get_type(sg->skill_id), ss, &unit->bl, bl, sg->skill_id, sg->skill_lv, tick, map_foreachinallrange(skill_area_sub, &unit->bl, skill_get_splash(sg->skill_id, sg->skill_lv), BL_CHAR, &unit->bl, sg->skill_id, sg->skill_lv, tick, BCT_ENEMY, skill_area_sub_count) | (sg->val1 == 1 ? NPC_EARTHQUAKE_FLAG : 0));
|
||||
break;
|
||||
|
||||
case UNT_ELECTRICSHOCKER:
|
||||
if( bl->id != ss->id ) {
|
||||
if( status_change_start(ss, bl,type,10000,sg->skill_lv,sg->group_id,0,0,skill_get_time2(sg->skill_id, sg->skill_lv), SCSTART_NORATEDEF) ) {
|
||||
|
@ -37,6 +37,9 @@ struct status_change_entry;
|
||||
#define SKILL_NAME_LENGTH 31 /// Max Skill Name length
|
||||
#define SKILL_DESC_LENGTH 31 /// Max Skill Desc length
|
||||
|
||||
/// Used with tracking the hitcount of Earthquake for skills that can avoid the first attack
|
||||
#define NPC_EARTHQUAKE_FLAG 0x800
|
||||
|
||||
/// Constants to identify a skill's nk value (damage properties)
|
||||
/// The NK value applies only to non INF_GROUND_SKILL skills
|
||||
/// when determining skill castend function to invoke.
|
||||
@ -2167,7 +2170,7 @@ enum e_skill_unit_id : uint16 {
|
||||
UNT_DEATHWAVE, //TODO
|
||||
UNT_WATERATTACK, //TODO
|
||||
UNT_WINDATTACK, //TODO
|
||||
UNT_EARTHQUAKE, //TODO
|
||||
UNT_EARTHQUAKE,
|
||||
UNT_EVILLAND,
|
||||
UNT_DARK_RUNNER, //TODO
|
||||
UNT_DARK_TRANSFER, //TODO
|
||||
|
Loading…
x
Reference in New Issue
Block a user