瀏覽代碼

Bug Fixes
* Fixed Decoration of Music status when equipping the headgear. (bugreport:9342)
* Fixed Warg Dash giving Endure when it shouldn't. (bugreport:9337)
* Fixed Mado Gear skill item requirements. (bugreport:9335)
* Fixed Super Novice Spirit being able to be casted by all classes. (bugreport:9344)
* Fixed Masquerade - Ignorance to work on monsters. (bugreport:8099)
* Fixed Voice of Siren duration depending on level of character. (bugreport:9289)
* Fixed Spirit Sympathy SP requirement reduction when summoning an Element. (bugreport:9329)

aleos89 10 年之前
父節點
當前提交
8b755e5419
共有 9 個文件被更改,包括 139 次插入193 次删除
  1. 10 10
      db/pre-re/skill_require_db.txt
  2. 1 1
      db/re/item_db.txt
  3. 10 10
      db/re/skill_require_db.txt
  4. 1 1
      sql-files/item_db_re.sql
  5. 1 1
      src/map/clif.c
  6. 40 28
      src/map/skill.c
  7. 5 3
      src/map/status.c
  8. 52 118
      src/map/unit.c
  9. 19 21
      src/map/unit.h

+ 10 - 10
db/pre-re/skill_require_db.txt

@@ -681,28 +681,28 @@
 2256,0,0,3:6:9:12:15,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_BOOSTKNUCKLE
 2257,0,0,50,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1549							//NC_PILEBUNKER
 2258,0,0,2:4:6,0,0,0,99,0,0,mado,0,0,6145,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_VULCANARM
-2259,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2139						//NC_FLAMELAUNCHER
+2259,0,0,20,0,0,0,99,0,0,mado,0,0,2139,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_FLAMELAUNCHER
 2260,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,6147,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_COLDSLOWER
 2261,0,0,40:45:50,0,0,0,99,8,1,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_ARMSCANNON
-2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800					//NC_ACCELERATION
+2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,2800,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_ACCELERATION
 2263,0,0,25,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2801						//NC_HOVERING
 2264,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_F_SIDESLIDE
 2265,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_B_SIDESLIDE
 
-2267,0,0,1,0,0,0,99,0,0,mado,0,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2802						//NC_SELFDESTRUCTION
-2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,1,6363,1,6362,1,6361,1,0,0,0,0,0,0,0,0,0,0,6146,2,2803			//NC_SHAPESHIFT
-2269,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2804						//NC_EMERGENCYCOOL
+2267,0,0,1,0,0,0,99,0,0,mado,0,0,2802,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_SELFDESTRUCTION
+2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,3,6363,3,6362,3,6361,3,2803,0,0,0,0,0,0,0,0,0,6146,2,0			//NC_SHAPESHIFT
+2269,0,0,20,0,0,0,99,0,0,mado,0,0,2804,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_EMERGENCYCOOL
 2270,0,0,45,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0								//NC_INFRAREDSCAN
 2271,0,0,30,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_ANALYZE
-2272,0,0,90,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2805						//NC_MAGNETICFIELD
-2273,0,0,90,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2806						//NC_NEUTRALBARRIER
-2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2808				//NC_STEALTHFIELD
-2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,0,0,0,0,0,0,0,0,6146,1,2807			//NC_REPAIR
+2272,0,0,60:70:80,0,0,0,99,0,0,mado,0,0,2805,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_MAGNETICFIELD
+2273,0,0,80:90:100,0,0,0,99,0,0,mado,0,0,2806,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_NEUTRALBARRIER
+2274,0,0,80:100:120,0,0,0,99,0,0,mado,0,0,2808,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0				//NC_STEALTHFIELD
+2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,2807,0,0,0,0,0,0,0,6146,1,0			//NC_REPAIR
 
 2278,0,0,20:22:24:26:28,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0				//NC_AXEBOOMERANG
 2279,0,0,20:22:24:26:28,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_POWERSWING
 2280,20:40:60:80:100,0,18:20:22:24:26,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//NC_AXETORNADO
-2281,0,0,25:30:35:40:45,0,0,0,99,0,0,none,0,0,612,0,615,0,998,1,999,5,0,0,0,0,0,0,0,0,0,0,0,0,0			//NC_SILVERSNIPER
+2281,0,0,25:30:35:40:45,0,0,0,99,0,0,none,0,0,612,0,615,0,998,1,999,2,0,0,0,0,0,0,0,0,0,0,0,0,0			//NC_SILVERSNIPER
 2282,0,0,40:45:50:55:60,0,0,0,99,0,0,none,0,0,612,0,615,0,998,2,7054,1,0,0,0,0,0,0,0,0,0,0,0,0,0		//NC_MAGICDECOY
 2283,0,0,15,0,0,0,99,0,0,none,0,0,6186,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_DISJOINT
 

