浏览代码

Fixed bugreport:2657 castend now also checks if the required weapon matches, fixing any possible exploits where a character manages to change weapon during cast/animation e.g., as the report claims, sonic blow. (also applied my curly brace love on the way)
Special Thanks to esu1214!

git-svn-id: https://svn.code.sf.net/p/rathena/svn/trunk@16817 54d463be-8e91-2dee-dedb-b68131a5f0ec

shennetsind 12 年之前
父节点
当前提交
b313d24eb2
共有 1 个文件被更改,包括 57 次插入59 次删除
  1. 57 59
      src/map/skill.c

+ 57 - 59
src/map/skill.c

@@ -12889,8 +12889,8 @@ int skill_check_condition_castend(struct map_session_data* sd, short skill, shor
 	if( lv <= 0 || sd->chatID )
 	if( lv <= 0 || sd->chatID )
 		return 0;
 		return 0;
 
 
-	if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill )
-	{	//GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
+	if( pc_has_permission(sd, PC_PERM_SKILL_UNCONDITIONAL) && sd->skillitem != skill ) {
+		//GMs don't override the skillItem check, otherwise they can use items without them being consumed! [Skotlex]
 		sd->state.arrow_atk = skill_get_ammotype(skill)?1:0; //Need to do arrow state check.
 		sd->state.arrow_atk = skill_get_ammotype(skill)?1:0; //Need to do arrow state check.
 		sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
 		sd->spiritball_old = sd->spiritball; //Need to do Spiritball check.
 		return 1;
 		return 1;
@@ -12920,70 +12920,65 @@ int skill_check_condition_castend(struct map_session_data* sd, short skill, shor
 	if( sd->skillitem == skill ) // Casting finished (Item skill or Hocus-Pocus)
 	if( sd->skillitem == skill ) // Casting finished (Item skill or Hocus-Pocus)
 		return 1;
 		return 1;
 
 
-	if( pc_is90overweight(sd) )
-	{
+	if( pc_is90overweight(sd) ) {
 		clif_skill_fail(sd,skill,USESKILL_FAIL_WEIGHTOVER,0);
 		clif_skill_fail(sd,skill,USESKILL_FAIL_WEIGHTOVER,0);
 		return 0;
 		return 0;
 	}
 	}
 
 
 	// perform skill-specific checks (and actions)
 	// perform skill-specific checks (and actions)
-	switch( skill )
-	{
-	case PR_BENEDICTIO:
-		skill_check_pc_partner(sd, skill, &lv, 1, 1);
-		break;
-	case AM_CANNIBALIZE:
-	case AM_SPHEREMINE:
-	{
-		int c=0;
-		int summons[5] = { 1589, 1579, 1575, 1555, 1590 };
-		//int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
-		int maxcount = (skill==AM_CANNIBALIZE)? 6-lv : skill_get_maxcount(skill,lv);
-		int mob_class = (skill==AM_CANNIBALIZE)? summons[lv-1] :1142;
-		if(battle_config.land_skill_limit && maxcount>0 && (battle_config.land_skill_limit&BL_PC)) {
-			i = map_foreachinmap(skill_check_condition_mob_master_sub ,sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill, &c);
-			if(c >= maxcount ||
-				(skill==AM_CANNIBALIZE && c != i && battle_config.summon_flora&2))
-			{	//Fails when: exceed max limit. There are other plant types already out.
-				clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
-				return 0;
+	switch( skill ) {
+		case PR_BENEDICTIO:
+			skill_check_pc_partner(sd, skill, &lv, 1, 1);
+			break;
+		case AM_CANNIBALIZE:
+		case AM_SPHEREMINE: {
+			int c=0;
+			int summons[5] = { 1589, 1579, 1575, 1555, 1590 };
+			//int summons[5] = { 1020, 1068, 1118, 1500, 1368 };
+			int maxcount = (skill==AM_CANNIBALIZE)? 6-lv : skill_get_maxcount(skill,lv);
+			int mob_class = (skill==AM_CANNIBALIZE)? summons[lv-1] :1142;
+			if(battle_config.land_skill_limit && maxcount>0 && (battle_config.land_skill_limit&BL_PC)) {
+				i = map_foreachinmap(skill_check_condition_mob_master_sub ,sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill, &c);
+				if(c >= maxcount ||
+					(skill==AM_CANNIBALIZE && c != i && battle_config.summon_flora&2))
+				{	//Fails when: exceed max limit. There are other plant types already out.
+					clif_skill_fail(sd,skill,USESKILL_FAIL_LEVEL,0);
+					return 0;
+				}
 			}
 			}
+			break;
 		}
 		}
-		break;
-	}
-	case NC_SILVERSNIPER:
-	case NC_MAGICDECOY:
-		{
-			int c = 0, j;
-			int maxcount = skill_get_maxcount(skill,lv);
-			int mob_class = 2042;
-			if( skill == NC_MAGICDECOY )
-				mob_class = 2043;
-
-			if( battle_config.land_skill_limit && maxcount > 0 && ( battle_config.land_skill_limit&BL_PC ) ) {
-				if( skill == NC_MAGICDECOY ) {
-					for( j = mob_class; j <= 2046; j++ )
-						map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, j, skill, &c);
-				} else
-					map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill, &c);
-				if( c >= maxcount ) {
+		case NC_SILVERSNIPER:
+		case NC_MAGICDECOY: {
+				int c = 0, j;
+				int maxcount = skill_get_maxcount(skill,lv);
+				int mob_class = 2042;
+				if( skill == NC_MAGICDECOY )
+					mob_class = 2043;
+
+				if( battle_config.land_skill_limit && maxcount > 0 && ( battle_config.land_skill_limit&BL_PC ) ) {
+					if( skill == NC_MAGICDECOY ) {
+						for( j = mob_class; j <= 2046; j++ )
+							map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, j, skill, &c);
+					} else
+						map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, mob_class, skill, &c);
+					if( c >= maxcount ) {
+						clif_skill_fail(sd , skill, USESKILL_FAIL_LEVEL, 0);
+						return 0;
+					}
+				}
+			}
+			break;
+		case KO_ZANZOU: {
+				int c = 0;
+				i = map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, 2308, skill, &c);
+				if( c >= skill_get_maxcount(skill,lv) || c != i)
+				{
 					clif_skill_fail(sd , skill, USESKILL_FAIL_LEVEL, 0);
 					clif_skill_fail(sd , skill, USESKILL_FAIL_LEVEL, 0);
 					return 0;
 					return 0;
 				}
 				}
 			}
 			}
-		}
-		break;
-	case KO_ZANZOU:
-		{
-			int c = 0;
-			i = map_foreachinmap(skill_check_condition_mob_master_sub, sd->bl.m, BL_MOB, sd->bl.id, 2308, skill, &c);
-			if( c >= skill_get_maxcount(skill,lv) || c != i)
-			{
-				clif_skill_fail(sd , skill, USESKILL_FAIL_LEVEL, 0);
-				return 0;
-			}
-		}
-		break;
+			break;
 	}
 	}
 
 
 	status = &sd->battle_status;
 	status = &sd->battle_status;
