Skip to content

Commit

Permalink
refactor SA_AUTOSPELL spell selection
Browse files Browse the repository at this point in the history
- split spell selection logic into smaller functions
- move spell list building to skill.c instead of clif
- use config file for autospell list
  • Loading branch information
guilherme-gm committed Oct 17, 2023
1 parent 142fba5 commit 225593f
Show file tree
Hide file tree
Showing 8 changed files with 178 additions and 74 deletions.
51 changes: 24 additions & 27 deletions src/map/clif.c
Original file line number Diff line number Diff line change
Expand Up @@ -7998,46 +7998,43 @@ static void clif_pet_food(struct map_session_data *sd, int foodid, int fail)
WFIFOSET(fd, sizeof(struct PACKET_ZC_FEED_PET));
}

/// Presents a list of skills that can be auto-spelled (ZC_AUTOSPELLLIST).
/// 01cd { <skill id>.L }*7
static void clif_autospell(struct map_session_data *sd, uint16 skill_lv)
/**
* Presents a list of skills that can be auto-spelled (ZC_AUTOSPELLLIST).
*
* 01cd { <skill id>.L }*7
* 0afb <packet len>.W { <skills>.L }*
*
* @param sd player who will receive the list
* @param skill_lv autospell skill level
* @param skill_ids_list list of available skills to choose from
* @param list_len length of skill_ids_list
*/
static void clif_autospell(struct map_session_data *sd, uint16 skill_lv, int *skill_ids_list, int list_len)
{
#if PACKETVER_MAIN_NUM >= 20090406 || defined(PACKETVER_RE) || defined(PACKETVER_ZERO) || PACKETVER_SAK_NUM >= 20080618
nullpo_retv(sd);

int fd = sd->fd;
#if PACKETVER_MAIN_NUM >= 20181128 || PACKETVER_RE_NUM >= 20181031
// reserve space for 7 skills
WFIFOHEAD(fd, sizeof(struct PACKET_ZC_AUTOSPELLLIST) + 4 * 7);
const int len = sizeof(struct PACKET_ZC_AUTOSPELLLIST) + sizeof(int) * list_len;
#else
WFIFOHEAD(fd, sizeof(struct PACKET_ZC_AUTOSPELLLIST));
const int len = sizeof(struct PACKET_ZC_AUTOSPELLLIST);
if (list_len > 7) {
ShowError("%s: AutoSpell list too big for current client. Limit: %d, received: %d. Truncating list...\n", 7, list_len);
list_len = 7;
}
#endif

int fd = sd->fd;
WFIFOHEAD(fd, len);

struct PACKET_ZC_AUTOSPELLLIST *p = WFIFOP(fd, 0);
memset(p, 0, sizeof(struct PACKET_ZC_AUTOSPELLLIST));
p->packetType = HEADER_ZC_AUTOSPELLLIST;
int index = 0;

if (skill_lv > 0 && pc->checkskill(sd, MG_NAPALMBEAT) > 0)
p->skills[index++] = MG_NAPALMBEAT;
if (skill_lv > 1 && pc->checkskill(sd, MG_COLDBOLT) > 0)
p->skills[index++] = MG_COLDBOLT;
if (skill_lv > 1 && pc->checkskill(sd, MG_FIREBOLT) > 0)
p->skills[index++] = MG_FIREBOLT;
if (skill_lv > 1 && pc->checkskill(sd, MG_LIGHTNINGBOLT) > 0)
p->skills[index++] = MG_LIGHTNINGBOLT;
if (skill_lv > 4 && pc->checkskill(sd, MG_SOULSTRIKE) > 0)
p->skills[index++] = MG_SOULSTRIKE;
if (skill_lv > 7 && pc->checkskill(sd, MG_FIREBALL) > 0)
p->skills[index++] = MG_FIREBALL;
if (skill_lv > 9 && pc->checkskill(sd, MG_FROSTDIVER) > 0)
p->skills[index++] = MG_FROSTDIVER;

p->packetType = HEADER_ZC_AUTOSPELLLIST;
#if PACKETVER_MAIN_NUM >= 20181128 || PACKETVER_RE_NUM >= 20181031
const int len = sizeof(struct PACKET_ZC_AUTOSPELLLIST) + index * 4;
p->packetLength = len;
#else
const int len = sizeof(struct PACKET_ZC_AUTOSPELLLIST);
#endif
memcpy(p->skills, skill_ids_list, sizeof(int) * list_len);
WFIFOSET(fd, len);

sd->menuskill_id = SA_AUTOSPELL;
Expand Down
2 changes: 1 addition & 1 deletion src/map/clif.h
Original file line number Diff line number Diff line change
Expand Up @@ -1088,7 +1088,7 @@ struct clif_interface {
void (*skill_mapinfomessage) (struct map_session_data *sd, int type);
void (*skill_produce_mix_list) (struct map_session_data *sd, int skill_id, int trigger);
void (*cooking_list) (struct map_session_data *sd, int trigger, uint16 skill_id, int qty, int list_type);
void (*autospell) (struct map_session_data *sd,uint16 skill_lv);
void (*autospell) (struct map_session_data *sd, uint16 skill_lv, int *skill_ids_list, int list_len);
void (*combo_delay) (struct block_list *bl,int wait);
void (*status_change) (struct block_list *bl, int relevant_bl, int type, int flag, int total_tick, int val1, int val2, int val3);
void (*status_change_sub) (struct block_list *bl, int type, int relevant_bl, int flag, int tick, int total_tick, int val1, int val2, int val3);
Expand Down
115 changes: 77 additions & 38 deletions src/map/skill.c
Original file line number Diff line number Diff line change
Expand Up @@ -8776,43 +8776,8 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
sc_start(src, bl, type, 100, skill_lv, skill->get_time(skill_id, skill_lv), skill_id);
break;
case SA_AUTOSPELL:
clif->skill_nodamage(src,bl,skill_id,skill_lv,1);
if(sd){
sd->state.workinprogress = 3;
clif->autospell(sd,skill_lv);
}else {
int maxlv=1,spellid=0;
static const int spellarray[3] = { MG_COLDBOLT,MG_FIREBOLT,MG_LIGHTNINGBOLT };
if(skill_lv >= 10) {
spellid = MG_FROSTDIVER;
#if 0
if (tsc && tsc->data[SC_SOULLINK] && tsc->data[SC_SOULLINK]->val2 == SA_SAGE)
maxlv = 10;
else
#endif // 0
maxlv = skill_lv - 9;
}
else if(skill_lv >=8) {
spellid = MG_FIREBALL;
maxlv = skill_lv - 7;
}
else if(skill_lv >=5) {
spellid = MG_SOULSTRIKE;
maxlv = skill_lv - 4;
}
else if(skill_lv >=2) {
int i = rnd() % ARRAYLENGTH(spellarray);
spellid = spellarray[i];
maxlv = skill_lv - 1;
}
else if(skill_lv > 0) {
spellid = MG_NAPALMBEAT;
maxlv = 3;
}
if(spellid > 0)
sc_start4(src,src,SC_AUTOSPELL,100,skill_lv,spellid,maxlv,0,
skill->get_time(SA_AUTOSPELL, skill_lv), SA_AUTOSPELL);
}
clif->skill_nodamage(src, bl, skill_id, skill_lv, 1);
skill->autospell_select_spell(src, skill_lv);
break;

case BS_GREED:
Expand Down Expand Up @@ -17834,8 +17799,80 @@ static void skill_weaponrefine(struct map_session_data *sd, int idx)
}

/*==========================================
*
* Auto Spell / Hindsight
*------------------------------------------*/

/**
* Prepares list and request player to choose the spell they want to use (Auto Spell skill)
* @param sd player casting the skill
* @param skill_lv Auto Spell level
*/
static void skill_autospell_select_spell_pc(struct map_session_data *sd, int skill_lv)
{
nullpo_retv(sd);

int *skill_ids;
CREATE(skill_ids, int, MAX_AUTOSPELL_DB);

int valid_len = 0;

for (int i = 0; i < MAX_AUTOSPELL_DB; ++i) {
const struct s_autospell_db *sk = &skill->dbs->autospell_db[i];
if (sk->autospell_level == 0)
break;

if (skill_lv >= sk->autospell_level && pc->checkskill(sd, sk->skill_id) > 0) {
skill_ids[valid_len] = sk->skill_id;
valid_len++;
}
}

sd->state.workinprogress = 3;
clif->autospell(sd, skill_lv, skill_ids, valid_len);

aFree(skill_ids);
}

/**
* Auto Spell skill spell selection step.
* @param bl unit casting the skill
* @param skill_lv skill level
*/
static void skill_autospell_select_spell(struct block_list *bl, int skill_lv)
{
nullpo_retv(bl);

if (bl->type == BL_PC) {
skill->autospell_select_spell_pc(BL_CAST(BL_PC, bl), skill_lv);
return;
}

int lower_idx = -1;
int upper_idx = 0;
int highest_autospell_tier = 0;
while (upper_idx < MAX_AUTOSPELL_DB
&& skill->dbs->autospell_db[upper_idx].autospell_level > 0
&& skill->dbs->autospell_db[upper_idx].autospell_level <= skill_lv) {
if (highest_autospell_tier != skill->dbs->autospell_db[upper_idx].autospell_level) {
lower_idx = upper_idx;
highest_autospell_tier = skill->dbs->autospell_db[upper_idx].autospell_level;
}

upper_idx++;
}

if (lower_idx == -1)
return; // No skill available

int skill_idx = lower_idx;
if ((upper_idx - lower_idx) > 1)
skill_idx += rnd() % (upper_idx - lower_idx);

const struct s_autospell_db *sk = &skill->dbs->autospell_db[skill_idx];
sc_start4(bl, bl, SC_AUTOSPELL, 100, skill_lv, sk->skill_id, sk->skill_lv[skill_lv - 1], 0,
skill->get_time(SA_AUTOSPELL, skill_lv), SA_AUTOSPELL);
}

static int skill_autospell(struct map_session_data *sd, uint16 skill_id)
{
uint16 skill_lv;
Expand Down Expand Up @@ -25242,6 +25279,8 @@ void skill_defaults(void)
skill->repairweapon = skill_repairweapon;
skill->identify = skill_identify;
skill->weaponrefine = skill_weaponrefine;
skill->autospell_select_spell = skill_autospell_select_spell;
skill->autospell_select_spell_pc = skill_autospell_select_spell_pc;
skill->autospell = skill_autospell;
skill->calc_heal = skill_calc_heal;
skill->check_cloaking = skill_check_cloaking;
Expand Down
2 changes: 2 additions & 0 deletions src/map/skill.h
Original file line number Diff line number Diff line change
Expand Up @@ -2168,6 +2168,8 @@ struct skill_interface {
void (*repairweapon) (struct map_session_data *sd, int idx);
void (*identify) (struct map_session_data *sd,int idx);
void (*weaponrefine) (struct map_session_data *sd,int idx);
void (*autospell_select_spell) (struct block_list *bl, int skill_lv);
void (*autospell_select_spell_pc) (struct map_session_data *sd, int skill_lv);
int (*autospell) (struct map_session_data *md,uint16 skill_id);
int (*calc_heal) (struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, bool heal);
bool (*check_cloaking) (struct block_list *bl, struct status_change_entry *sce);
Expand Down
8 changes: 6 additions & 2 deletions src/plugins/HPMHooking/HPMHooking.Defs.inc
Original file line number Diff line number Diff line change
Expand Up @@ -1566,8 +1566,8 @@ typedef void (*HPMHOOK_pre_clif_skill_produce_mix_list) (struct map_session_data
typedef void (*HPMHOOK_post_clif_skill_produce_mix_list) (struct map_session_data *sd, int skill_id, int trigger);
typedef void (*HPMHOOK_pre_clif_cooking_list) (struct map_session_data **sd, int *trigger, uint16 *skill_id, int *qty, int *list_type);
typedef void (*HPMHOOK_post_clif_cooking_list) (struct map_session_data *sd, int trigger, uint16 skill_id, int qty, int list_type);
typedef void (*HPMHOOK_pre_clif_autospell) (struct map_session_data **sd, uint16 *skill_lv);
typedef void (*HPMHOOK_post_clif_autospell) (struct map_session_data *sd, uint16 skill_lv);
typedef void (*HPMHOOK_pre_clif_autospell) (struct map_session_data **sd, uint16 *skill_lv, int **skill_ids_list, int *list_len);
typedef void (*HPMHOOK_post_clif_autospell) (struct map_session_data *sd, uint16 skill_lv, int *skill_ids_list, int list_len);
typedef void (*HPMHOOK_pre_clif_combo_delay) (struct block_list **bl, int *wait);
typedef void (*HPMHOOK_post_clif_combo_delay) (struct block_list *bl, int wait);
typedef void (*HPMHOOK_pre_clif_status_change) (struct block_list **bl, int *relevant_bl, int *type, int *flag, int *total_tick, int *val1, int *val2, int *val3);
Expand Down Expand Up @@ -8466,6 +8466,10 @@ typedef void (*HPMHOOK_pre_skill_identify) (struct map_session_data **sd, int *i
typedef void (*HPMHOOK_post_skill_identify) (struct map_session_data *sd, int idx);
typedef void (*HPMHOOK_pre_skill_weaponrefine) (struct map_session_data **sd, int *idx);
typedef void (*HPMHOOK_post_skill_weaponrefine) (struct map_session_data *sd, int idx);
typedef void (*HPMHOOK_pre_skill_autospell_select_spell) (struct block_list **bl, int *skill_lv);
typedef void (*HPMHOOK_post_skill_autospell_select_spell) (struct block_list *bl, int skill_lv);
typedef void (*HPMHOOK_pre_skill_autospell_select_spell_pc) (struct map_session_data **sd, int *skill_lv);
typedef void (*HPMHOOK_post_skill_autospell_select_spell_pc) (struct map_session_data *sd, int skill_lv);
typedef int (*HPMHOOK_pre_skill_autospell) (struct map_session_data **md, uint16 *skill_id);
typedef int (*HPMHOOK_post_skill_autospell) (int retVal___, struct map_session_data *md, uint16 skill_id);
typedef int (*HPMHOOK_pre_skill_calc_heal) (struct block_list **src, struct block_list **target, uint16 *skill_id, uint16 *skill_lv, bool *heal);
Expand Down
8 changes: 8 additions & 0 deletions src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
Original file line number Diff line number Diff line change
Expand Up @@ -6390,6 +6390,10 @@ struct {
struct HPMHookPoint *HP_skill_identify_post;
struct HPMHookPoint *HP_skill_weaponrefine_pre;
struct HPMHookPoint *HP_skill_weaponrefine_post;
struct HPMHookPoint *HP_skill_autospell_select_spell_pre;
struct HPMHookPoint *HP_skill_autospell_select_spell_post;
struct HPMHookPoint *HP_skill_autospell_select_spell_pc_pre;
struct HPMHookPoint *HP_skill_autospell_select_spell_pc_post;
struct HPMHookPoint *HP_skill_autospell_pre;
struct HPMHookPoint *HP_skill_autospell_post;
struct HPMHookPoint *HP_skill_calc_heal_pre;
Expand Down Expand Up @@ -13931,6 +13935,10 @@ struct {
int HP_skill_identify_post;
int HP_skill_weaponrefine_pre;
int HP_skill_weaponrefine_post;
int HP_skill_autospell_select_spell_pre;
int HP_skill_autospell_select_spell_post;
int HP_skill_autospell_select_spell_pc_pre;
int HP_skill_autospell_select_spell_pc_post;
int HP_skill_autospell_pre;
int HP_skill_autospell_post;
int HP_skill_calc_heal_pre;
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
Original file line number Diff line number Diff line change
Expand Up @@ -3270,6 +3270,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(skill->repairweapon, HP_skill_repairweapon) },
{ HP_POP(skill->identify, HP_skill_identify) },
{ HP_POP(skill->weaponrefine, HP_skill_weaponrefine) },
{ HP_POP(skill->autospell_select_spell, HP_skill_autospell_select_spell) },
{ HP_POP(skill->autospell_select_spell_pc, HP_skill_autospell_select_spell_pc) },
{ HP_POP(skill->autospell, HP_skill_autospell) },
{ HP_POP(skill->calc_heal, HP_skill_calc_heal) },
{ HP_POP(skill->check_cloaking, HP_skill_check_cloaking) },
Expand Down
64 changes: 58 additions & 6 deletions src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
Original file line number Diff line number Diff line change
Expand Up @@ -12071,28 +12071,28 @@ void HP_clif_cooking_list(struct map_session_data *sd, int trigger, uint16 skill
}
return;
}
void HP_clif_autospell(struct map_session_data *sd, uint16 skill_lv) {
void HP_clif_autospell(struct map_session_data *sd, uint16 skill_lv, int *skill_ids_list, int list_len) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_autospell_pre > 0) {
void (*preHookFunc) (struct map_session_data **sd, uint16 *skill_lv);
void (*preHookFunc) (struct map_session_data **sd, uint16 *skill_lv, int **skill_ids_list, int *list_len);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_autospell_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_clif_autospell_pre[hIndex].func;
preHookFunc(&sd, &skill_lv);
preHookFunc(&sd, &skill_lv, &skill_ids_list, &list_len);
}
if (*HPMforce_return) {
*HPMforce_return = false;
return;
}
}
{
HPMHooks.source.clif.autospell(sd, skill_lv);
HPMHooks.source.clif.autospell(sd, skill_lv, skill_ids_list, list_len);
}
if (HPMHooks.count.HP_clif_autospell_post > 0) {
void (*postHookFunc) (struct map_session_data *sd, uint16 skill_lv);
void (*postHookFunc) (struct map_session_data *sd, uint16 skill_lv, int *skill_ids_list, int list_len);
for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_autospell_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_clif_autospell_post[hIndex].func;
postHookFunc(sd, skill_lv);
postHookFunc(sd, skill_lv, skill_ids_list, list_len);
}
}
return;
Expand Down Expand Up @@ -85256,6 +85256,58 @@ void HP_skill_weaponrefine(struct map_session_data *sd, int idx) {
}
return;
}
void HP_skill_autospell_select_spell(struct block_list *bl, int skill_lv) {
int hIndex = 0;
if (HPMHooks.count.HP_skill_autospell_select_spell_pre > 0) {
void (*preHookFunc) (struct block_list **bl, int *skill_lv);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_autospell_select_spell_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_skill_autospell_select_spell_pre[hIndex].func;
preHookFunc(&bl, &skill_lv);
}
if (*HPMforce_return) {
*HPMforce_return = false;
return;
}
}
{
HPMHooks.source.skill.autospell_select_spell(bl, skill_lv);
}
if (HPMHooks.count.HP_skill_autospell_select_spell_post > 0) {
void (*postHookFunc) (struct block_list *bl, int skill_lv);
for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_autospell_select_spell_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_skill_autospell_select_spell_post[hIndex].func;
postHookFunc(bl, skill_lv);
}
}
return;
}
void HP_skill_autospell_select_spell_pc(struct map_session_data *sd, int skill_lv) {
int hIndex = 0;
if (HPMHooks.count.HP_skill_autospell_select_spell_pc_pre > 0) {
void (*preHookFunc) (struct map_session_data **sd, int *skill_lv);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_autospell_select_spell_pc_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_skill_autospell_select_spell_pc_pre[hIndex].func;
preHookFunc(&sd, &skill_lv);
}
if (*HPMforce_return) {
*HPMforce_return = false;
return;
}
}
{
HPMHooks.source.skill.autospell_select_spell_pc(sd, skill_lv);
}
if (HPMHooks.count.HP_skill_autospell_select_spell_pc_post > 0) {
void (*postHookFunc) (struct map_session_data *sd, int skill_lv);
for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_autospell_select_spell_pc_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_skill_autospell_select_spell_pc_post[hIndex].func;
postHookFunc(sd, skill_lv);
}
}
return;
}
int HP_skill_autospell(struct map_session_data *md, uint16 skill_id) {
int hIndex = 0;
int retVal___ = 0;
Expand Down

0 comments on commit 225593f

Please sign in to comment.