Przeglądaj źródła

Yet another autospell fix (#6341)

Fixes #6337

Hopefully this was all now.

Thanks to @renniw
Lemongrass3110 3 lat temu
rodzic
commit
22c7f3988d
4 zmienionych plików z 34 dodań i 16 usunięć
  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

+ 10 - 9
src/map/pc.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,7 +4464,7 @@ 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;
@@ -4471,7 +4472,7 @@ 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->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;

+ 7 - 0
src/map/pc.hpp

@@ -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;

+ 6 - 0
src/map/script_constants.hpp

@@ -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

+ 11 - 7
src/map/skill.cpp

@@ -2188,7 +2188,7 @@ 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;
@@ -2196,7 +2196,7 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
 			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))