@@ -12995,6 +12990,11 @@ int skill_check_condition_castend(struct map_session_data* sd, short skill, shor
 		return 0;
 		return 0;
 	}
 	}
 
 
+	if( require.weapon && !pc_check_weapontype(sd,require.weapon) ) {
+		clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
+		return 0;
+	}
+	
 	if( require.ammo ) { //Skill requires stuff equipped in the arrow slot.
 	if( require.ammo ) { //Skill requires stuff equipped in the arrow slot.
 		if((i=sd->equip_index[EQI_AMMO]) < 0 || !sd->inventory_data[i] ) {
 		if((i=sd->equip_index[EQI_AMMO]) < 0 || !sd->inventory_data[i] ) {
 			clif_arrow_fail(sd,0);
 			clif_arrow_fail(sd,0);
@@ -13008,8 +13008,7 @@ int skill_check_condition_castend(struct map_session_data* sd, short skill, shor
 			clif_colormes(sd,COLOR_RED,e_msg);
 			clif_colormes(sd,COLOR_RED,e_msg);
 			return 0;
 			return 0;
 		}
 		}
-		if (!(require.ammo&1<<sd->inventory_data[i]->look))
-		{	//Ammo type check. Send the "wrong weapon type" message
+		if (!(require.ammo&1<<sd->inventory_data[i]->look)) { //Ammo type check. Send the "wrong weapon type" message
 			//which is the closest we have to wrong ammo type. [Skotlex]
 			//which is the closest we have to wrong ammo type. [Skotlex]
 			clif_arrow_fail(sd,0); //Haplo suggested we just send the equip-arrows message instead. [Skotlex]
 			clif_arrow_fail(sd,0); //Haplo suggested we just send the equip-arrows message instead. [Skotlex]
 			//clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
 			//clif_skill_fail(sd,skill,USESKILL_FAIL_THIS_WEAPON,0);
@@ -13017,8 +13016,7 @@ int skill_check_condition_castend(struct map_session_data* sd, short skill, shor
 		}
 		}
 	}
 	}
 
 
-	for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i )
-	{
+	for( i = 0; i < MAX_SKILL_ITEM_REQUIRE; ++i ) {
 		if( !require.itemid[i] )
 		if( !require.itemid[i] )
 			continue;
 			continue;
 		index[i] = pc_search_inventory(sd,require.itemid[i]);
 		index[i] = pc_search_inventory(sd,require.itemid[i]);