diff options
author | Jesusaves <cpntb1@ymail.com> | 2020-06-15 22:04:30 -0300 |
---|---|---|
committer | Jesusaves <cpntb1@ymail.com> | 2020-06-15 22:04:30 -0300 |
commit | 8eb5d96c3394c619797a44f244dc5a0644ddf40c (patch) | |
tree | ef326c86a1d5f79d1cf91dfdb8d8afc52f1895c2 | |
parent | 85c88e6ce91086d5c061df3b66d423a5ddcdfb9b (diff) | |
download | evol-hercules-8eb5d96c3394c619797a44f244dc5a0644ddf40c.tar.gz evol-hercules-8eb5d96c3394c619797a44f244dc5a0644ddf40c.tar.bz2 evol-hercules-8eb5d96c3394c619797a44f244dc5a0644ddf40c.tar.xz evol-hercules-8eb5d96c3394c619797a44f244dc5a0644ddf40c.zip |
Magic Attacks may now crit.
Perfect Dodge / Blocking will now work versus magic as well.
Infinite Defense rules respected.
-rw-r--r-- | src/emap/battle.c | 113 | ||||
-rw-r--r-- | src/emap/battle.h | 6 | ||||
-rw-r--r-- | src/emap/init.c | 2 |
3 files changed, 120 insertions, 1 deletions
diff --git a/src/emap/battle.c b/src/emap/battle.c index 7ef8c83..abc38a5 100644 --- a/src/emap/battle.c +++ b/src/emap/battle.c @@ -10,6 +10,7 @@ #include "common/HPMi.h" #include "common/nullpo.h" #include "common/utils.h" +#include "common/random.h" #include "map/itemdb.h" #include "map/mob.h" @@ -87,6 +88,8 @@ bool ebattle_check_arrows_post(bool retVal, return false; } + + struct Damage ebattle_calc_weapon_attack_post(struct Damage retVal, struct block_list *src, struct block_list *target, @@ -151,6 +154,116 @@ struct Damage ebattle_calc_weapon_attack_post(struct Damage retVal, return retVal; } + + +struct Damage ebattle_calc_magic_attack_post(struct Damage retVal, + struct block_list *src, + struct block_list *target, + uint16 skill_id, + uint16 skill_lv __attribute__ ((unused)), + int mflag __attribute__ ((unused))) +{ + // Rebuild SD and SC data + struct map_session_data *sd, *tsd; + struct status_change *sc = status->get_sc(src); + struct status_change *tsc = status->get_sc(target); + struct status_data *sstatus = status->get_status_data(src); + struct status_data *tstatus = status->get_status_data(target); + + sd = BL_CAST(BL_PC, src); + tsd = BL_CAST(BL_PC, target); + + //Skip checking as there are no status changes active. + if (sc && !sc->count) + sc = NULL; + if (tsc && !tsc->count) + tsc = NULL; + + // Magic attacks can be blocked by shields. + // This terminates everything + if (tstatus->flee2 && rnd()%1000 < tstatus->flee2) { + retVal.type = BDT_PDODGE; + retVal.dmg_lv=ATK_LUCKY; + if (retVal.div_ < 0) retVal.div_*=-1; + retVal.damage=0; + retVal.damage2=0; + return retVal; + } + + // Rebuild Infinite Defense Rule + int infdef = 0; + infdef = (tstatus->mode&MD_PLANT) ? 1 : 0; + if (!infdef && target->type == BL_SKILL) { + const struct skill_unit *su = BL_UCCAST(BL_SKILL, target); + if (su->group->unit_id == UNT_REVERBERATION) + infdef = 1; // Reverberation takes 1 damage + } + + // Not infinite defense, extra calculations + if (!infdef) { + // Allow magic attacks to crit + if ( sstatus->cri ) { + int cri = sstatus->cri; + + // Race critical bonuses + cri+= sd->critaddrace[tstatus->race]; + + // Critical Defense + cri -= status->get_lv(target) / 5 + (3 * status_get_luk(target))/2; + + // Magic deals in average, 3x less criticals + cri = cri / 3; + + // Sleeping target? + if( tsc && tsc->data[SC_SLEEP] ) + cri <<= 1; + + // Official critical defense calculation + if(tsd && tsd->bonus.critical_def) + cri = cri * ( 100 - tsd->bonus.critical_def ) / 100; + + // And finally, check if a crit! + if (rnd()%1000 < cri) { + // Damage +40% (official behavior) and CRITDMG bonus + // Magic Crits are 50% weaker, because they rarely miss + retVal.damage=apply_percentrate64(retVal.damage, (40+sd->bonus.crit_atk_rate)/2+100, 100); + retVal.damage2=apply_percentrate64(retVal.damage2, (40+sd->bonus.crit_atk_rate)/2+100, 100); + retVal.type = BDT_CRIT; + } + } + + // Err, enough maths for today + } + // Apply 4144 code if relevant + if (src == NULL || sd == NULL) + return retVal; + + struct mob_data *md = BL_CAST(BL_MOB, target); + if (md == NULL) + return retVal; + + struct MobdExt *data = mobd_get_by_mob(md); + if (data == NULL) + return retVal; + + int mod = 0; + if (skill_id > 0) + { + const int idx = skill->get_index(skill_id); + mod = data->skillAttacks[idx]; + } + else + { + mod = data->weaponAttacks[sd->weapontype1]; + } + retVal.damage = apply_percentrate64(retVal.damage, mod, 10000); + retVal.damage2 = apply_percentrate64(retVal.damage2, mod, 10000); + + return retVal; +} + + + enum damage_lv ebattle_weapon_attack_pre(struct block_list **srcPtr, struct block_list **targetPtr, int64 *tickPtr __attribute__ ((unused)), diff --git a/src/emap/battle.h b/src/emap/battle.h index 17d7ba7..e7c14ea 100644 --- a/src/emap/battle.h +++ b/src/emap/battle.h @@ -12,6 +12,12 @@ struct Damage ebattle_calc_weapon_attack_post(struct Damage retVal, uint16 skill_id, uint16 skill_lv, int wflag); +struct Damage ebattle_calc_magic_attack_post(struct Damage retVal, + struct block_list *src, + struct block_list *target, + uint16 skill_id, + uint16 skill_lv, + int mflag); enum damage_lv ebattle_weapon_attack_pre(struct block_list **srcPtr, struct block_list **targetPtr, int64 *tickPtr, diff --git a/src/emap/init.c b/src/emap/init.c index 8cfa95d..bd42f4a 100644 --- a/src/emap/init.c +++ b/src/emap/init.c @@ -383,7 +383,7 @@ HPExport void plugin_init (void) //addHookPost(skill, castend_type, eskill_castend_type_post); addHookPost(battle, calc_weapon_attack, ebattle_calc_weapon_attack_post); - addHookPost(battle, calc_magic_attack, ebattle_calc_weapon_attack_post); + addHookPost(battle, calc_magic_attack, ebattle_calc_magic_attack_post); addHookPost(battle, calc_misc_attack, ebattle_calc_weapon_attack_post); addHookPost(battle, check_arrows, ebattle_check_arrows_post); addHookPost(clan, join, eclan_join_post); |