From a3158d2110a2a846d39a5ddc364adb40c212241d Mon Sep 17 00:00:00 2001 From: Andrei Karas Date: Wed, 31 Aug 2016 23:50:14 +0300 Subject: Add into mob_db weapot type attacks modifier. New group in mob_db: WeaponAttacks Example: WeaponAttacks: { Bows: 5000 // mean bow attack do 50% of normal attack } Default value is 10000 mean 100% --- src/emap/battle.c | 59 ++++++++++++++++++ src/emap/battle.h | 6 ++ src/emap/data/mobd.c | 2 + src/emap/init.c | 1 + src/emap/mob.c | 152 ++++++++++++++++++++++++++++++++++++++++++++++ src/emap/struct/mobdext.h | 1 + 6 files changed, 221 insertions(+) (limited to 'src') diff --git a/src/emap/battle.c b/src/emap/battle.c index 5b16244..161da3d 100644 --- a/src/emap/battle.c +++ b/src/emap/battle.c @@ -8,12 +8,42 @@ #include #include "common/HPMi.h" +#include "common/nullpo.h" +#include "common/utils.h" #include "map/itemdb.h" +#include "map/mob.h" #include "map/pc.h" #include "emap/data/itemd.h" +#include "emap/data/mobd.h" #include "emap/struct/itemdext.h" +#include "emap/struct/mobdext.h" + +// copy from common/utils.c +/** + * Applies a percentual rate modifier. + * + * @param value The base value. + * @param rate The rate modifier to apply. + * @param stdrate The rate modifier's divider (rate == stdrate => 100%). + * @return The modified value. + */ +int64 apply_percentrate64(int64 value, int rate, int stdrate) +{ + Assert_ret(stdrate > 0); + Assert_ret(rate >= 0); + if (rate == stdrate) + return value; + if (rate == 0) + return 0; + if (INT64_MAX / rate < value) + { + // Give up some precision to prevent overflows + return value / stdrate * rate; + } + return value * rate / stdrate; +} bool ebattle_check_arrows_post(bool retVal, struct map_session_data *sd) @@ -52,3 +82,32 @@ 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 __attribute__ ((unused)), + uint16 skill_id __attribute__ ((unused)), + uint16 skill_lv __attribute__ ((unused)), + int wflag __attribute__ ((unused))) +{ + if (src == NULL) + return retVal; + + struct map_session_data *sd = BL_CAST(BL_PC, src); + if (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; + + const int mod = data->weaponAttacks[sd->weapontype1]; + retVal.damage = apply_percentrate64(retVal.damage, mod, 10000); + retVal.damage2 = apply_percentrate64(retVal.damage2, mod, 10000); + + return retVal; +} diff --git a/src/emap/battle.h b/src/emap/battle.h index 7ab2db2..38ce379 100644 --- a/src/emap/battle.h +++ b/src/emap/battle.h @@ -6,5 +6,11 @@ bool ebattle_check_arrows_post(bool retVal, struct map_session_data *sd); +struct Damage ebattle_calc_weapon_attack_post(struct Damage retVal, + struct block_list *src, + struct block_list *target, + uint16 skill_id, + uint16 skill_lv, + int wflag); #endif // EVOL_MAP_BATTLE diff --git a/src/emap/data/mobd.c b/src/emap/data/mobd.c index e3a6c34..abddb3d 100644 --- a/src/emap/data/mobd.c +++ b/src/emap/data/mobd.c @@ -47,5 +47,7 @@ struct MobdExt *mobd_create(void) if (!data) return NULL; data->walkMask = 0; + for (int f = 0; f < MAX_WEAPON_TYPE; f ++) + data->weaponAttacks[f] = 10000; return data; } diff --git a/src/emap/init.c b/src/emap/init.c index 93d027c..179fe59 100644 --- a/src/emap/init.c +++ b/src/emap/init.c @@ -269,6 +269,7 @@ HPExport void plugin_init (void) addHookPre(status, set_viewdata, estatus_set_viewdata_pre); addHookPre(homun, gainexp, ehomunculus_gainexp_pre); + addHookPost(battle, calc_weapon_attack, ebattle_calc_weapon_attack_post); addHookPost(battle, check_arrows, ebattle_check_arrows_post); addHookPost(clif, addcards, eclif_addcards_post); addHookPost(clif, addcards2, eclif_addcards2_post); diff --git a/src/emap/mob.c b/src/emap/mob.c index 0bddb02..534e858 100644 --- a/src/emap/mob.c +++ b/src/emap/mob.c @@ -7,6 +7,7 @@ #include #include +#include "common/cbasetypes.h" #include "common/conf.h" #include "common/HPMi.h" #include "common/memmgr.h" @@ -59,6 +60,145 @@ int emob_deleteslave_sub_pre(struct block_list **blPtr, return 0; } +static void emob_load_weaponattacks(const char *type, + int val, + struct MobdExt *data, + struct mob_db *entry) +{ + int key = -1; + if (strcmp(type, "NoWeapon") == 0) + { + key = W_FIST; + } + else if (strcmp(type, "Daggers") == 0) + { + key = W_DAGGER; + } + else if (strcmp(type, "1HSwords") == 0) + { + key = W_1HSWORD; + } + else if (strcmp(type, "2HSwords") == 0) + { + key = W_2HSWORD; + } + else if (strcmp(type, "1HSpears") == 0) + { + key = W_1HSPEAR; + } + else if (strcmp(type, "2HSpears") == 0) + { + key = W_2HSPEAR; + } + else if (strcmp(type, "1HAxes") == 0) + { + key = W_1HAXE; + } + else if (strcmp(type, "2HAxes") == 0) + { + key = W_2HAXE; + } + else if (strcmp(type, "Maces") == 0) + { + key = W_MACE; + } + else if (strcmp(type, "2HMaces") == 0) + { + key = W_2HMACE; + } + else if (strcmp(type, "Staves") == 0) + { + key = W_STAFF; + } + else if (strcmp(type, "Bows") == 0) + { + key = W_BOW; + } + else if (strcmp(type, "Knuckles") == 0) + { + key = W_KNUCKLE; + } + else if (strcmp(type, "Instruments") == 0) + { + key = W_MUSICAL; + } + else if (strcmp(type, "Whips") == 0) + { + key = W_WHIP; + } + else if (strcmp(type, "Books") == 0) + { + key = W_BOOK; + } + else if (strcmp(type, "Katars") == 0) + { + key = W_KATAR; + } + else if (strcmp(type, "Revolvers") == 0) + { + key = W_REVOLVER; + } + else if (strcmp(type, "Rifles") == 0) + { + key = W_RIFLE; + } + else if (strcmp(type, "GatlingGuns") == 0) + { + key = W_GATLING; + } + else if (strcmp(type, "Shotguns") == 0) + { + key = W_SHOTGUN; + } + else if (strcmp(type, "GrenadeLaunchers") == 0) + { + key = W_GRENADE; + } + else if (strcmp(type, "FuumaShurikens") == 0) + { + key = W_HUUMA; + } + else if (strcmp(type, "2HStaves") == 0) + { + key = W_2HSTAFF; + } + else if (strcmp(type, "DWDaggers") == 0) + { + key = W_DOUBLE_DD; + } + else if (strcmp(type, "DWSwords") == 0) + { + key = W_DOUBLE_SS; + } + else if (strcmp(type, "DWAxes") == 0) + { + key = W_DOUBLE_AA; + } + else if (strcmp(type, "DWDaggerSword") == 0) + { + key = W_DOUBLE_DS; + } + else if (strcmp(type, "DWDaggerAxe") == 0) + { + key = W_DOUBLE_DA; + } + else if (strcmp(type, "DWSwordAxe") == 0) + { + key = W_DOUBLE_SA; + } + else if (strcmp(type, "All") == 0) + { + for (int f = 0; f < MAX_WEAPON_TYPE; f ++) + data->weaponAttacks[f] = val; + } + else + { + ShowError("Mob %d. Unknown weapon type %s\n", entry->mob_id, type); + return; + } + data->weaponAttacks[key] = val; +} + void emob_read_db_additional_fields_pre(struct mob_db **entryPtr, struct config_setting_t **itPtr, int *nPtr __attribute__ ((unused)), @@ -75,6 +215,18 @@ void emob_read_db_additional_fields_pre(struct mob_db **entryPtr, if (mob->lookup_const(*itPtr, "WalkMask", &i32)) data->walkMask = i32; + + struct config_setting_t *tt = libconfig->setting_get_member(*itPtr, "WeaponAttacks"); + + if (tt && config_setting_is_group(tt)) + { + int j = 0; + struct config_setting_t *wpt = NULL; + while ((wpt = libconfig->setting_get_elem(tt, j++)) != NULL) + { + emob_load_weaponattacks(config_setting_name(wpt), libconfig->setting_get_int(wpt), data, *entryPtr); + } + } } uint32 emob_read_db_mode_sub_post(uint32 retVal, diff --git a/src/emap/struct/mobdext.h b/src/emap/struct/mobdext.h index ed49e6c..879ca99 100644 --- a/src/emap/struct/mobdext.h +++ b/src/emap/struct/mobdext.h @@ -7,6 +7,7 @@ struct MobdExt { int walkMask; + int weaponAttacks[MAX_WEAPON_TYPE]; }; #endif // EVOL_MAP_MOBDEXT -- cgit v1.2.3-70-g09d2