summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenpachi Developer <Kenpachi.Developer@gmx.de>2020-05-17 02:09:06 +0200
committerKenpachi Developer <Kenpachi.Developer@gmx.de>2020-06-01 02:01:55 +0200
commit529401c53e79ed848cea6dfaab75366d05174a43 (patch)
treeb0e8cd2f1f07ddf1f39494b79a15b0204927bba3
parenta30f969b07c2d4e0f7e3189c5566fb50738babde (diff)
downloadhercules-529401c53e79ed848cea6dfaab75366d05174a43.tar.gz
hercules-529401c53e79ed848cea6dfaab75366d05174a43.tar.bz2
hercules-529401c53e79ed848cea6dfaab75366d05174a43.tar.xz
hercules-529401c53e79ed848cea6dfaab75366d05174a43.zip
Make Requirements->State can be grouped by levels
-rw-r--r--src/map/skill.c168
-rw-r--r--src/map/skill.h9
-rw-r--r--src/map/unit.c4
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc12
5 files changed, 130 insertions, 67 deletions
diff --git a/src/map/skill.c b/src/map/skill.c
index e987e4c8f..306237565 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -332,14 +332,26 @@ static int skill_get_sp_rate(int skill_id, int skill_lv)
return skill->dbs->db[idx].sp_rate[skill_get_lvl_idx(skill_lv)];
}
-static int skill_get_state(int skill_id)
+/**
+ * Gets a skill's required state by its ID and level.
+ *
+ * @param skill_id The skill's ID.
+ * @param skill_lv The skill's level.
+ * @return The skill's required state corresponding to the passed level. Defaults to ST_NONE (0) in case of error.
+ *
+ **/
+static int skill_get_state(int skill_id, int skill_lv)
{
- int idx;
if (skill_id == 0)
return ST_NONE;
- idx = skill->get_index(skill_id);
+
+ Assert_retr(ST_NONE, skill_lv > 0);
+
+ int idx = skill->get_index(skill_id);
+
Assert_retr(ST_NONE, idx != 0);
- return skill->dbs->db[idx].state;
+
+ return skill->dbs->db[idx].state[skill_get_lvl_idx(skill_lv)];
}
static int skill_get_spiritball(int skill_id, int skill_lv)
@@ -3847,7 +3859,7 @@ static int skill_check_condition_mercenary(struct block_list *bl, int skill_id,
sp = skill->dbs->db[idx].sp[lv-1];
hp_rate = skill->dbs->db[idx].hp_rate[lv-1];
sp_rate = skill->dbs->db[idx].sp_rate[lv-1];
- state = skill->dbs->db[idx].state;
+ state = skill->dbs->db[idx].state[lv - 1];
if( (mhp = skill->dbs->db[idx].mhp[lv-1]) > 0 )
hp += (st->max_hp * mhp) / 100;
if( hp_rate > 0 )
@@ -5926,7 +5938,7 @@ static int skill_castend_id(int tid, int64 tick, int id, intptr_t data)
break;
}
}
- if (skill->get_state(ud->skill_id) != ST_MOVE_ENABLE)
+ if (skill->get_state(ud->skill_id, ud->skill_lv) != ST_MOVE_ENABLE)
unit->set_walkdelay(src, tick, battle_config.default_walk_delay+skill->get_walkdelay(ud->skill_id, ud->skill_lv), 1);
if(battle_config.skill_log && battle_config.skill_log&src->type)
@@ -15538,7 +15550,7 @@ static struct skill_condition skill_get_requirement(struct map_session_data *sd,
req.spiritball = skill->dbs->db[idx].spiritball[skill_lv-1];
- req.state = skill->dbs->db[idx].state;
+ req.state = skill->dbs->db[idx].state[skill_lv - 1];
req.mhp = skill->dbs->db[idx].mhp[skill_lv-1];
@@ -22121,6 +22133,71 @@ static void skill_validate_ammo_amount(struct config_setting_t *conf, struct s_s
}
/**
+ * Validates a single required state when reading the skill DB.
+ *
+ * @param state The required state to validate.
+ * @return A number greater than or equal to 0 if the passed required state is valid, otherwise -1.
+ *
+ **/
+static int skill_validate_state_sub(const char *state)
+{
+ nullpo_retr(-1, state);
+
+ int ret_val = ST_NONE;
+
+ if (strcmpi(state, "Hiding") == 0)
+ ret_val = ST_HIDING;
+ else if (strcmpi(state, "Cloaking") == 0)
+ ret_val = ST_CLOAKING;
+ else if (strcmpi(state, "Hidden") == 0)
+ ret_val = ST_HIDDEN;
+ else if (strcmpi(state, "Riding") == 0)
+ ret_val = ST_RIDING;
+ else if (strcmpi(state, "Falcon") == 0)
+ ret_val = ST_FALCON;
+ else if (strcmpi(state, "Cart") == 0)
+ ret_val = ST_CART;
+ else if (strcmpi(state, "Shield") == 0)
+ ret_val = ST_SHIELD;
+ else if (strcmpi(state, "Sight") == 0)
+ ret_val = ST_SIGHT;
+ else if (strcmpi(state, "ExplosionSpirits") == 0)
+ ret_val = ST_EXPLOSIONSPIRITS;
+ else if (strcmpi(state, "CartBoost") == 0)
+ ret_val = ST_CARTBOOST;
+ else if (strcmpi(state, "NotOverWeight") == 0)
+ ret_val = ST_RECOV_WEIGHT_RATE;
+ else if (strcmpi(state, "Moveable") == 0)
+ ret_val = ST_MOVE_ENABLE;
+ else if (strcmpi(state, "InWater") == 0)
+ ret_val = ST_WATER;
+ else if (strcmpi(state, "Dragon") == 0)
+ ret_val = ST_RIDINGDRAGON;
+ else if (strcmpi(state, "Warg") == 0)
+ ret_val = ST_WUG;
+ else if (strcmpi(state, "RidingWarg") == 0)
+ ret_val = ST_RIDINGWUG;
+ else if (strcmpi(state, "MadoGear") == 0)
+ ret_val = ST_MADO;
+ else if (strcmpi(state, "ElementalSpirit") == 0)
+ ret_val = ST_ELEMENTALSPIRIT;
+ else if (strcmpi(state, "PoisonWeapon") == 0)
+ ret_val = ST_POISONINGWEAPON;
+ else if (strcmpi(state, "RollingCutter") == 0)
+ ret_val = ST_ROLLINGCUTTER;
+ else if (strcmpi(state, "MH_Fighting") == 0)
+ ret_val = ST_MH_FIGHTING;
+ else if (strcmpi(state, "MH_Grappling") == 0)
+ ret_val = ST_MH_GRAPPLING;
+ else if (strcmpi(state, "Peco") == 0)
+ ret_val = ST_PECO;
+ else if (strcmpi(state, "None") != 0)
+ ret_val = -1;
+
+ return ret_val;
+}
+
+/**
* Validates a skill's required states when reading the skill DB.
*
* @param conf The libconfig settings block which contains the skill's data.
@@ -22132,58 +22209,38 @@ static void skill_validate_state(struct config_setting_t *conf, struct s_skill_d
nullpo_retv(conf);
nullpo_retv(sk);
- sk->state = ST_NONE;
+ skill->level_set_value(sk->state, ST_NONE);
+
+ struct config_setting_t *t = libconfig->setting_get_member(conf, "State");
+
+ if (t != NULL && config_setting_is_group(t)) {
+ for (int i = 0; i < MAX_SKILL_LEVEL; i++) {
+ char lv[6]; // Big enough to contain "Lv999" in case of custom MAX_SKILL_LEVEL.
+ safesnprintf(lv, sizeof(lv), "Lv%d", i + 1);
+ const char *state;
+
+ if (libconfig->setting_lookup_string(t, lv, &state) == CONFIG_TRUE) {
+ int sta = skill->validate_state_sub(state);
+
+ if (sta > ST_NONE)
+ sk->state[i] = sta;
+ else if (sta == -1)
+ ShowWarning("%s: Invalid required state %s specified in level %d for skill ID %d in %s! Defaulting to None...\n",
+ __func__, state, i + 1, sk->nameid, conf->file);
+ }
+ }
+
+ return;
+ }
const char *state;
if (libconfig->setting_lookup_string(conf, "State", &state) == CONFIG_TRUE) {
- if (strcmpi(state, "Hiding") == 0)
- sk->state = ST_HIDING;
- else if (strcmpi(state, "Cloaking") == 0)
- sk->state = ST_CLOAKING;
- else if (strcmpi(state, "Hidden") == 0)
- sk->state = ST_HIDDEN;
- else if (strcmpi(state, "Riding") == 0)
- sk->state = ST_RIDING;
- else if (strcmpi(state, "Falcon") == 0)
- sk->state = ST_FALCON;
- else if (strcmpi(state, "Cart") == 0)
- sk->state = ST_CART;
- else if (strcmpi(state, "Shield") == 0)
- sk->state = ST_SHIELD;
- else if (strcmpi(state, "Sight") == 0)
- sk->state = ST_SIGHT;
- else if (strcmpi(state, "ExplosionSpirits") == 0)
- sk->state = ST_EXPLOSIONSPIRITS;
- else if (strcmpi(state, "CartBoost") == 0)
- sk->state = ST_CARTBOOST;
- else if (strcmpi(state, "NotOverWeight") == 0)
- sk->state = ST_RECOV_WEIGHT_RATE;
- else if (strcmpi(state, "Moveable") == 0)
- sk->state = ST_MOVE_ENABLE;
- else if (strcmpi(state, "InWater") == 0)
- sk->state = ST_WATER;
- else if (strcmpi(state, "Dragon") == 0)
- sk->state = ST_RIDINGDRAGON;
- else if (strcmpi(state, "Warg") == 0)
- sk->state = ST_WUG;
- else if (strcmpi(state, "RidingWarg") == 0)
- sk->state = ST_RIDINGWUG;
- else if (strcmpi(state, "MadoGear") == 0)
- sk->state = ST_MADO;
- else if (strcmpi(state, "ElementalSpirit") == 0)
- sk->state = ST_ELEMENTALSPIRIT;
- else if (strcmpi(state, "PoisonWeapon") == 0)
- sk->state = ST_POISONINGWEAPON;
- else if (strcmpi(state, "RollingCutter") == 0)
- sk->state = ST_ROLLINGCUTTER;
- else if (strcmpi(state, "MH_Fighting") == 0)
- sk->state = ST_MH_FIGHTING;
- else if (strcmpi(state, "MH_Grappling") == 0)
- sk->state = ST_MH_GRAPPLING;
- else if (strcmpi(state, "Peco") == 0)
- sk->state = ST_PECO;
- else if (strcmpi(state, "None") != 0)
+ int sta = skill->validate_state_sub(state);
+
+ if (sta > ST_NONE)
+ skill->level_set_value(sk->state, sta);
+ else if (sta == -1)
ShowWarning("%s: Invalid required state %s specified for skill ID %d in %s! Defaulting to None...\n",
__func__, state, sk->nameid, conf->file);
}
@@ -23197,6 +23254,7 @@ void skill_defaults(void)
skill->validate_ammotype_sub = skill_validate_ammotype_sub;
skill->validate_ammotype = skill_validate_ammotype;
skill->validate_ammo_amount = skill_validate_ammo_amount;
+ skill->validate_state_sub = skill_validate_state_sub;
skill->validate_state = skill_validate_state;
skill->validate_spirit_sphere_cost = skill_validate_spirit_sphere_cost;
skill->validate_item_requirements = skill_validate_item_requirements;
diff --git a/src/map/skill.h b/src/map/skill.h
index a185535a1..daa03d24e 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -1771,7 +1771,11 @@ struct s_skill_db {
int skill_type[MAX_SKILL_LEVEL];
int blewcount[MAX_SKILL_LEVEL];
int hp[MAX_SKILL_LEVEL],sp[MAX_SKILL_LEVEL],mhp[MAX_SKILL_LEVEL],hp_rate[MAX_SKILL_LEVEL],sp_rate[MAX_SKILL_LEVEL],zeny[MAX_SKILL_LEVEL];
- int weapon,ammo,ammo_qty[MAX_SKILL_LEVEL],state,spiritball[MAX_SKILL_LEVEL];
+ int weapon;
+ int ammo;
+ int ammo_qty[MAX_SKILL_LEVEL];
+ int state[MAX_SKILL_LEVEL];
+ int spiritball[MAX_SKILL_LEVEL];
int itemid[MAX_SKILL_ITEM_REQUIRE],amount[MAX_SKILL_ITEM_REQUIRE];
int castnodex[MAX_SKILL_LEVEL], delaynodex[MAX_SKILL_LEVEL];
int unit_id[2];
@@ -1979,7 +1983,7 @@ struct skill_interface {
int (*get_sp) (int skill_id, int skill_lv);
int (*get_hp_rate) (int skill_id, int skill_lv);
int (*get_sp_rate) (int skill_id, int skill_lv);
- int (*get_state) (int skill_id);
+ int (*get_state) (int skill_id, int skill_lv);
int (*get_spiritball) (int skill_id, int skill_lv);
int (*get_itemid) (int skill_id, int item_idx);
int (*get_itemqty) (int skill_id, int item_idx);
@@ -2164,6 +2168,7 @@ struct skill_interface {
int (*validate_ammotype_sub) (const char *type, bool on, struct s_skill_db *sk);
void (*validate_ammotype) (struct config_setting_t *conf, struct s_skill_db *sk);
void (*validate_ammo_amount) (struct config_setting_t *conf, struct s_skill_db *sk);
+ int (*validate_state_sub) (const char *state);
void (*validate_state) (struct config_setting_t *conf, struct s_skill_db *sk);
void (*validate_spirit_sphere_cost) (struct config_setting_t *conf, struct s_skill_db *sk);
void (*validate_item_requirements) (struct config_setting_t *conf, struct s_skill_db *sk);
diff --git a/src/map/unit.c b/src/map/unit.c
index 223a4a82b..a6afb5ee7 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -1567,7 +1567,7 @@ static int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill
//Check range when not using skill on yourself or is a combo-skill during attack
//(these are supposed to always have the same range as your attack)
if( src->id != target_id && (!temp || ud->attacktimer == INVALID_TIMER) ) {
- if( skill->get_state(ud->skill_id) == ST_MOVE_ENABLE ) {
+ if (skill->get_state(ud->skill_id, ud->skill_lv) == ST_MOVE_ENABLE) {
if( !unit->can_reach_bl(src, target, range + 1, 1, NULL, NULL) )
return 0; // Walk-path check failed.
} else if( src->type == BL_MER && skill_id == MA_REMOVETRAP ) {
@@ -1872,7 +1872,7 @@ static int unit_skilluse_pos2(struct block_list *src, short skill_x, short skill
return 0; // Attacking will be handled by unit_walk_toxy_timer in this case
}
- if( skill->get_state(ud->skill_id) == ST_MOVE_ENABLE ) {
+ if (skill->get_state(ud->skill_id, ud->skill_lv) == ST_MOVE_ENABLE) {
if( !unit->can_reach_bl(src, &bl, range + 1, 1, NULL, NULL) )
return 0; //Walk-path check failed.
} else if( !battle->check_range(src, &bl, range) )
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 5ce0ba4e6..8a4aa7712 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -7258,8 +7258,8 @@ typedef int (*HPMHOOK_pre_skill_get_hp_rate) (int *skill_id, int *skill_lv);
typedef int (*HPMHOOK_post_skill_get_hp_rate) (int retVal___, int skill_id, int skill_lv);
typedef int (*HPMHOOK_pre_skill_get_sp_rate) (int *skill_id, int *skill_lv);
typedef int (*HPMHOOK_post_skill_get_sp_rate) (int retVal___, int skill_id, int skill_lv);
-typedef int (*HPMHOOK_pre_skill_get_state) (int *skill_id);
-typedef int (*HPMHOOK_post_skill_get_state) (int retVal___, int skill_id);
+typedef int (*HPMHOOK_pre_skill_get_state) (int *skill_id, int *skill_lv);
+typedef int (*HPMHOOK_post_skill_get_state) (int retVal___, int skill_id, int skill_lv);
typedef int (*HPMHOOK_pre_skill_get_spiritball) (int *skill_id, int *skill_lv);
typedef int (*HPMHOOK_post_skill_get_spiritball) (int retVal___, int skill_id, int skill_lv);
typedef int (*HPMHOOK_pre_skill_get_itemid) (int *skill_id, int *item_idx);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 357ba2421..46682e33c 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -77147,15 +77147,15 @@ int HP_skill_get_sp_rate(int skill_id, int skill_lv) {
}
return retVal___;
}
-int HP_skill_get_state(int skill_id) {
+int HP_skill_get_state(int skill_id, int skill_lv) {
int hIndex = 0;
int retVal___ = 0;
if (HPMHooks.count.HP_skill_get_state_pre > 0) {
- int (*preHookFunc) (int *skill_id);
+ int (*preHookFunc) (int *skill_id, int *skill_lv);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_state_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_skill_get_state_pre[hIndex].func;
- retVal___ = preHookFunc(&skill_id);
+ retVal___ = preHookFunc(&skill_id, &skill_lv);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -77163,13 +77163,13 @@ int HP_skill_get_state(int skill_id) {
}
}
{
- retVal___ = HPMHooks.source.skill.get_state(skill_id);
+ retVal___ = HPMHooks.source.skill.get_state(skill_id, skill_lv);
}
if (HPMHooks.count.HP_skill_get_state_post > 0) {
- int (*postHookFunc) (int retVal___, int skill_id);
+ int (*postHookFunc) (int retVal___, int skill_id, int skill_lv);
for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_state_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_skill_get_state_post[hIndex].func;
- retVal___ = postHookFunc(retVal___, skill_id);
+ retVal___ = postHookFunc(retVal___, skill_id, skill_lv);
}
}
return retVal___;