Skip to content
Permalink
Browse files
Yet another autospell fix (#6341)
Fixes #6337

Hopefully this was all now.

Thanks to @renniw
  • Loading branch information
Lemongrass3110 committed Nov 2, 2021
1 parent 7277d47 commit 22c7f3988dd0b8f0b8089acb2f1e2cd11ca008ee
Showing with 34 additions and 16 deletions.
  1. +10 −9 src/map/pc.cpp
  2. +7 −0 src/map/pc.hpp
  3. +6 −0 src/map/script_constants.hpp
  4. +11 −7 src/map/skill.cpp
@@ -2527,6 +2527,7 @@ int pc_disguise(struct map_session_data *sd, int class_)
* @param battle_flag: Battle flag
* @param card_id: Used to prevent card stacking
* @param flag: Flags used for extra arguments
* &0: forces the skill to be casted on self, rather than on the target
* &1: forces the skill to be casted on target, rather than self
* &2: random skill level in [1..lv] is chosen
*/
@@ -2552,7 +2553,7 @@ static void pc_bonus_autospell(std::vector<s_autospell> &spell, uint16 id, uint1
}

for (auto &it : spell) {
if ((it.card_id == card_id || it.rate < 0 || rate < 0) && it.id == id && it.lv == lv && it.flag == battle_flag) {
if ((it.card_id == card_id || it.rate < 0 || rate < 0) && it.id == id && it.lv == lv && it.battle_flag == battle_flag && it.flag == flag) {
if (!battle_config.autospell_stacking && it.rate > 0 && rate > 0) // Stacking disabled
return;
it.rate = cap_value(it.rate + rate, -10000, 10000);
@@ -4463,15 +4464,15 @@ void pc_bonus3(struct map_session_data *sd,int type,int type2,int type3,int val)
{
int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !skill_get_inf2(type2, INF2_NOTARGETSELF));
pc_bonus_autospell(sd->autospell, type2, type3, val, 0, current_equip_card_id, target ? 1 : 0);
pc_bonus_autospell(sd->autospell, type2, type3, val, 0, current_equip_card_id, target ? AUTOSPELL_FORCE_TARGET : AUTOSPELL_FORCE_SELF);
}
break;
case SP_AUTOSPELL_WHENHIT: // bonus3 bAutoSpellWhenHit,sk,y,n;
if(sd->state.lr_flag != 2)
{
int target = skill_get_inf(type2); //Support or Self (non-auto-target) skills should pick self.
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !skill_get_inf2(type2, INF2_NOTARGETSELF));
pc_bonus_autospell(sd->autospell2, type2, type3, val, BF_NORMAL|BF_SKILL, current_equip_card_id, target ? 1 : 0);
pc_bonus_autospell(sd->autospell2, type2, type3, val, BF_NORMAL|BF_SKILL, current_equip_card_id, target ? AUTOSPELL_FORCE_TARGET : AUTOSPELL_FORCE_SELF);
}
break;
case SP_ADD_MONSTER_DROP_ITEMGROUP: // bonus3 bAddMonsterDropItemGroup,ig,r,n;
@@ -4589,12 +4590,12 @@ void pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type
switch(type){
case SP_AUTOSPELL: // bonus4 bAutoSpell,sk,y,n,i;
if(sd->state.lr_flag != 2)
pc_bonus_autospell(sd->autospell, type2, type3, type4, 0, current_equip_card_id, val);
pc_bonus_autospell(sd->autospell, type2, type3, type4, 0, current_equip_card_id, val & AUTOSPELL_FORCE_ALL);
break;

case SP_AUTOSPELL_WHENHIT: // bonus4 bAutoSpellWhenHit,sk,y,n,i;
if(sd->state.lr_flag != 2)
pc_bonus_autospell(sd->autospell2, type2, type3, type4, BF_NORMAL|BF_SKILL, current_equip_card_id, val);
pc_bonus_autospell(sd->autospell2, type2, type3, type4, BF_NORMAL|BF_SKILL, current_equip_card_id, val & AUTOSPELL_FORCE_ALL);
break;

case SP_AUTOSPELL_ONSKILL: // bonus4 bAutoSpellOnSkill,sk,x,y,n;
@@ -4603,7 +4604,7 @@ void pc_bonus4(struct map_session_data *sd,int type,int type2,int type3,int type
int target = skill_get_inf(type3); //Support or Self (non-auto-target) skills should pick self.
target = target&INF_SUPPORT_SKILL || (target&INF_SELF_SKILL && !skill_get_inf2(type3, INF2_NOTARGETSELF));

pc_bonus_autospell_onskill(sd->autospell3, type2, type3, type4, val, current_equip_card_id, target ? 1 : 0);
pc_bonus_autospell_onskill(sd->autospell3, type2, type3, type4, val, current_equip_card_id, target ? AUTOSPELL_FORCE_TARGET : AUTOSPELL_FORCE_SELF);
}
break;

@@ -4672,17 +4673,17 @@ void pc_bonus5(struct map_session_data *sd,int type,int type2,int type3,int type
switch(type){
case SP_AUTOSPELL: // bonus5 bAutoSpell,sk,y,n,bf,i;
if(sd->state.lr_flag != 2)
pc_bonus_autospell(sd->autospell, type2, type3, type4, type5, current_equip_card_id, val);
pc_bonus_autospell(sd->autospell, type2, type3, type4, type5, current_equip_card_id, val & AUTOSPELL_FORCE_ALL);
break;

case SP_AUTOSPELL_WHENHIT: // bonus5 bAutoSpellWhenHit,sk,y,n,bf,i;
if(sd->state.lr_flag != 2)
pc_bonus_autospell(sd->autospell2, type2, type3, type4, type5, current_equip_card_id, val);
pc_bonus_autospell(sd->autospell2, type2, type3, type4, type5, current_equip_card_id, val & AUTOSPELL_FORCE_ALL);
break;

case SP_AUTOSPELL_ONSKILL: // bonus5 bAutoSpellOnSkill,sk,x,y,n,i;
if(sd->state.lr_flag != 2)
pc_bonus_autospell_onskill(sd->autospell3, type2, type3, type4, type5, current_equip_card_id, val);
pc_bonus_autospell_onskill(sd->autospell3, type2, type3, type4, type5, current_equip_card_id, val & AUTOSPELL_FORCE_ALL);
break;

case SP_ADDEFF_ONSKILL: // bonus5 bAddEffOnSkill,sk,eff,n,y,t;
@@ -192,6 +192,13 @@ struct weapon_data {
std::vector<s_addrace2> addrace3;
};

enum e_autospell_flags{
AUTOSPELL_FORCE_SELF = 0x0,
AUTOSPELL_FORCE_TARGET = 0x1,
AUTOSPELL_FORCE_RANDOM_LEVEL = 0x2,
AUTOSPELL_FORCE_ALL = 0x3
};

/// AutoSpell bonus struct
struct s_autospell {
uint16 id, lv, trigger_skill;
@@ -8205,6 +8205,12 @@
export_constant(REFINE_TYPE_SHADOW_ARMOR);
export_constant(REFINE_TYPE_SHADOW_WEAPON);

/* autospell flags */
export_constant(AUTOSPELL_FORCE_SELF);
export_constant(AUTOSPELL_FORCE_TARGET);
export_constant(AUTOSPELL_FORCE_RANDOM_LEVEL);
export_constant(AUTOSPELL_FORCE_ALL);

#undef export_constant
#undef export_constant2
#undef export_parameter
@@ -2188,15 +2188,15 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1

uint16 autospl_skill_lv = it.lv ? it.lv : 1;

if (it.flag & 2)
if (it.flag & AUTOSPELL_FORCE_RANDOM_LEVEL)
autospl_skill_lv = rnd_value( 1, autospl_skill_lv );

rate = (!sd->state.arrow_atk) ? it.rate : it.rate / 2;

if (rnd()%1000 >= rate)
continue;

block_list *tbl = (it.flag & 1) ? src : bl;
block_list *tbl = (it.flag & AUTOSPELL_FORCE_TARGET) ? bl : src;
e_cast_type type = skill_get_casttype(skill);

if (type == CAST_GROUND) {
@@ -2300,15 +2300,19 @@ int skill_onskillusage(struct map_session_data *sd, struct block_list *bl, uint1

sd->state.autocast = 0;

if( skill > 0 && bl == nullptr )
// DANGER DANGER: here force target actually means use yourself as target!
block_list *tbl = (it.flag & AUTOSPELL_FORCE_TARGET) ? &sd->bl : bl;

if( tbl == nullptr ){
continue; // No target
}

if( rnd()%1000 >= it.rate )
continue;

block_list *tbl = (it.flag & 1) ? &sd->bl : bl;
uint16 skill_lv = it.lv ? it.lv : 1;

if (it.flag & 2)
if (it.flag & AUTOSPELL_FORCE_RANDOM_LEVEL)
skill_lv = rnd_value( 1, skill_lv ); //random skill_lv

e_cast_type type = skill_get_casttype(skill);
@@ -2504,7 +2508,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *

uint16 autospl_skill_id = it.id, autospl_skill_lv = it.lv ? it.lv : 1;

if (it.flag & 2)
if (it.flag & AUTOSPELL_FORCE_RANDOM_LEVEL)
autospl_skill_lv = rnd_value( 1, autospl_skill_lv );

int autospl_rate = it.rate;
@@ -2523,7 +2527,7 @@ int skill_counter_additional_effect (struct block_list* src, struct block_list *
if (rnd()%1000 >= autospl_rate)
continue;

block_list *tbl = (it.flag & 1) ? bl : src;
block_list *tbl = (it.flag & AUTOSPELL_FORCE_TARGET) ? bl : src;
e_cast_type type = skill_get_casttype(autospl_skill_id);

if (type == CAST_GROUND && !skill_pos_maxcount_check(bl, tbl->x, tbl->y, autospl_skill_id, autospl_skill_lv, BL_PC, false))

2 comments on commit 22c7f39

@Anjuts
Copy link

@Anjuts Anjuts commented on 22c7f39 Nov 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I test this latest commit, but this script still back to the caster:

bonus3 bAutoSpell,"MG_COLDBOLT",1,1000;
bonus3 bAutoSpell,"MG_FIREBOLT",1,1000;
bonus3 bAutoSpell,"MG_LIGHTNINGBOLT",1,1000;

@mazvi
Copy link
Contributor

@mazvi mazvi commented on 22c7f39 Nov 3, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Anjuts please open issue with detailed how to reproduce, and full script of the item from item id.

Edit:
issue comfirm, i just open new issue #6346

Please sign in to comment.