+ 1 - 1
db/re/item_db.txt

@@ -9480,7 +9480,7 @@
 19863,C_Incubus_Horn,Incubus Horn,4,20,,0,,0,,0,0xFFFFFFFF,63,2,1024,,0,0,156,{},{},{}
 19864,C_Dokebi's_Wig,Dokebi's Wig,4,20,,0,,0,,0,0xFFFFFFFF,63,2,3072,,0,0,302,{},{},{}
 19865,C_Joker_Jester,Joker Jester,4,20,,0,,0,,0,0xFFFFFFFF,63,2,1024,,0,0,89,{},{},{}
-19871,C_DecorationOfMusic_Accessory,Decoration of Music,4,20,,0,,0,,0,0xFFFFFFFF,63,2,2048,,0,0,1074,{ sc_start SC_DECORATION_OF_MUSIC,-1,0; },{},{ sc_end SC_DECORATION_OF_MUSIC; }
+19871,C_DecorationOfMusic_Accessory,Decoration of Music,4,20,,0,,0,,0,0xFFFFFFFF,63,2,2048,,0,0,1074,{},{ sc_start SC_DECORATION_OF_MUSIC,-1,0; },{ sc_end SC_DECORATION_OF_MUSIC; }
 19878,C_Evolved_Drooping_Bunny,Costume Evolved Drooping Bunny,4,0,,0,,,,,0xFFFFFFFF,63,2,1024,,1,,249,{},{},{}
 19882,C_Flowerpot_Mask,Costume Flowerpot Mask,4,0,,0,,,,,0xFFFFFFFF,63,2,4096,,1,,,{/*TODO: View ID*/},{},{}
 19883,C_Cyclops_Glasses,Costume Cyclops Glasses,4,0,,0,,,,,0xFFFFFFFF,63,2,2048,,1,,1087,{},{},{}

+ 10 - 10
db/re/skill_require_db.txt

@@ -681,28 +681,28 @@
 2256,0,0,3:6:9:12:15,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_BOOSTKNUCKLE
 2257,0,0,50,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1549							//NC_PILEBUNKER
 2258,0,0,2:4:6,0,0,0,99,0,0,mado,0,0,6145,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_VULCANARM
-2259,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2139						//NC_FLAMELAUNCHER
+2259,0,0,20,0,0,0,99,0,0,mado,0,0,2139,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_FLAMELAUNCHER
 2260,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,6147,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_COLDSLOWER
 2261,0,0,40:45:50,0,0,0,99,8,1,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_ARMSCANNON
-2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2800					//NC_ACCELERATION
+2262,0,0,20:40:60,0,0,0,99,0,0,mado,0,0,2800,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_ACCELERATION
 2263,0,0,25,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2801						//NC_HOVERING
 2264,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_F_SIDESLIDE
 2265,0,0,5,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_B_SIDESLIDE
 
-2267,0,0,1,0,0,0,99,0,0,mado,0,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2802						//NC_SELFDESTRUCTION
-2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,1,6363,1,6362,1,6361,1,0,0,0,0,0,0,0,0,0,0,6146,2,2803			//NC_SHAPESHIFT
-2269,0,0,20,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2804						//NC_EMERGENCYCOOL
+2267,0,0,1,0,0,0,99,0,0,mado,0,0,2802,0,6146,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_SELFDESTRUCTION
+2268,0,0,100,0,0,0,99,0,0,mado,0,0,6360,3,6363,3,6362,3,6361,3,2803,0,0,0,0,0,0,0,0,0,6146,2,0			//NC_SHAPESHIFT
+2269,0,0,20,0,0,0,99,0,0,mado,0,0,2804,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_EMERGENCYCOOL
 2270,0,0,45,0,0,0,99,0,0,mado,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0								//NC_INFRAREDSCAN
 2271,0,0,30,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_ANALYZE
