Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Clean up auto-cast related code #2657

Merged
merged 21 commits into from
Apr 5, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
81a2b77
Add enumeration for auto-cast types
Kenpachi2k13 Mar 11, 2020
e0ce59d
Add structure for auto-cast related data
Kenpachi2k13 Mar 11, 2020
bfbb4fc
Add struct autocast_data to struct map_session_data
Kenpachi2k13 Mar 11, 2020
3e84767
Add map_session_data->autocast.type assignments
Kenpachi2k13 Mar 11, 2020
80e505d
Add map_session_data->autocast.skill_id/_lv assignments
Kenpachi2k13 Mar 11, 2020
735b763
Add map_session_data->autocast.itemskill_* assignments
Kenpachi2k13 Mar 11, 2020
0a1982b
Rename function pc_itemskill_clear() to pc_autocast_clear()
Kenpachi2k13 Mar 11, 2020
b6ecc4b
Add pc_autocast_clear() function calls
Kenpachi2k13 Mar 11, 2020
017b07d
Remove misplaced pc_autocast_clear() function call
Kenpachi2k13 Mar 11, 2020
4470161
Add skill_validate_autocast_data() function
Kenpachi2k13 Mar 11, 2020
b151b29
Add skill_validate_autocast_data() function calls
Kenpachi2k13 Mar 11, 2020
7d70f7e
Remove map_session_data->state.autocast and use map_session_data->aut…
Kenpachi2k13 Mar 11, 2020
492c7bc
Remove map_session_data->state.abra_flag and use map_session_data->au…
Kenpachi2k13 Mar 11, 2020
49d0ce1
Remove skill_is_item_skill() function and use map_session_data->autoc…
Kenpachi2k13 Mar 11, 2020
d92d177
Remove itemskill_id and itemskill_lv helper variables, since they are…
Kenpachi2k13 Mar 11, 2020
12de22e
Remove map_session_data->state.itemskill_* and use map_session_data->…
Kenpachi2k13 Mar 11, 2020
6f49858
Use map_session_data->autocast.type instead of skillitem variable to …
Kenpachi2k13 Mar 11, 2020
10312bc
Remove obsolete auto-cast type validation from skill_check_condition_…
Kenpachi2k13 Mar 11, 2020
44581f9
Remove skillitem and skillitemlv variables and use map_session_data->…
Kenpachi2k13 Mar 11, 2020
7c6e21a
Remove IT_DELAYCONSUME related auto-cast code
Kenpachi2k13 Mar 12, 2020
876cfa6
Make skills cast by Improvised Song ignore all requirements
Kenpachi2k13 Mar 13, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/map/atcommand.c
Original file line number Diff line number Diff line change
Expand Up @@ -5671,6 +5671,8 @@ ACMD(useskill)
return false;
}

pc->autocast_clear(sd);

if (skill_id >= HM_SKILLBASE && skill_id < HM_SKILLBASE+MAX_HOMUNSKILL
&& sd->hd && homun_alive(sd->hd)) // (If used with @useskill, put the homunc as dest)
bl = &sd->hd->bl;
Expand Down
20 changes: 10 additions & 10 deletions src/map/battle.c
Original file line number Diff line number Diff line change
Expand Up @@ -5928,21 +5928,21 @@ static void battle_reflect_damage(struct block_list *target, struct block_list *
delay += 100;/* gradual increase so the numbers don't clip in the client */
}
if( sc->data[SC_LG_REFLECTDAMAGE] && rnd()%100 < (30 + 10*sc->data[SC_LG_REFLECTDAMAGE]->val1) ) {
bool change = false;

NORMALIZE_RDAMAGE(damage * sc->data[SC_LG_REFLECTDAMAGE]->val2 / 100);

trdamage -= rdamage;/* wont count towards total */

if( sd && !sd->state.autocast ) {
change = true;
sd->state.autocast = 1;
enum autocast_type ac_type;

if (sd != NULL) {
ac_type = sd->autocast.type;
sd->autocast.type = AUTOCAST_TEMP;
}

map->foreachinshootrange(battle->damage_area,target,skill->get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,delay,wd->dmotion,rdamage,status_get_race(target));

if( change )
sd->state.autocast = 0;
if (sd != NULL)
sd->autocast.type = ac_type;

delay += 150;/* gradual increase so the numbers don't clip in the client */

Expand Down Expand Up @@ -6132,7 +6132,7 @@ static int battle_damage_area(struct block_list *bl, va_list ap)
else
status_fix_damage(src,bl,damage,0);
clif->damage(bl,bl,amotion,dmotion,damage,1,BDT_ENDURE,0);
if (src->type != BL_PC || !BL_UCCAST(BL_PC, src)->state.autocast)
if (src->type != BL_PC || BL_UCCAST(BL_PC, src)->autocast.type != AUTOCAST_TEMP)
skill->additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
map->freeblock_unlock();
}
Expand Down Expand Up @@ -6456,10 +6456,10 @@ static enum damage_lv battle_weapon_attack(struct block_list *src, struct block_
}
}

