summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJesusaves <cpntb1@ymail.com>2020-06-15 22:04:30 -0300
committerJesusaves <cpntb1@ymail.com>2020-06-15 22:04:30 -0300
commit8eb5d96c3394c619797a44f244dc5a0644ddf40c (patch)
treeef326c86a1d5f79d1cf91dfdb8d8afc52f1895c2
parent85c88e6ce91086d5c061df3b66d423a5ddcdfb9b (diff)
downloadevol-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.c113
-rw-r--r--src/emap/battle.h6
-rw-r--r--src/emap/init.c2
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);