-2272,0,0,90,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2805						//NC_MAGNETICFIELD
-2273,0,0,90,0,0,0,99,0,0,mado,0,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2806						//NC_NEUTRALBARRIER
-2274,0,0,100:150:200,0,0,0,99,0,0,mado,0,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2808				//NC_STEALTHFIELD
-2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,0,0,0,0,0,0,0,0,6146,1,2807			//NC_REPAIR
+2272,0,0,60:70:80,0,0,0,99,0,0,mado,0,0,2805,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_MAGNETICFIELD
+2273,0,0,80:90:100,0,0,0,99,0,0,mado,0,0,2806,0,6146,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0						//NC_NEUTRALBARRIER
+2274,0,0,80:100:120,0,0,0,99,0,0,mado,0,0,2808,0,6146,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0				//NC_STEALTHFIELD
+2275,0,0,25:30:35:40:45,0,0,0,99,0,0,mado,0,0,12392,1,12392,1,12393,1,12393,1,12394,1,2807,0,0,0,0,0,0,0,6146,1,0			//NC_REPAIR
 
 2278,0,0,20:22:24:26:28,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0				//NC_AXEBOOMERANG
 2279,0,0,20:22:24:26:28,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0					//NC_POWERSWING
 2280,20:40:60:80:100,0,18:20:22:24:26,0,0,0,6:7,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0	//NC_AXETORNADO
-2281,0,0,25:30:35:40:45,0,0,0,99,0,0,none,0,0,612,0,615,0,998,1,999,5,0,0,0,0,0,0,0,0,0,0,0,0,0			//NC_SILVERSNIPER
+2281,0,0,25:30:35:40:45,0,0,0,99,0,0,none,0,0,612,0,615,0,998,1,999,2,0,0,0,0,0,0,0,0,0,0,0,0,0			//NC_SILVERSNIPER
 2282,0,0,40:45:50:55:60,0,0,0,99,0,0,none,0,0,612,0,615,0,998,2,7054,1,0,0,0,0,0,0,0,0,0,0,0,0,0		//NC_MAGICDECOY
 2283,0,0,15,0,0,0,99,0,0,none,0,0,6186,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0							//NC_DISJOINT
 

+ 1 - 1
sql-files/item_db_re.sql

@@ -9511,7 +9511,7 @@ REPLACE INTO `item_db_re` VALUES (19862,'C_Succubus_Horn','Succubus Horn',4,20,N
 REPLACE INTO `item_db_re` VALUES (19863,'C_Incubus_Horn','Incubus Horn',4,20,NULL,0,NULL,0,NULL,0,0xFFFFFFFF,63,2,1024,NULL,'0',0,156,NULL,NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (19864,'C_Dokebi\'s_Wig','Dokebi\'s Wig',4,20,NULL,0,NULL,0,NULL,0,0xFFFFFFFF,63,2,3072,NULL,'0',0,302,NULL,NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (19865,'C_Joker_Jester','Joker Jester',4,20,NULL,0,NULL,0,NULL,0,0xFFFFFFFF,63,2,1024,NULL,'0',0,89,NULL,NULL,NULL);
-REPLACE INTO `item_db_re` VALUES (19871,'C_DecorationOfMusic_Accessory','Decoration of Music',4,20,NULL,0,NULL,0,NULL,0,0xFFFFFFFF,63,2,2048,NULL,'0',0,1074,'sc_start SC_DECORATION_OF_MUSIC,-1,0;',NULL,'sc_end SC_DECORATION_OF_MUSIC;');
+REPLACE INTO `item_db_re` VALUES (19871,'C_DecorationOfMusic_Accessory','Decoration of Music',4,20,NULL,0,NULL,0,NULL,0,0xFFFFFFFF,63,2,2048,NULL,'0',0,1074,NULL,'sc_start SC_DECORATION_OF_MUSIC,-1,0;','sc_end SC_DECORATION_OF_MUSIC;');
 REPLACE INTO `item_db_re` VALUES (19878,'C_Evolved_Drooping_Bunny','Costume Evolved Drooping Bunny',4,0,NULL,0,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,1024,NULL,'1',NULL,249,NULL,NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (19882,'C_Flowerpot_Mask','Costume Flowerpot Mask',4,0,NULL,0,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,4096,NULL,'1',NULL,NULL,'/*TODO: View ID*/',NULL,NULL);
 REPLACE INTO `item_db_re` VALUES (19883,'C_Cyclops_Glasses','Costume Cyclops Glasses',4,0,NULL,0,NULL,NULL,NULL,NULL,0xFFFFFFFF,63,2,2048,NULL,'1',NULL,1087,NULL,NULL,NULL);

+ 1 - 1
src/map/clif.c

@@ -10365,8 +10365,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
 		if (battle_config.idletime_option&IDLE_SIT)
 			sd->idletime = last_tick;
 
-		skill_sit(sd, 1);
 		pc_setsit(sd);
+		skill_sit(sd, 1);
 		clif_sitting(&sd->bl);
 	break;
 	case 0x03: // standup

+ 40 - 28
src/map/skill.c

@@ -8061,7 +8061,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case SL_SUPERNOVICE:
 	case SL_WIZARD:
 		//NOTE: here, 'type' has the value of the associated MAPID, not of the SC_SPIRIT constant.
-		if (sd && !(dstsd && ((skill_id != SL_SUPERNOVICE && (dstsd->class_&MAPID_UPPERMASK) == type) || (skill_id == SL_SUPERNOVICE && !(dstsd->class_&JOBL_SUPER_NOVICE))))) {
+		if (sd && dstsd && !((dstsd->class_&MAPID_UPPERMASK) == type) || (skill_id == SL_SUPERNOVICE && (dstsd->class_&JOBL_SUPER_NOVICE))) {
 			clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 			break;
 		}
@@ -9016,7 +9016,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			return 0;
 		}
 		if( sd && pc_isridingwug(sd) ) {
-			clif_skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,bl,type,100,skill_lv,unit_getdir(bl),0,0,1));
+			clif_skill_nodamage(src,bl,skill_id,skill_lv,sc_start4(src,bl,type,100,skill_lv,unit_getdir(bl),0,0,0));
 			clif_walkok(sd);
 		}
 		break;
@@ -9162,11 +9162,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			rate = cap_value(rate, skill_lv + sstatus->dex / 20, 100);
 			if (clif_skill_nodamage(src,bl,skill_id,0,sc_start(src,bl,type,rate,skill_lv,skill_get_time(skill_id,skill_lv)))) {
 				int sp = 100 * skill_lv;
-				if( dstmd ) sp = dstmd->level * 2;
-				if( !dstmd && status_zap(bl,0,sp) )
-					status_heal(src,0,sp/2,3);
-			}
-			else if( sd ) clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
+
+				if( dstmd )
+					sp = dstmd->level;
+				if( !dstmd )
+					status_zap(bl, 0, sp);
+
+				status_heal(src, 0, sp / 2, 3);
+			} else if( sd )
+				clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 		} else if( sd )
 			clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 		break;