sd->state.autocast = 1;
sd->autocast.type = AUTOCAST_TEMP;
skill->consume_requirement(sd,r_skill,r_lv,3);
skill->castend_type(type, src, target, r_skill, r_lv, tick, flag);
sd->state.autocast = 0;
sd->autocast.type = AUTOCAST_NONE;
sd->ud.canact_tick = tick + skill->delay_fix(src, r_skill, r_lv);
clif->status_change(src, status->get_sc_icon(SC_POSTDELAY), status->get_sc_relevant_bl_types(SC_POSTDELAY), 1, skill->delay_fix(src, r_skill, r_lv), 0, 0, 1);
}
Expand Down
48 changes: 36 additions & 12 deletions src/map/clif.c
Original file line number Diff line number Diff line change
Expand Up @@ -6766,7 +6766,7 @@ static void clif_item_skill(struct map_session_data *sd, uint16 skill_id, uint16
struct PACKET_ZC_AUTORUN_SKILL *p = WFIFOP(fd, 0);
int type = skill->get_inf(skill_id);

if (sd->state.itemskill_castonself == 1 && skill->is_item_skill(sd, skill_id, skill_lv))
if (sd->autocast.itemskill_cast_on_self && sd->autocast.type == AUTOCAST_ITEM)
type = INF_SELF_SKILL;

p->packetType = HEADER_ZC_AUTORUN_SKILL;
Expand Down Expand Up @@ -12706,6 +12706,14 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill
{
int64 tick = timer->gettick();

/**
* According to Skotlex' comment below, the client sometimes passes 0 for the skill level.
* Even though this seems to only affect guild skills, sd->autocast.skill_lv is used
* for the auto-cast data validation if skill_lv is 0.
*
**/
skill->validate_autocast_data(sd, skill_id, (skill_lv == 0) ? sd->autocast.skill_lv : skill_lv);

if (skill_lv < 1)
skill_lv = 1; //No clue, I have seen the client do this with guild skills :/ [Skotlex]

Expand Down Expand Up @@ -12759,7 +12767,7 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill
if (skill_id != SA_CASTCANCEL && skill_id != SO_SPELLFIST)
return;
} else if (DIFF_TICK(tick, sd->ud.canact_tick) < 0) {
if (sd->skillitem != skill_id) {
if (sd->autocast.type == AUTOCAST_NONE) {
clif->skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0, 0);
return;
}
Expand All @@ -12777,16 +12785,16 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill
} else if (sd->menuskill_id != SA_AUTOSPELL)
return; //Can't use skills while a menu is open.
}
if (sd->skillitem == skill_id) {
if (skill_lv != sd->skillitemlv)
skill_lv = sd->skillitemlv;
if (sd->autocast.type != AUTOCAST_NONE) {
if (skill_lv != sd->autocast.skill_lv)
skill_lv = sd->autocast.skill_lv;
if (!(tmp&INF_SELF_SKILL))
pc->delinvincibletimer(sd); // Target skills through items cancel invincibility. [Inkfish]
unit->skilluse_id(&sd->bl, target_id, skill_id, skill_lv);
return;
}

sd->skillitem = sd->skillitemlv = 0;
pc->autocast_clear(sd);

if (skill_id >= GD_SKILLBASE && skill_id < GD_MAX) {
if (sd->state.gmaster_flag)
Expand Down Expand Up @@ -12847,6 +12855,16 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
int64 tick = timer->gettick();

nullpo_retv(sd);

/**
* When using clif_item_skill() to initiate the execution of ground skills,
* the client sometimes passes 0 for the skill level in packet 0x0af4.
* In that case sd->autocast.skill_lv is used for the auto-cast data validation,
* since clif_item_skill() is only used for auto-cast skills.
*
**/
skill->validate_autocast_data(sd, skill_id, (skill_lv == 0) ? sd->autocast.skill_lv : skill_lv);

if( !(skill->get_inf(skill_id)&INF_GROUND_SKILL) )
return; //Using a target skill on the ground? WRONG.

Expand Down Expand Up @@ -12887,7 +12905,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
return;

if( DIFF_TICK(tick, sd->ud.canact_tick) < 0 ) {
if( sd->skillitem != skill_id ) {
if (sd->autocast.type == AUTOCAST_NONE) {
clif->skill_fail(sd, skill_id, USESKILL_FAIL_SKILLINTERVAL, 0, 0);
return;
}
Expand All @@ -12908,13 +12926,13 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin

pc->delinvincibletimer(sd);

if( sd->skillitem == skill_id ) {
if( skill_lv != sd->skillitemlv )
skill_lv = sd->skillitemlv;
if (sd->autocast.type != AUTOCAST_NONE) {
if (skill_lv != sd->autocast.skill_lv)
skill_lv = sd->autocast.skill_lv;
unit->skilluse_pos(&sd->bl, x, y, skill_id, skill_lv);
} else {
int lv;
sd->skillitem = sd->skillitemlv = 0;
pc->autocast_clear(sd);
if( (lv = pc->checkskill(sd, skill_id)) > 0 ) {
if( skill_lv > lv )
skill_lv = lv;
Expand Down Expand Up @@ -12985,9 +13003,15 @@ static void clif_parse_UseSkillMap(int fd, struct map_session_data *sd)
return;
}

/**
* Since no skill level was passed use 0 to notify skill_validate_autocast_data() of this special case.
*
**/
skill->validate_autocast_data(sd, skill_id, 0);

pc->delinvincibletimer(sd);
skill->castend_map(sd,skill_id,map_name);
pc->itemskill_clear(sd);
pc->autocast_clear(sd);
}

static void clif_parse_RequestMemo(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
Expand Down
29 changes: 13 additions & 16 deletions src/map/pc.c
Original file line number Diff line number Diff line change
Expand Up @@ -5295,10 +5295,6 @@ static int pc_useitem(struct map_session_data *sd, int n)
if(sd->catch_target_class != -1) //Abort pet catching.
sd->catch_target_class = -1;

// Removes abracadabra/randomize spell flag for delayed consume items or item doesn't get consumed
if (sd->inventory_data[n]->flag.delay_consume)
sd->state.abra_flag = 0;

amount = sd->status.inventory[n].amount;
//Check if the item is to be consumed immediately [Skotlex]
if (sd->inventory_data[n]->flag.delay_consume || sd->inventory_data[n]->flag.keepafteruse)
Expand Down Expand Up @@ -5337,21 +5333,22 @@ static int pc_useitem(struct map_session_data *sd, int n)
}

/**
* Sets state flags and helper variables, used by itemskill() script command, to 0.
* Unsets a character's auto-cast related data.
*
* @param sd The character's session data.
* @return 0 if parameter sd is NULL, otherwise 1.
*/
static int pc_itemskill_clear(struct map_session_data *sd)
static int pc_autocast_clear(struct map_session_data *sd)
{
nullpo_ret(sd);

sd->itemskill_id = 0;
sd->itemskill_lv = 0;
sd->state.itemskill_conditions_checked = 0;
sd->state.itemskill_check_conditions = 0;
sd->state.itemskill_no_casttime = 0;
sd->state.itemskill_castonself = 0;
sd->autocast.type = AUTOCAST_NONE;
sd->autocast.skill_id = 0;
sd->autocast.skill_lv = 0;
sd->autocast.itemskill_conditions_checked = false;
sd->autocast.itemskill_check_conditions = false;
sd->autocast.itemskill_instant_cast = false;
sd->autocast.itemskill_cast_on_self = false;

return 1;
}
Expand Down Expand Up @@ -8122,9 +8119,9 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src)

clif->party_dead_notification(sd);

//Reset menu skills/item skills
if (sd->skillitem)
sd->skillitem = sd->skillitemlv = 0;
pc->autocast_clear(sd); // Unset auto-cast data.

// Reset menu skills.
if (sd->menuskill_id)
sd->menuskill_id = sd->menuskill_val = 0;
//Reset ticks.
Expand Down Expand Up @@ -12726,7 +12723,7 @@ void pc_defaults(void)
pc->unequipitem_pos = pc_unequipitem_pos;
pc->checkitem = pc_checkitem;
pc->useitem = pc_useitem;
pc->itemskill_clear = pc_itemskill_clear;
pc->autocast_clear = pc_autocast_clear;

pc->skillatk_bonus = pc_skillatk_bonus;
pc->skillheal_bonus = pc_skillheal_bonus;
Expand Down
30 changes: 13 additions & 17 deletions src/map/pc.h
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,17 @@ struct pc_combos {
int id; /* this combo id */
};

/** Auto-cast related data. **/
struct autocast_data {
enum autocast_type type; // The auto-cast type.
int skill_id; // The auto-cast skill ID.
int skill_lv; // The auto-cast skill level.
bool itemskill_conditions_checked; // Used by itemskill() script command, to prevent second check of conditions after target was selected.
Kenpachi2k13 marked this conversation as resolved.
Show resolved Hide resolved
bool itemskill_check_conditions; // Used by itemskill() script command, to check skill conditions and consume them.
bool itemskill_instant_cast; // Used by itemskill() script command, to cast skill instantaneously.
bool itemskill_cast_on_self; // Used by itemskill() script command, to forcefully cast skill on invoking character.
};

struct map_session_data {
struct block_list bl;
struct unit_data ud;
Expand All @@ -181,6 +192,7 @@ struct map_session_data {
struct status_change sc;
struct regen_data regen;
struct regen_data_sub sregen, ssregen;
struct autocast_data autocast;
//NOTE: When deciding to add a flag to state or special_state, take into consideration that state is preserved in
//status_calc_pc, while special_state is recalculated in each call. [Skotlex]
struct {
Expand All @@ -194,8 +206,6 @@ struct map_session_data {
unsigned int rest : 1;
unsigned int storage_flag : 2; // @see enum storage_flag
unsigned int snovice_dead_flag : 1; //Explosion spirits on death: 0 off, 1 used.
unsigned int abra_flag : 2; // Abracadabra bugfix by Aru
unsigned int autocast : 1; // Autospell flag [Inkfish]
unsigned int autotrade : 2; //By Fantik
unsigned int showdelay :1;
unsigned int showexp :1;
Expand Down Expand Up @@ -240,10 +250,6 @@ struct map_session_data {
unsigned int refine_ui : 1;
unsigned int npc_unloaded : 1; ///< The player is talking with an unloaded NPCs (respawned tombstones)
unsigned int lapine_ui : 1;
unsigned int itemskill_conditions_checked : 1; // Used by itemskill() script command, to prevent second check of conditions after target was selected.
unsigned int itemskill_check_conditions : 1; // Used by itemskill() script command, to check skill conditions and consume them.
unsigned int itemskill_no_casttime : 1; // Used by itemskill() script command, to cast skill instantaneously.
unsigned int itemskill_castonself : 1; // Used by itemskill() script command, to forcefully cast skill on invoking character.
} state;
struct {
unsigned char no_weapon_damage, no_magic_damage, no_misc_damage;
Expand Down Expand Up @@ -298,7 +304,6 @@ struct map_session_data {
int followtimer; // [MouseJstr]
int followtarget;
time_t emotionlasttime; // to limit flood with emotion packets
int skillitem,skillitemlv;
uint16 skill_id_old,skill_lv_old;
uint16 skill_id_dance,skill_lv_dance;
short cook_mastery; // range: [0,1999] [Inkfish]
Expand Down Expand Up @@ -647,15 +652,6 @@ END_ZEROED_BLOCK;
bool achievements_received;
// Title
VECTOR_DECL(int) title_ids;

/*
* itemskill_conditions_checked/itemskill_no_conditions/itemskill_no_casttime/itemskill_castonself abuse prevention.
* If a skill, casted by itemskill() script command, is aborted while target selection,
* the map server gets no notification where these states could be unset.
* Thus we need this helper variables to prevent abusing these states for next skill cast.
*/
int itemskill_id;
int itemskill_lv;
};

#define EQP_WEAPON EQP_HAND_R
Expand Down Expand Up @@ -1034,7 +1030,7 @@ END_ZEROED_BLOCK; /* End */
void (*unequipitem_pos) (struct map_session_data *sd, int n, int pos);
int (*checkitem) (struct map_session_data *sd);
int (*useitem) (struct map_session_data *sd,int n);
int (*itemskill_clear) (struct map_session_data *sd);
int (*autocast_clear) (struct map_session_data *sd);

int (*skillatk_bonus) (struct map_session_data *sd, uint16 skill_id);
int (*skillheal_bonus) (struct map_session_data *sd, uint16 skill_id);
Expand Down
36 changes: 19 additions & 17 deletions src/map/script.c
Original file line number Diff line number Diff line change
Expand Up @@ -11001,33 +11001,29 @@ static BUILDIN(itemskill)
if (sd == NULL || sd->ud.skilltimer != INVALID_TIMER)
return true;

pc->itemskill_clear(sd);
sd->skillitem = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2);
sd->skillitemlv = script_getnum(st, 3);
sd->state.itemskill_conditions_checked = 0; // Skill casting items will check the conditions prior to the target selection in AEGIS. Thus we need a flag to prevent checking them twice.
pc->autocast_clear(sd);
sd->autocast.type = AUTOCAST_ITEM;
sd->autocast.skill_id = script_isstringtype(st, 2) ? skill->name2id(script_getstr(st, 2)) : script_getnum(st, 2);
sd->autocast.skill_lv = script_getnum(st, 3);

int flag = script_hasdata(st, 4) ? script_getnum(st, 4) : ISF_NONE;

sd->state.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS) ? 1 : 0; // Unset in pc_itemskill_clear().
sd->autocast.itemskill_check_conditions = ((flag & ISF_CHECKCONDITIONS) == ISF_CHECKCONDITIONS);

if (sd->state.itemskill_check_conditions == 1) {
if (skill->check_condition_castbegin(sd, sd->skillitem, sd->skillitemlv) == 0
|| skill->check_condition_castend(sd, sd->skillitem, sd->skillitemlv) == 0) {
pc->itemskill_clear(sd);
if (sd->autocast.itemskill_check_conditions) {
if (skill->check_condition_castbegin(sd, sd->autocast.skill_id, sd->autocast.skill_lv) == 0
|| skill->check_condition_castend(sd, sd->autocast.skill_id, sd->autocast.skill_lv) == 0) {
pc->autocast_clear(sd);
return true;
}

sd->state.itemskill_conditions_checked = 1; // Unset in pc_itemskill_clear().
sd->autocast.itemskill_conditions_checked = true;
}

sd->state.itemskill_no_casttime = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST) ? 1 : 0; // Unset in pc_itemskill_clear().
sd->state.itemskill_castonself = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF) ? 1 : 0; // Unset in pc_itemskill_clear().
sd->autocast.itemskill_instant_cast = ((flag & ISF_INSTANTCAST) == ISF_INSTANTCAST);
sd->autocast.itemskill_cast_on_self = ((flag & ISF_CASTONSELF) == ISF_CASTONSELF);

// itemskill_conditions_checked/itemskill_no_conditions/itemskill_no_casttime/itemskill_castonself abuse prevention. Unset in pc_itemskill_clear().
sd->itemskill_id = sd->skillitem;
sd->itemskill_lv = sd->skillitemlv;

clif->item_skill(sd, sd->skillitem, sd->skillitemlv);
clif->item_skill(sd, sd->autocast.skill_id, sd->autocast.skill_lv);

return true;
}
Expand Down Expand Up @@ -21429,7 +21425,10 @@ static BUILDIN(unitskilluseid)
} else {
status_calc_npc(nd, SCO_NONE);
}
} else if (bl->type == BL_PC) {
pc->autocast_clear(BL_UCAST(BL_PC, bl));
}

unit->skilluse_id(bl, target_id, skill_id, skill_lv);
}

Expand Down Expand Up @@ -21465,7 +21464,10 @@ static BUILDIN(unitskillusepos)
} else {
status_calc_npc(nd, SCO_NONE);
}
} else if (bl->type == BL_PC) {
pc->autocast_clear(BL_UCAST(BL_PC, bl));
}

unit->skilluse_pos(bl, skill_x, skill_y, skill_id, skill_lv);
}

Expand Down
Loading