summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/emap/battle.c59
-rw-r--r--src/emap/battle.h6
-rw-r--r--src/emap/data/mobd.c2
-rw-r--r--src/emap/init.c1
-rw-r--r--src/emap/mob.c152
-rw-r--r--src/emap/struct/mobdext.h1
6 files changed, 221 insertions, 0 deletions
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 <string.h>
#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 <stdlib.h>
#include <string.h>
+#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