@@ -9458,22 +9462,28 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 
 	case WM_SIRCLEOFNATURE:
-		flag |= BCT_SELF|BCT_PARTY|BCT_GUILD;
-	case WM_VOICEOFSIREN:
-	{
-		int rate = 100;
-		if( skill_id != WM_SIRCLEOFNATURE ) {
-			rate = 6 * skill_lv + ((sd) ? pc_checkskill(sd,WM_LESSON)*2 + sd->status.job_level/2 : skill_get_max(WM_LESSON));
-			flag &= ~BCT_SELF;
+		if( flag&1 )
+			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv));
+		else {
+			map_foreachinrange(skill_area_sub,src,skill_get_splash(skill_id,skill_lv),BL_PC,src,skill_id,skill_lv,tick,flag|BCT_ALL|1,skill_castend_nodamage_id);
+			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 		}
+		break;
+
+	case WM_VOICEOFSIREN:
 		if( flag&1 ) {
-			sc_start2(src,bl,type,rate,skill_lv,(skill_id==WM_VOICEOFSIREN)?src->id:0,skill_get_time(skill_id,skill_lv));
+			tick = (status_get_lv(bl) > 150 ? 150 : status_get_lv(bl)) / 10 + (dstsd ? (dstsd->status.job_level > 50 ? 50 : dstsd->status.job_level) / 5 : 0);
+			sc_start2(src,bl,type,100,skill_lv,src->id,skill_get_time(skill_id,skill_lv) - (1000 * tick));
 		} else {
-			map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv),(skill_id==WM_VOICEOFSIREN)?BL_CHAR|BL_SKILL:BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
-			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
+			int rate = 6 * skill_lv + ((sd) ? pc_checkskill(sd,WM_LESSON) * 2 + (sd->status.job_level > 50 ? 50 : sd->status.job_level) / 2 : skill_get_max(WM_LESSON));
+
+			if (rnd()%100 < rate) {
+				map_foreachinrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv), BL_CHAR|BL_SKILL, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+				clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
+			}
 		}
 		break;
-	}
+
 	case WM_GLOOMYDAY:
 		clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 		if( dstsd && ( pc_checkskill(dstsd,KN_BRANDISHSPEAR) || pc_checkskill(dstsd,LK_SPIRALPIERCE) ||
@@ -14698,7 +14708,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 		}
 	}
 
-	//check if equiped item
+	//check if equipped item
 	if (require.eqItem_count) {
 		for (i = 0; i < require.eqItem_count; i++) {
 			uint16 reqeqit = require.eqItem[i];
@@ -15268,14 +15278,11 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 				req.spiritball = 0;
 			break;
 		case MO_EXTREMITYFIST:
-			if( sc )
-			{
+			if( sc ) {
 				if( sc->data[SC_BLADESTOP] )
 					req.spiritball--;
-				else if( sc->data[SC_COMBO] )
-				{
-					switch( sc->data[SC_COMBO]->val1 )
-					{
+				else if( sc->data[SC_COMBO] ) {
+					switch( sc->data[SC_COMBO]->val1 ) {
 						case MO_COMBOFINISH:
 							req.spiritball = 4;
 							break;
@@ -15286,7 +15293,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 							req.spiritball = sd->spiritball?sd->spiritball:1;
 							break;
 					}
-				}else if( sc->data[SC_RAISINGDRAGON] && sd->spiritball > 5)
+				} else if( sc->data[SC_RAISINGDRAGON] && sd->spiritball > 5)
 					req.spiritball = sd->spiritball; // must consume all regardless of the amount required
 			}
 			break;
@@ -15303,8 +15310,12 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 		case SO_SUMMON_AGNI:
 		case SO_SUMMON_AQUA:
 		case SO_SUMMON_VENTUS:
-		case SO_SUMMON_TERA:
-			req.sp -= req.sp * (5 + 5 * pc_checkskill(sd,SO_EL_SYMPATHY)) / 100;
+		case SO_SUMMON_TERA: {
+				int spirit_sympathy = pc_checkskill(sd,SO_EL_SYMPATHY);
+
+				if( spirit_sympathy )
+					req.sp -= req.sp * (5 + 5 * spirit_sympathy) / 100;
+			}
 			break;
 		case SO_PSYCHIC_WAVE:
 			if( sc && (sc->data[SC_HEATER_OPTION] || sc->data[SC_COOLER_OPTION] || sc->data[SC_CURSED_SOIL_OPTION] || sc->data[SC_BLAST_OPTION]) )
@@ -15315,6 +15326,7 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, uint16
 	//Check if player is using the copied skill [Cydh]
 	if (sd->status.skill[idx].flag == SKILL_FLAG_PLAGIARIZED) {
 		uint16 req_opt = skill_db[idx].copyable.req_opt;
+
 		if (req_opt&0x0001) req.hp = 0;
 		if (req_opt&0x0002) req.mhp = 0;
 		if (req_opt&0x0004) req.sp = 0;

+ 5 - 3
src/map/status.c

@@ -642,7 +642,7 @@ void initChangeTables(void)
 	/* Ranger */
 	set_sc( RA_FEARBREEZE		, SC_FEARBREEZE		, SI_FEARBREEZE		, SCB_NONE );
 	set_sc( RA_ELECTRICSHOCKER	, SC_ELECTRICSHOCKER	, SI_ELECTRICSHOCKER	, SCB_NONE );
-	set_sc( RA_WUGDASH		, SC_WUGDASH		, SI_WUGDASH		, SCB_SPEED );
+	set_sc( RA_WUGDASH			, SC_WUGDASH		, SI_WUGDASH		, SCB_SPEED|SCB_DSPD );
 	set_sc( RA_WUGBITE          , SC_BITE           , SI_WUGBITE        , SCB_NONE );
 	set_sc( RA_CAMOUFLAGE		, SC_CAMOUFLAGE		, SI_CAMOUFLAGE		, SCB_SPEED );
 	add_sc( RA_MAGENTATRAP		, SC_ELEMENTALCHANGE	);
@@ -10305,8 +10305,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		case SC_RUN:
 			{
 				struct unit_data *ud = unit_bl2ud(bl);
+
 				if( ud )
-					ud->state.running = unit_run(bl);
+					ud->state.running = unit_run(bl, NULL, SC_RUN);
 			}
 			break;
 		case SC_BOSSMAPINFO:
@@ -10321,8 +10322,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		case SC_WUGDASH:
 			{
 				struct unit_data *ud = unit_bl2ud(bl);
+
 				if( ud )
-					ud->state.running = unit_wugdash(bl, sd);
+					ud->state.running = unit_run(bl, sd, SC_WUGDASH);
 			}
 			break;
 		case SC_COMBO:

+ 52 - 118
src/map/unit.c

@@ -474,9 +474,8 @@ static int unit_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data
 		ud->walktimer = add_timer(tick+i,unit_walktoxy_timer,id,i);
 		if( md && DIFF_TICK(tick,md->dmgtick) < 3000 ) // Not required not damaged recently
 			clif_move(ud);
-	} else if(ud->state.running) {
-		// Keep trying to run.
-		if ( !(unit_run(bl) || unit_wugdash(bl,sd)) )
+	} else if(ud->state.running) { // Keep trying to run.
+		if ( !(unit_run(bl, NULL, SC_RUN) || unit_run(bl, sd, SC_WUGDASH)) )
 			ud->state.running = 0;
 	} else if (!ud->stepaction && ud->target_to) {
 		// Update target trajectory.
@@ -748,160 +747,95 @@ int unit_walktobl(struct block_list *bl, struct block_list *tbl, int range, unsi
 }
 
 /**
- * Set a unit to run, checking for obstacles
- * @param bl: Object that is running
- * @return 1: Success 0: Fail
+ * Called by unit_run when an object is hit.
+ * @param sd Required only when using SC_WUGDASH
  */
-int unit_run(struct block_list *bl)
-{
-	struct status_change *sc = status_get_sc(bl);
-	short to_x,to_y,dir_x,dir_y;
-	int lv;
-	int i;
-
-	if (!(sc && sc->data[SC_RUN]))
-		return 0;
-
-	if (!unit_can_move(bl)) {
-		status_change_end(bl, SC_RUN, INVALID_TIMER);
+void unit_run_hit(struct block_list *bl, struct status_change *sc, struct map_session_data *sd, enum sc_type type) {
+	int lv = sc->data[type]->val1;
 
-		return 0;
-	}
-
-	lv = sc->data[SC_RUN]->val1;
-	dir_x = dirx[sc->data[SC_RUN]->val2];
-	dir_y = diry[sc->data[SC_RUN]->val2];
-
-	// Determine destination cell
-	to_x = bl->x;
-	to_y = bl->y;
-	for(i = 0; i < AREA_SIZE; i++) {
-		if(!map_getcell(bl->m,to_x+dir_x,to_y+dir_y,CELL_CHKPASS))
-			break;
-
-		// If sprinting and there's a PC/Mob/NPC, block the path [Kevin]
-		if(sc->data[SC_RUN] && map_count_oncell(bl->m, to_x+dir_x, to_y+dir_y, BL_PC|BL_MOB|BL_NPC))
-			break;
-
-		to_x += dir_x;
-		to_y += dir_y;
-	}
-
-	if( (to_x == bl->x && to_y == bl->y ) || (to_x == (bl->x+1) || to_y == (bl->y+1)) || (to_x == (bl->x-1) || to_y == (bl->y-1))) {
-		// If you can't run forward, you must be next to a wall, so bounce back. [Skotlex]
+	// If you can't run forward, you must be next to a wall, so bounce back. [Skotlex]
+	if (type == SC_RUN)
 		clif_status_change(bl, SI_BUMP, 1, 0, 0, 0, 0);
 
-		// Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
-		unit_bl2ud(bl)->state.running = 0;
-		status_change_end(bl, SC_RUN, INVALID_TIMER);
+	// Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
+	unit_bl2ud(bl)->state.running = 0;
+	status_change_end(bl, type, INVALID_TIMER);
 
-		skill_blown(bl,bl,skill_get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
+	if (type == SC_RUN) {
+		skill_blown(bl, bl, skill_get_blewcount(TK_RUN, lv), unit_getdir(bl), 0);
 		clif_status_change(bl, SI_BUMP, 0, 0, 0, 0, 0);
-
-		return 0;
-	}
-
-	if (unit_walktoxy(bl, to_x, to_y, 1))
-		return 1;
-
-	// There must be an obstacle nearby. Attempt walking one cell at a time.
-	do {
-		to_x -= dir_x;
-		to_y -= dir_y;
-	} while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1));
-
-	if (i == 0) {
-		// Copy-paste from above
-		clif_status_change(bl, SI_BUMP, 1, 0, 0, 0, 0);
-
-		// Set running to 0 beforehand so status_change_end knows not to enable spurt [Kevin]
-		unit_bl2ud(bl)->state.running = 0;
-		status_change_end(bl, SC_RUN, INVALID_TIMER);
-
-		skill_blown(bl,bl,skill_get_blewcount(TK_RUN,lv),unit_getdir(bl),0);
+	} else if (sd) {
 		clif_fixpos(bl);
-		clif_status_change(bl, SI_BUMP, 0, 0, 0, 0, 0);
-
-		return 0;
+		skill_castend_damage_id(bl, &sd->bl, RA_WUGDASH, lv, gettick(), SD_LEVEL);
 	}
-
-	return 1;
+	return;
 }
 
 /**
- * Character movement with Warg Dash
- * @author [Jobbie/3CeAM]
- * @param bl: Object that is dashing
- * @param sd: Player
- * @return 1: Success 0: Fail
+ * Set a unit to run, checking for obstacles
+ * @param bl: Object that is running
+ * @param sd: Required only when using SC_WUGDASH
+ * @return true: Success (Finished running) false: Fail (Hit an object/Couldn't run)
  */
-int unit_wugdash(struct block_list *bl, struct map_session_data *sd)
+bool unit_run(struct block_list *bl, struct map_session_data *sd, enum sc_type type)
 {
-	struct status_change *sc = status_get_sc(bl);
-	short to_x,to_y,dir_x,dir_y;
-	int lv, i;
+	struct status_change *sc;
+	short to_x, to_y, dir_x, dir_y;
+	int i;
 
-	if (!(sc && sc->data[SC_WUGDASH]))
-		return 0;
+	nullpo_retr(false, bl);
 
-	nullpo_ret(sd); //FIXME do we really need that check since we rechecking afterward
-	nullpo_ret(bl);
+	sc = status_get_sc(bl);
+
+	if (!(sc && sc->data[SC_RUN]))
+		return false;
 
 	if (!unit_can_move(bl)) {
-		status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
-		return 0;
+		status_change_end(bl, type, INVALID_TIMER);
+		return false;
 	}
 
-	lv = sc->data[SC_WUGDASH]->val1;
-	dir_x = dirx[sc->data[SC_WUGDASH]->val2];
-	dir_y = diry[sc->data[SC_WUGDASH]->val2];
+	dir_x = dirx[sc->data[type]->val2];
+	dir_y = diry[sc->data[type]->val2];
 
+	// Determine destination cell
 	to_x = bl->x;
 	to_y = bl->y;
+
+	// Search for available path
 	for(i = 0; i < AREA_SIZE; i++) {
-		if(!map_getcell(bl->m,to_x+dir_x,to_y+dir_y,CELL_CHKPASS))
+		if(!map_getcell(bl->m, to_x + dir_x, to_y + dir_y, CELL_CHKPASS))
 			break;
 
-		if(sc->data[SC_WUGDASH] && map_count_oncell(bl->m, to_x+dir_x, to_y+dir_y, BL_PC|BL_MOB|BL_NPC))
+		// If sprinting and there's a PC/Mob/NPC, block the path [Kevin]
+		if(map_count_oncell(bl->m, to_x + dir_x, to_y + dir_y, BL_PC|BL_MOB|BL_NPC))
 			break;
 
 		to_x += dir_x;
 		to_y += dir_y;
 	}
 
-	if(to_x == bl->x && to_y == bl->y) {
-		unit_bl2ud(bl)->state.running = 0;
-		status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
-
-		if( sd ) {
-			clif_fixpos(bl);
-			skill_castend_damage_id(bl, &sd->bl, RA_WUGDASH, lv, gettick(), SD_LEVEL);
-		}
-
-		return 0;
+	// Can't run forward.
+	if( (to_x == bl->x && to_y == bl->y ) || (to_x == (bl->x + 1) || to_y == (bl->y + 1)) || (to_x == (bl->x - 1) || to_y == (bl->y - 1))) {
+		unit_run_hit(bl, sc, sd, type);
+		return false;
 	}
 
 	if (unit_walktoxy(bl, to_x, to_y, 1))
-		return 1;
+		return true;
 
+	// There must be an obstacle nearby. Attempt walking one cell at a time.
 	do {
 		to_x -= dir_x;
 		to_y -= dir_y;
 	} while (--i > 0 && !unit_walktoxy(bl, to_x, to_y, 1));
 
-	if (i==0) {
-		unit_bl2ud(bl)->state.running = 0;
-		status_change_end(bl,SC_WUGDASH,INVALID_TIMER);
-
-		if( sd ) {
-			clif_fixpos(bl);
-			skill_castend_damage_id(bl, &sd->bl, RA_WUGDASH, lv, gettick(), SD_LEVEL);
-		}
-
-		return 0;
+	if (i == 0) {
+		unit_run_hit(bl, sc, sd, type);
+		return false;
 	}
 
-	return 1;
+	return true;
 }
 
 /**
@@ -1360,11 +1294,11 @@ int unit_resume_running(int tid, unsigned int tick, int id, intptr_t data)
 {
 
 	struct unit_data *ud = (struct unit_data *)data;
-	TBL_PC * sd = map_id2sd(id);
+	TBL_PC *sd = map_id2sd(id);
 
-	if(sd && pc_isridingwug(sd))
+	if (sd && pc_isridingwug(sd))
 		clif_skill_nodamage(ud->bl,ud->bl,RA_WUGDASH,ud->skill_lv,
-			sc_start4(ud->bl,ud->bl,status_skill2sc(RA_WUGDASH),100,ud->skill_lv,unit_getdir(ud->bl),0,0,1));
+			sc_start4(ud->bl,ud->bl,status_skill2sc(RA_WUGDASH),100,ud->skill_lv,unit_getdir(ud->bl),0,0,0));
 	else
 		clif_skill_nodamage(ud->bl,ud->bl,TK_RUN,ud->skill_lv,
 			sc_start4(ud->bl,ud->bl,status_skill2sc(TK_RUN),100,ud->skill_lv,unit_getdir(ud->bl),0,0,0));

+ 19 - 21
src/map/unit.h

@@ -19,24 +19,24 @@ extern const short diry[8]; ///lookup to know where will move to y according dir
 
 struct unit_data {
 	struct block_list *bl; ///link to owner object BL_PC|BL_MOB|BL_PET|BL_NPC|BL_HOM|BL_MER|BL_ELEM
-	struct walkpath_data walkpath; 
+	struct walkpath_data walkpath;
 	struct skill_timerskill *skilltimerskill[MAX_SKILLTIMERSKILL];
 	struct skill_unit_group *skillunit[MAX_SKILLUNITGROUP];
 	struct skill_unit_group_tickset skillunittick[MAX_SKILLUNITGROUPTICKSET];
 	short attacktarget_lv;
-	short to_x,to_y;
-	short skillx,skilly;
-	uint16 skill_id,skill_lv;
-	int   skilltarget;
-	int   skilltimer;
-	int   target;
-	int   target_to;
-	int   attacktimer;
-	int   walktimer;
-	int   chaserange;
-	bool  stepaction; //Action should be executed on step [Playtester]
-	int   steptimer; //Timer that triggers the action [Playtester]
-	uint16 stepskill_id,stepskill_lv; //Remembers skill that should be casted on step [Playtester]
+	short to_x, to_y;
+	short skillx, skilly;
+	uint16 skill_id, skill_lv;
+	int skilltarget;
+	int skilltimer;
+	int target;
+	int target_to;
+	int attacktimer;
+	int walktimer;
+	int chaserange;
+	bool stepaction; //Action should be executed on step [Playtester]
+	int steptimer; //Timer that triggers the action [Playtester]
+	uint16 stepskill_id, stepskill_lv; //Remembers skill that should be casted on step [Playtester]
 	unsigned int attackabletime;
 	unsigned int canact_tick;
 	unsigned int canmove_tick;
@@ -77,16 +77,14 @@ struct view_data {
 // PC, MOB, PET
 
 // Does walk action for unit
-int unit_walktoxy( struct block_list *bl, short x, short y, unsigned char flag);
-int unit_walktobl( struct block_list *bl, struct block_list *target, int range, unsigned char flag);
-int unit_run(struct block_list *bl);
+int unit_walktoxy(struct block_list *bl, short x, short y, unsigned char flag);
+int unit_walktobl(struct block_list *bl, struct block_list *target, int range, unsigned char flag);
+void unit_run_hit(struct block_list *bl, struct status_change *sc, struct map_session_data *sd, enum sc_type type);
+bool unit_run(struct block_list *bl, struct map_session_data *sd, enum sc_type type);
 int unit_calc_pos(struct block_list *bl, int tx, int ty, uint8 dir);
 int unit_delay_walktoxy_timer(int tid, unsigned int tick, int id, intptr_t data);
 int unit_delay_walktobl_timer(int tid, unsigned int tick, int id, intptr_t data);
 
-// Ranger
-int unit_wugdash(struct block_list *bl, struct map_session_data *sd);
-
 // Causes the target object to stop moving.
 int unit_stop_walking(struct block_list *bl,int type);
 int unit_can_move(struct block_list *bl);
@@ -98,7 +96,7 @@ int unit_escape(struct block_list *bl, struct block_list *target, short dist);
 // Instant unit changes
 int unit_movepos(struct block_list *bl, short dst_x, short dst_y, int easy, bool checkpath);
 int unit_warp(struct block_list *bl, short map, short x, short y, clr_type type);
-int unit_setdir(struct block_list *bl,unsigned char dir);
+int unit_setdir(struct block_list *bl, unsigned char dir);
 uint8 unit_getdir(struct block_list *bl);
 int unit_blown(struct block_list* bl, int dx, int dy, int count, int flag);