From e901cc96b0095e523bae56da43766c9c821e6a91 Mon Sep 17 00:00:00 2001
From: shennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>
Date: Sat, 18 Feb 2012 17:34:59 +0000
Subject: Initial Support for Shura and a few adjustments here and there. -
 credits to 3ceam for the base. - should you step by any bugs let us know,
 http://rathena.org/board/tracker

git-svn-id: https://rathena.svn.sourceforge.net/svnroot/rathena/trunk@15606 54d463be-8e91-2dee-dedb-b68131a5f0ec
---
 src/map/battle.c |  70 ++++++++++--
 src/map/map.c    |  67 ++++++++++++
 src/map/map.h    |   1 +
 src/map/skill.c  | 322 +++++++++++++++++++++++++++++++++++++++++++------------
 src/map/status.c |  70 +++++++++---
 src/map/unit.c   |   4 +-
 6 files changed, 441 insertions(+), 93 deletions(-)

(limited to 'src')

diff --git a/src/map/battle.c b/src/map/battle.c
index 3292f55ee..3ca8480b4 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -2119,6 +2119,52 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 				case LG_HESPERUSLIT:
 					skillratio += 120 * skill_lv - 100;
 					break;
+				case SR_DRAGONCOMBO:
+					skillratio += 40 * skill_lv;
+					break;
+				case SR_SKYNETBLOW:
+					skillratio += 80 * skill_lv - 100 + ( sstatus->agi * 4 );
+					break;
+				case SR_EARTHSHAKER:
+					skillratio += 50 * skill_lv - 50;// Need to code a check to make the ratio 3x when hitting a hidden player. [Rytech]
+					break;
+				case SR_FALLENEMPIRE:
+					skillratio += 150 * skill_lv; // Need official on how much enemy players weight affects damage. [Rytech]
+					//if( tsd && tsd->weight )
+					//	skillratio = (100 + 150 * skill_lv) * tsd->weight / 10000;
+					//else
+					//	skillratio = (100 + 150 * skill_lv) * 600 / 100;
+					break;
+				case SR_TIGERCANNON:
+						skillratio = 2000 + ( sstatus->hp * ( 10 + 2 * skill_lv ) / 100 );
+					break;
+				case SR_RAMPAGEBLASTER:
+					if( sc && sc->data[SC_EXPLOSIONSPIRITS] )
+						skillratio += 40 * skill_lv * (sd?sd->spiritball_old:5) - 100;
+					else
+						skillratio += 20 * skill_lv * (sd?sd->spiritball_old:5) - 100;
+					break;
+				case SR_KNUCKLEARROW:
+					if( wflag&4 )
+						skillratio = 150 * skill_lv; //+Knockback Damage (Must check and test. [Rytech])
+					else
+						skillratio += 400 + (100 * skill_lv);
+					break;
+				case SR_WINDMILL:
+					skillratio += 150;
+					break;
+				case SR_GATEOFHELL:
+					skillratio += 500 * skill_lv -100;
+					break;
+				case SR_GENTLETOUCH_QUIET:
+					skillratio += 100 * skill_lv - 100 + sstatus->dex;
+					break;
+				case SR_HOWLINGOFLION:
+					skillratio += 300 * skill_lv - 100;
+					break;
+				case SR_RIDEINLIGHTNING:
+					skillratio += 200 * skill_lv -100;
+					break;
 			}
 
 			ATK_RATE(skillratio);
@@ -2147,24 +2193,21 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 				case NJ_SYURIKEN:
 					ATK_ADD(4*skill_lv);
 					break;
-				/**
-				 * Ranger
-				 **/
 				case RA_WUGDASH:
 				case RA_WUGSTRIKE:
 				case RA_WUGBITE:
 					if(sd)
 						ATK_ADD(30*pc_checkskill(sd, RA_TOOTHOFWUG));
 					break;
-				/**
-				 * Royal Guard
-				 **/
 				case LG_RAYOFGENESIS:
 					if( sc && sc->data[SC_BANDING] ) {// Increase only if the RG is under Banding.
 						short lv = (short)skill_lv;
 						ATK_ADDRATE( 190 * ((sd) ? skill_check_pc_partner(sd,(short)skill_num,&lv,skill_get_splash(skill_num,skill_lv),0) : 1));
 					}
 					break;
+				case SR_GATEOFHELL:
+					ATK_ADD (sstatus->max_hp - status_get_hp(src));//Will have to add the consumed SP part to the formula in the future. [Rytech]
+					break;
 			}
 		}
 		//Div fix.
@@ -2205,6 +2248,14 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src,struct blo
 				if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND )
 					ATK_ADDRATE(50);
 				break;
+			case SR_EARTHSHAKER:
+				if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED]) )
+					ATK_ADDRATE(150+150*skill_lv);
+				break;
+			case SR_RIDEINLIGHTNING:
+				if( (sstatus->rhw.ele) == ELE_WIND || (sstatus->lhw.ele) == ELE_WIND )
+					ATK_ADDRATE(skill_lv*5);
+				break;
 		}
 		
 		if( sd )
@@ -3969,6 +4020,13 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 				if( src != target )// Don't reflect your own damage (Grand Cross)
 					map_foreachinshootrange(battle_damage_area,target,skill_get_splash(LG_REFLECTDAMAGE,1),BL_CHAR,tick,target,wd.amotion,wd.dmotion,rdamage,tstatus->race,0);
 			} else {
+				if( tsc && tsc->data[SC_CRESCENTELBOW] ) {	// Deal rdamage to src and 10% damage back to target.
+					clif_skill_nodamage(target,target,SR_CRESCENTELBOW_AUTOSPELL,tsc->data[SC_CRESCENTELBOW]->val1,1);
+					skill_blown(target,src,skill_get_blewcount(SR_CRESCENTELBOW_AUTOSPELL,tsc->data[SC_CRESCENTELBOW]->val1),unit_getdir(src),0);
+					status_damage(NULL,target,rdamage/10,0,0,1);
+					clif_damage(target, target, tick, wd.amotion, wd.dmotion, rdamage/10, wd.div_ , wd.type, wd.damage2);
+					status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER);
+				}
 				rdelay = clif_damage(src, src, tick, wd.amotion, sstatus->dmotion, rdamage, 1, 4, 0);
 				//Use Reflect Shield to signal this kind of skill trigger. [Skotlex]
 				skill_additional_effect(target,src,CR_REFLECTSHIELD,1,BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
diff --git a/src/map/map.c b/src/map/map.c
index b1fa2d132..0ae05d3f4 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -692,7 +692,74 @@ int map_foreachinarea(int (*func)(struct block_list*,va_list), int m, int x0, in
 	bl_list_count = blockcount;
 	return returnCount;	//[Skotlex]
 }
+/*==========================================
+ * Adapted from forcountinarea for an easier invocation. [pakpil]
+ *------------------------------------------*/
+int map_forcountinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int count, int type, ...)
+{
+	int bx,by,m;
+	int returnCount =0;	//total sum of returned values of func() [Skotlex]
+	struct block_list *bl;
+	int blockcount=bl_list_count,i;
+	int x0,x1,y0,y1;
+
+	m = center->m;
+	x0 = max(center->x-range, 0);
+	y0 = max(center->y-range, 0);
+	x1 = min(center->x+range, map[m].xs-1);
+	y1 = min(center->y+range, map[m].ys-1);
+	
+	if (type&~BL_MOB)
+		for (by = y0 / BLOCK_SIZE; by <= y1 / BLOCK_SIZE; by++) {
+			for(bx = x0 / BLOCK_SIZE; bx <= x1 / BLOCK_SIZE; bx++) {
+				for( bl = map[m].block[bx+by*map[m].bxs] ; bl != NULL ; bl = bl->next )
+				{
+					if( bl->type&type
+						&& bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1
+#ifdef CIRCULAR_AREA
+						&& check_distance_bl(center, bl, range)
+#endif
+					  	&& bl_list_count<BL_LIST_MAX)
+						bl_list[bl_list_count++]=bl;
+				}
+			}
+		}
+	if(type&BL_MOB)
+		for(by=y0/BLOCK_SIZE;by<=y1/BLOCK_SIZE;by++){
+			for(bx=x0/BLOCK_SIZE;bx<=x1/BLOCK_SIZE;bx++){
+				for( bl = map[m].block_mob[bx+by*map[m].bxs] ; bl != NULL ; bl = bl->next )
+				{
+					if( bl->x>=x0 && bl->x<=x1 && bl->y>=y0 && bl->y<=y1
+#ifdef CIRCULAR_AREA
+						&& check_distance_bl(center, bl, range)
+#endif
+						&& bl_list_count<BL_LIST_MAX)
+						bl_list[bl_list_count++]=bl;
+				}
+			}
+		}
+
+	if(bl_list_count>=BL_LIST_MAX)
+		ShowWarning("map_forcountinrange: block count too many!\n");
+
+	map_freeblock_lock();	// ����������̉�����֎~����
 
+	for(i=blockcount;i<bl_list_count;i++)
+		if(bl_list[i]->prev)	// �L?���ǂ����`�F�b�N
+		{
+			va_list ap;
+			va_start(ap, type);
+			returnCount += func(bl_list[i], ap);
+			va_end(ap);
+			if( count && returnCount >= count )
+				break;
+		}
+
+	map_freeblock_unlock();	// ��������‚���
+
+	bl_list_count = blockcount;
+	return returnCount;	//[Skotlex]
+}
 int map_forcountinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int count, int type, ...)
 {
 	int bx,by;
diff --git a/src/map/map.h b/src/map/map.h
index 98833fe85..f55140847 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -591,6 +591,7 @@ int map_moveblock(struct block_list *, int, int, unsigned int);
 int map_foreachinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int type, ...);
 int map_foreachinshootrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int type, ...);
 int map_foreachinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int type, ...);
+int map_forcountinrange(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int count, int type, ...);
 int map_forcountinarea(int (*func)(struct block_list*,va_list), int m, int x0, int y0, int x1, int y1, int count, int type, ...);
 int map_foreachinmovearea(int (*func)(struct block_list*,va_list), struct block_list* center, int range, int dx, int dy, int type, ...);
 int map_foreachincell(int (*func)(struct block_list*,va_list), int m, int x, int y, int type, ...);
diff --git a/src/map/skill.c b/src/map/skill.c
index 31b4045ea..cac203aba 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -1214,6 +1214,27 @@ int skill_additional_effect (struct block_list* src, struct block_list *bl, int
 		skill_break_equip(src, EQP_SHIELD, 500, BCT_SELF);
 		sc_start(bl, SC_EARTHDRIVE, 100, skilllv, skill_get_time(skillid, skilllv));
 		break;
+	case SR_DRAGONCOMBO:
+		sc_start(bl, SC_STUN, 1 + 1 * skilllv, skilllv, skill_get_time(skillid, skilllv));
+		break;
+	case SR_FALLENEMPIRE:
+		sc_start(bl, SC_STOP, 100, skilllv, skill_get_time(skillid, skilllv));
+		break;
+	case SR_TIGERCANNON:
+		status_percent_damage(src, bl, 0, 5+1*skilllv, false); // The hell is this? [Rytech]
+		break;
+	case SR_WINDMILL:
+		if( dstsd )
+			skill_addtimerskill(src,tick+status_get_amotion(src),bl->id,0,0,skillid,skilllv,BF_WEAPON,0);
+		else if( dstmd && !is_boss(bl) )
+			sc_start(bl, SC_STUN, 100, skilllv, 1000 + 1000 * (rand()%3));
+		break;
+	case SR_GENTLETOUCH_QUIET:
+		sc_start(bl, SC_SILENCE, 2 * skilllv, skilllv, skill_get_time(skillid, skilllv));
+		break;
+	case SR_HOWLINGOFLION:
+		sc_start(bl, SC_FEAR, 5 + 5 * skilllv, skilllv, skill_get_time(skillid, skilllv));
+		break;
 	}
 
 	if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai)
@@ -2105,7 +2126,7 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 		switch(skillid)
 		{
 			case MO_TRIPLEATTACK:
-				if (pc_checkskill(sd, MO_CHAINCOMBO) > 0)
+				if (pc_checkskill(sd, MO_CHAINCOMBO) > 0 || pc_checkskill(sd, SR_DRAGONCOMBO) > 0)
 					flag=1;
 				break;
 			case MO_CHAINCOMBO:
@@ -2148,10 +2169,21 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 				//Can't attack nor use items until skill's delay expires. [Skotlex]
 				sd->ud.attackabletime = sd->canuseitem_tick = sd->ud.canact_tick;
 				break;
+			case SR_DRAGONCOMBO:
+				if( pc_checkskill(sd, SR_FALLENEMPIRE) > 0 )
+					flag = 1;
+				break;
+			case SR_FALLENEMPIRE:
+				if( pc_checkskill(sd, SR_TIGERCANNON) > 0 || pc_checkskill(sd, SR_GATEOFHELL) > 0 )
+					flag = 1;
+				break;
 		}	//Switch End
 		if (flag) { //Possible to chain
 			flag = DIFF_TICK(sd->ud.canact_tick, tick);
 			if (flag < 1) flag = 1;
+			// Dragon Combo must change into self skill and auto-select target when used as combo skill.
+			if( skillid == MO_TRIPLEATTACK && pc_checkskill(sd, SR_DRAGONCOMBO) > 0 )
+				clif_skillinfo(sd,SR_DRAGONCOMBO,INF_SELF_SKILL);
 			sc_start2(src,SC_COMBO,100,skillid,bl->id,flag);
 			clif_combo_delay(src, flag);
 		}
@@ -2183,10 +2215,8 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 		else // the central target doesn't display an animation
 			dmg.dmotion = clif_skill_damage(dsrc,bl,tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skillid, -2, 5); // needs -2(!) as skill level
 		break;
-	/**
-	 * Warlock
-	 **/
 	case WL_HELLINFERNO:
+	case SR_EARTHSHAKER:
 		dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,skillid,-2,6);
 		break;
 	case WL_SOULEXPANSION:
@@ -2202,9 +2232,6 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 	case WL_TETRAVORTEX_GROUND:
 		dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,1,WL_TETRAVORTEX_FIRE,-2,type);
 		break;
-	/**
-	 * Royal Guard
-	 **/
 	case LG_OVERBRAND_BRANDISH:
 	case LG_OVERBRAND_PLUSATK:
 		dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skillid,-1,5);
@@ -2332,12 +2359,13 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 	if (dmg.blewcount > 0 && bl!=dsrc && !status_isdead(bl))
 	{
 		int direction = -1; // default
-		switch(skillid) {
+		switch(skillid) {//direction
 			case MG_FIREWALL:
 			case WZ_STORMGUST:
 			case PR_SANCTUARY:
 			case SC_TRIANGLESHOT:
 			case LG_OVERBRAND:
+			case SR_KNUCKLEARROW:
 				direction = unit_getdir(bl);// backwards
 				break;
 			case WL_CRIMSONROCK:
@@ -2345,17 +2373,31 @@ int skill_attack (int attack_type, struct block_list* src, struct block_list *ds
 				break;
 
 		}
-		if( skillid == LG_OVERBRAND ) {
-			if( skill_blown(dsrc,bl,dmg.blewcount,direction,0) ) {
-				short dir_x, dir_y;
-				dir_x = dirx[(direction+4)%8];
-				dir_y = diry[(direction+4)%8];
-				if( map_getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0 )
+		//blown-specific handling
+		switch( skillid ) {
+			case LG_OVERBRAND:
+				if( skill_blown(dsrc,bl,dmg.blewcount,direction,0) ) {
+					short dir_x, dir_y;
+					dir_x = dirx[(direction+4)%8];
+					dir_y = diry[(direction+4)%8];
+					if( map_getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0 )
+						skill_addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skilllv, BF_WEAPON, flag );
+				} else
 					skill_addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skilllv, BF_WEAPON, flag );
-			} else
-				skill_addtimerskill(src, tick + status_get_amotion(src), bl->id, 0, 0, LG_OVERBRAND_PLUSATK, skilllv, BF_WEAPON, flag );
-		} else
-			skill_blown(dsrc,bl,dmg.blewcount,direction,0);
+				break;
+			case SR_KNUCKLEARROW:
+				if( skill_blown(dsrc,bl,dmg.blewcount,direction,0) && !(flag&4) ) {
+					short dir_x, dir_y;
+					dir_x = dirx[(direction+4)%8];
+					dir_y = diry[(direction+4)%8];
+					if( map_getcell(bl->m, bl->x+dir_x, bl->y+dir_y, CELL_CHKNOPASS) != 0 )
+						skill_addtimerskill(src, tick + 300 * ((flag&2) ? 1 : 2), bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|4);	
+				}			
+				break;
+			default:
+				skill_blown(dsrc,bl,dmg.blewcount,direction,0);
+				break;
+		}
 	}
 
 	//Delayed damage must be dealt after the knockback (it needs to know actual position of target)
@@ -2901,6 +2943,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
 					}
 					break;
 				case LG_MOONSLASHER:
+				case SR_WINDMILL:
 					if( target->type == BL_PC ) {
 						struct map_session_data *tsd = NULL;
 						if( (tsd = ((TBL_PC*)target)) && !pc_issit(tsd) ) {
@@ -2912,6 +2955,7 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
 					break;
 				case LG_OVERBRAND_BRANDISH:
 				case LG_OVERBRAND_PLUSATK:
+				case SR_KNUCKLEARROW:
 					skill_attack(BF_WEAPON, src, src, target, skl->skill_id, skl->skill_lv, tick, skl->flag|SD_LEVEL);
 					break;
 				default:
@@ -3161,6 +3205,11 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 	case LG_RAGEBURST:
 	case LG_RAYOFGENESIS:
 	case LG_HESPERUSLIT:
+	case SR_SKYNETBLOW:
+	case SR_FALLENEMPIRE:
+	case SR_CRESCENTELBOW_AUTOSPELL:
+	case SR_GATEOFHELL:
+	case SR_GENTLETOUCH_QUIET:
 		skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
 	break;
 
@@ -3365,40 +3414,23 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 	case NPC_PULSESTRIKE:
 	case NPC_HELLJUDGEMENT:
 	case NPC_VAMPIRE_GIFT:
-	/**
-	 * Rune Knight
-	 **/
 	case RK_IGNITIONBREAK:
-	/**
-	 * Arch Bishop
-	 **/
 	case AB_JUDEX:
-	/**
-	 * Warlock
-	 **/
 	case WL_SOULEXPANSION:
 	case WL_CRIMSONROCK:
 	case WL_COMET:
-	/**
-	 * Ranger
-	 **/
 	case RA_ARROWSTORM:
 	case RA_WUGDASH:
-	/**
-	 * Mechanic
-	 **/
 	case NC_SELFDESTRUCTION:
 	case NC_AXETORNADO:
-	/**
-	 * Guilotine Cross
-	 **/
 	case GC_ROLLINGCUTTER:
 	case GC_COUNTERSLASH:
-	/**
-	 * Royal Guard
-	 **/
 	case LG_MOONSLASHER:
 	case LG_EARTHDRIVE:
+	case SR_TIGERCANNON:
+	case SR_RAMPAGEBLASTER:
+	case SR_WINDMILL:
+	case SR_RIDEINLIGHTNING:
 		if( flag&1 )
 		{	//Recursive invocation
 			// skill_area_temp[0] holds number of targets in area
@@ -3715,9 +3747,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 		status_change_end(src, SC_HIDING, INVALID_TIMER);
 		skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
 		break;
-	/**
-	 * Rune Knight
-	 **/
 	case RK_PHANTOMTHRUST:
 		unit_setdir(src,map_calc_dir(src, bl->x, bl->y));
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
@@ -3737,9 +3766,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 		} else //non-sd support
 			skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
 		break;
-	/**
-	 * Guilotinne Cross
-	 **/
 	case GC_DARKILLUSION:
 		{
 			short x, y;
@@ -3789,9 +3815,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 				skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
 		}
 		break;
-	/**
-	 * Warlock
-	 **/
 	case WL_CHAINLIGHTNING:
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
 		skill_addtimerskill(src,tick + 150,bl->id,3,0,WL_CHAINLIGHTNING_ATK,skilllv,4+skilllv,flag);
@@ -3975,9 +3998,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 		skill_attack(skill_get_type(skillid), src, src, bl, skillid, skilllv, tick, flag);
 		}
 		break;
-	/**
-	 * Ranger
-	 **/
 	case RA_WUGSTRIKE:
 	case RA_WUGBITE:
 		if( path_search(NULL,src->m,src->x,src->y,bl->x,bl->y,1,CELL_CHKNOREACH) ) {
@@ -4016,9 +4036,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 			}
 		}
 		break;
-	/**
-	 * Mechanic
-	 **/
 	case NC_INFRAREDSCAN:
 		if( flag&1 )
 		{ //TODO: Need a confirmation if the other type of hidden status is included to be scanned. [Jobbie]
@@ -4054,9 +4071,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 			clif_skill_damage(src,src,tick,status_get_amotion(src),0,-30000,1,skillid,skilllv,6);
 		}
 		break;
-	/**
-	 * Royal Guard
-	 **/
 	case LG_PINPOINTATTACK:
 		if( !map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 1, 1) )
 			clif_slide(src,bl->x,bl->y);
@@ -4075,6 +4089,59 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, int
 	case LG_OVERBRAND_BRANDISH:
 		skill_addtimerskill(src, tick + status_get_amotion(src)*8/10, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|SD_LEVEL);
 		break;
+	case SR_DRAGONCOMBO:
+		if( sd ) // Dragon Combo must back to target-selectable skill after use it as combo.
+			clif_skillinfo(sd,SR_DRAGONCOMBO,0);
+		skill_attack(BF_WEAPON,src,src,bl,skillid,skilllv,tick,flag);
+		break;
+
+	case SR_KNUCKLEARROW:
+			if( !map_flag_gvg(src->m) && !map[src->m].flag.battleground && unit_movepos(src, bl->x, bl->y, 1, 1) ) {
+				clif_slide(src,bl->x,bl->y);
+				clif_fixpos(src); // Aegis send this packet too.
+			}
+
+			if( flag&1 )
+				skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag|SD_LEVEL);
+			else
+				skill_addtimerskill(src, tick + 300, bl->id, 0, 0, skillid, skilllv, BF_WEAPON, flag|SD_LEVEL|2);
+		break;
+
+	case SR_HOWLINGOFLION:
+			status_change_end(bl, SC_SWINGDANCE, -1);
+			status_change_end(bl, SC_SYMPHONYOFLOVER, -1);
+			status_change_end(bl, SC_MOONLITSERENADE, -1);
+			status_change_end(bl, SC_RUSHWINDMILL, -1);
+			status_change_end(bl, SC_ECHOSONG, -1);
+			status_change_end(bl, SC_HARMONIZE, -1);
+			status_change_end(bl, SC_SIRCLEOFNATURE, -1);
+			status_change_end(bl, SC_SATURDAYNIGHTFEVER, -1);
+			status_change_end(bl, SC_DANCEWITHWUG, -1);
+			status_change_end(bl, SC_LERADSDEW, -1);
+			status_change_end(bl, SC_MELODYOFSINK, -1);
+			status_change_end(bl, SC_BEYONDOFWARCRY, -1);
+			status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, -1);
+			skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+		break;
+
+	case SR_EARTHSHAKER:
+		if( flag&1 ) {
+			struct status_change *tsc = status_get_sc(bl);
+			if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKING] || tsc->data[SC_CLOAKINGEXCEED]) ) {
+				status_change_end(bl, SC_HIDING, -1);
+				status_change_end(bl, SC_CLOAKING, -1);
+				status_change_end(bl, SC_CHASEWALK, -1);
+				status_change_end(bl, SC_CLOAKINGEXCEED, -1);
+				sc_start(bl,SC_STUN, 25 + 5 * skilllv,skilllv,skill_get_time(skillid,skilllv));//Does it apply the stun chance to targets knocked out of hiding, or it applys allways? [Rytech]
+				skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+			} else
+				skill_attack(BF_WEAPON, src, src, bl, skillid, skilllv, tick, flag);
+		}
+		else
+			map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
+		clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+		break;
+
 
 	case 0:
 		if(sd) {
@@ -4718,6 +4785,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 	case SC_DEADLYINFECT:
 	case LG_EXEEDBREAK:
 	case LG_PRESTIGE:
+	case SR_CRESCENTELBOW:
+	case SR_LIGHTNINGWALK:
+	case SR_GENTLETOUCH_ENERGYGAIN:
+	case SR_GENTLETOUCH_CHANGE:
+	case SR_GENTLETOUCH_REVITALIZE:
 		clif_skill_nodamage(src,bl,skillid,skilllv,
 			sc_start(bl,type,100,skilllv,skill_get_time(skillid,skilllv)));
 		break;
@@ -5004,18 +5076,12 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 
 	case ASC_METEORASSAULT:
 	case GS_SPREADATTACK:
-	/**
-	 * Rune Knight
-	 **/
 	case RK_STORMBLAST:
-	/**
-	 * Mechanic
-	 **/
 	case NC_AXETORNADO:
-	/**
-	 * Guilotine Cross
-	 **/
 	case GC_COUNTERSLASH:
+	case SR_SKYNETBLOW:
+	case SR_RAMPAGEBLASTER:
+	case SR_HOWLINGOFLION:
 		skill_area_temp[1] = 0;
 		clif_skill_nodamage(src,bl,skillid,skilllv,1);
 		i = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), 
@@ -5029,6 +5095,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 		status_change_end(src,SC_OVERHEAT_LIMITPOINT,-1);
 		status_change_end(src,SC_OVERHEAT,-1);
 		break;
+	case SR_EARTHSHAKER:
+	case SR_WINDMILL:
 	case NC_INFRAREDSCAN:
 	case NPC_EARTHQUAKE:
 	case NPC_VAMPIRE_GIFT:
@@ -7607,6 +7675,83 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, in
 			clif_skill_nodamage(bl,src,skillid,skilllv,
 				sc_start(bl, type, 100, skilllv, skill_get_time(skillid, skilllv)));
 		break;
+	case SR_CURSEDCIRCLE:
+		if( flag&1 ) {
+			if( is_boss(bl) ) break;
+			if( sc_start2(bl, type, 100, skilllv, src->id, skill_get_time(skillid, skilllv))) {
+				unit_stop_attack(bl);
+				clif_bladestop(src, bl->id, 1);
+				map_freeblock_unlock();
+				return 1;
+			}
+		} else {
+			int count = 0;
+			clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+			count = map_forcountinrange(skill_area_sub, src, skill_get_splash(skillid,skilllv), (sd)?sd->spiritball_old:15, // Assume 15 spiritballs in non-charactors
+				BL_CHAR, src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+			if( sd ) pc_delspiritball(sd, count, 0);
+			clif_skill_nodamage(src, src, skillid, skilllv,
+				sc_start2(src, SC_CURSEDCIRCLE_ATKER, 100, skilllv, count, skill_get_time(skillid,skilllv)));
+		}
+		break;
+
+	case SR_RAISINGDRAGON:
+		if( sd ) {
+			short max = 5 + skilllv;
+			sc_start(bl, SC_EXPLOSIONSPIRITS, 100, skilllv, skill_get_time(skillid, skilllv));				
+			for( i = 0; i < max; i++ ) // Don't call more than max available spheres.
+				pc_addspiritball(sd, skill_get_time(skillid, skilllv), max);
+			clif_skill_nodamage(src, bl, skillid, skilllv, sc_start(bl, type, 100, skilllv,skill_get_time(skillid, skilllv)));
+		}
+		break;
+
+	case SR_ASSIMILATEPOWER:
+		if( flag&1 ) {
+			i = 0;
+			if( dstsd && dstsd->spiritball && (sd == dstsd || map_flag_vs(src->m)) && (dstsd->class_&MAPID_BASEMASK)!=MAPID_GUNSLINGER )
+			{
+				i = dstsd->spiritball; //1%sp per spiritball.
+				pc_delspiritball(dstsd, dstsd->spiritball, 0);
+			}
+			if( i ) status_percent_heal(src, 0, i); 
+			clif_skill_nodamage(src, bl, skillid, skilllv, i ? 1:0);
+		} else {
+			clif_skill_damage(src,bl,tick, status_get_amotion(src), 0, -30000, 1, skillid, skilllv, 6);
+			map_foreachinrange(skill_area_sub, bl, skill_get_splash(skillid, skilllv), splash_target(src), src, skillid, skilllv, tick, flag|BCT_ENEMY|BCT_SELF|SD_SPLASH|1, skill_castend_nodamage_id);
+		}
+		break;
+
+	case SR_POWERVELOCITY:
+		if( !dstsd )
+			break;
+		if( sd && dstsd->spiritball <= 5 ) {
+			for(i = 0; i <= 5; i++) {
+				pc_addspiritball(dstsd, skill_get_time(MO_CALLSPIRITS, pc_checkskill(sd,MO_CALLSPIRITS)), i);
+				pc_delspiritball(sd, sd->spiritball, 0);
+			}
+		}
+		clif_skill_nodamage(src, bl, skillid, skilllv, 1);
+		break;
+
+	case SR_GENTLETOUCH_CURE:
+		if( status_isimmune(bl) ) {
+			clif_skill_nodamage(src,bl,skillid,skilllv,0);
+			break;
+		}
+		if( (tsc && tsc->opt1) && rand()%100 < 5 * skilllv ) {
+			status_change_end(bl, SC_STONE, -1 );
+			status_change_end(bl, SC_FREEZE, -1 );
+			status_change_end(bl, SC_STUN, -1 );
+			status_change_end(bl, SC_POISON, -1 );
+			status_change_end(bl, SC_SILENCE, -1 );
+			status_change_end(bl, SC_BLIND, -1 );
+			status_change_end(bl, SC_HALLUCINATION, -1 );
+			status_change_end(bl, SC_BURNING, -1 );
+			status_change_end(bl, SC_FREEZING, -1 );
+			skill_castend_nodamage_id(src, bl, AL_HEAL, skilllv, tick, flag);
+		}
+		clif_skill_nodamage(src,bl,skillid,skilllv,1);
+		break;
 
 	case RETURN_TO_ELDICASTES:
 	case ALL_GUARDIAN_RECALL:
@@ -7778,7 +7923,8 @@ int skill_castend_id(int tid, unsigned int tick, int id, intptr_t data)
 			inf2 = skill_get_inf2(ud->skillid);
 
 			if(inf&INF_ATTACK_SKILL ||
-				(inf&INF_SELF_SKILL && inf2&INF2_NO_TARGET_SELF)) //Combo skills
+				(inf&INF_SELF_SKILL && inf2&INF2_NO_TARGET_SELF) || //Combo skills
+				(ud->skillid == SR_DRAGONCOMBO && src == target) ) // Casted through combo.
 				inf = BCT_ENEMY; //Offensive skill.
 			else if(inf2&INF2_NO_ENEMY)
 				inf = BCT_NOENEMY;
@@ -8184,6 +8330,12 @@ int skill_castend_pos2(struct block_list* src, int x, int y, int skillid, int sk
 			src->m, x-i, y-i, x+i,y+i,BL_SKILL);
 		break;
 
+	case SR_RIDEINLIGHTNING:
+		i = skill_get_splash(skillid, skilllv);
+		map_foreachinarea(skill_area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR, 
+			src, skillid, skilllv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
+		break;
+
 	case SA_VOLCANO:
 	case SA_DELUGE:
 	case SA_VIOLENTGALE:
@@ -10563,6 +10715,8 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
 		break;
 	case MO_FINGEROFFENSIVE:
 	case GS_FLING:
+	case SR_RAMPAGEBLASTER:
+	case SR_RIDEINLIGHTNING:
 		if( sd->spiritball > 0 && sd->spiritball < require.spiritball )
 			sd->spiritball_old = require.spiritball = sd->spiritball;
 		else
@@ -10967,6 +11121,28 @@ int skill_check_condition_castbegin(struct map_session_data* sd, short skill, sh
 			return 0;
 		}
 		break;
+	case SR_FALLENEMPIRE:
+		if( !(sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO) )
+			return 0;
+		break;
+	case SR_CRESCENTELBOW:
+		if( sc && sc->data[SC_CRESCENTELBOW] ) {
+			clif_skill_fail(sd,skill,0,0);
+			return 0;
+		}
+		break;
+	case SR_CURSEDCIRCLE:
+		if( sd->spiritball > 0 )
+			sd->spiritball_old = require.spiritball = sd->spiritball;
+		else {
+			clif_skill_fail(sd,skill,0,0);
+			return 0;
+		}
+		break;
+	case SR_GATEOFHELL:
+		if( sd->spiritball > 0 )
+			sd->spiritball_old = require.spiritball;
+		break;
 	case SC_MANHOLE:
 	case SC_DIMENSIONDOOR:
 		if( sc && sc->data[SC_MAGNETICFIELD] ) {
@@ -11519,6 +11695,13 @@ struct skill_condition skill_get_requirement(struct map_session_data* sd, short
 				}
 			}
 			break;
+		case SR_RAMPAGEBLASTER:
+			req.spiritball = sd->spiritball?sd->spiritball:15;
+			break;
+		case SR_GATEOFHELL:
+			if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE )
+				req.sp -= req.sp * 10 / 100;
+			break;
 	}
 	
 	return req;
@@ -11638,13 +11821,14 @@ int skill_delayfix (struct block_list *bl, int skill_id, int skill_lv)
 		time = -time + status_get_amotion(bl);	// If set to <0, add to attack motion.
 
 	// Delay reductions
-	switch (skill_id)
-  	{	//Monk combo skills have their delay reduced by agi/dex.
+	switch (skill_id) {	//Monk combo skills have their delay reduced by agi/dex.
 	case MO_TRIPLEATTACK:
 	case MO_CHAINCOMBO:
 	case MO_COMBOFINISH:
 	case CH_TIGERFIST:
 	case CH_CHAINCRUSH:
+	case SR_DRAGONCOMBO:
+	case SR_FALLENEMPIRE:
 		time -= 4*status_get_agi(bl) - 2*status_get_dex(bl);
 		break;
 	case HP_BASILICA:
diff --git a/src/map/status.c b/src/map/status.c
index 39634ad09..dc0d8fdb2 100644
--- a/src/map/status.c
+++ b/src/map/status.c
@@ -555,18 +555,18 @@ void initChangeTables(void)
 	set_sc( SC_MANHOLE           , SC__MANHOLE        , SI_MANHOLE         , SCB_NONE );
 	add_sc( SC_CHAOSPANIC        , SC_CHAOS );
 	set_sc( SC_BLOODYLUST        , SC__BLOODYLUST     , SI_BLOODYLUST      , SCB_DEF|SCB_DEF2|SCB_BATK|SCB_WATK );
-	///**
-	// * Sura
-	// **/
-	//add_sc( SR_DRAGONCOMBO           , SC_STUN            );
-	//add_sc( SR_EARTHSHAKER           , SC_STUN            );
-	//set_sc( SR_CRESCENTELBOW         , SC_CRESCENTELBOW      , SI_CRESCENTELBOW         , SCB_NONE );
-	//set_sc( SR_CURSEDCIRCLE          , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET   , SCB_NONE );
-	//set_sc( SR_LIGHTNINGWALK         , SC_LIGHTNINGWALK      , SI_LIGHTNINGWALK         , SCB_NONE );
-	//set_sc( SR_RAISINGDRAGON         , SC_RAISINGDRAGON      , SI_RAISINGDRAGON         , SCB_REGEN|SCB_MAXHP|SCB_MAXSP/*|SCB_ASPD*/ );
-	//set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GT_ENERGYGAIN      , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE );
-	//set_sc( SR_GENTLETOUCH_CHANGE    , SC_GT_CHANGE          , SI_GENTLETOUCH_CHANGE    , SCB_BATK|SCB_ASPD|SCB_DEF|SCB_MDEF );
-	//set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE      , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_DEF2|SCB_REGEN|SCB_ASPD|SCB_SPEED );
+	/**
+	 * Sura
+	 **/
+	add_sc( SR_DRAGONCOMBO           , SC_STUN            );
+	add_sc( SR_EARTHSHAKER           , SC_STUN            );
+	set_sc( SR_CRESCENTELBOW         , SC_CRESCENTELBOW      , SI_CRESCENTELBOW         , SCB_NONE );
+	set_sc( SR_CURSEDCIRCLE          , SC_CURSEDCIRCLE_TARGET, SI_CURSEDCIRCLE_TARGET   , SCB_NONE );
+	set_sc( SR_LIGHTNINGWALK         , SC_LIGHTNINGWALK      , SI_LIGHTNINGWALK         , SCB_NONE );
+	set_sc( SR_RAISINGDRAGON         , SC_RAISINGDRAGON      , SI_RAISINGDRAGON         , SCB_REGEN|SCB_MAXHP|SCB_MAXSP/*|SCB_ASPD*/ );
+	set_sc( SR_GENTLETOUCH_ENERGYGAIN, SC_GT_ENERGYGAIN      , SI_GENTLETOUCH_ENERGYGAIN, SCB_NONE );
+	set_sc( SR_GENTLETOUCH_CHANGE    , SC_GT_CHANGE          , SI_GENTLETOUCH_CHANGE    , SCB_BATK|SCB_ASPD|SCB_DEF|SCB_MDEF );
+	set_sc( SR_GENTLETOUCH_REVITALIZE, SC_GT_REVITALIZE      , SI_GENTLETOUCH_REVITALIZE, SCB_MAXHP|SCB_DEF2|SCB_REGEN|SCB_ASPD|SCB_SPEED );
 	///**
 	// * Wanderer / Mistrel
 	// **/
@@ -1013,6 +1013,8 @@ int status_damage(struct block_list *src,struct block_list *target,int hp, int s
 			sc_start4(target,SC_PROVOKE,100,10,1,0,0,0);
 		if (sc->data[SC_BERSERK] && status->hp <= 100)
 			status_change_end(target, SC_BERSERK, INVALID_TIMER);
+		if( sc->data[SC_RAISINGDRAGON] && status->hp <= 1000 )
+			status_change_end(target, SC_RAISINGDRAGON, -1);
 	}
 
 	switch (target->type)
@@ -1411,7 +1413,8 @@ int status_check_skilluse(struct block_list *src, struct block_list *target, int
 				sc->data[SC_WHITEIMPRISON] ||
 				(sc->data[SC_STASIS] && skill_stasis_check(src, sc->data[SC_STASIS]->val2, skill_num)) ||
 				sc->data[SC__INVISIBILITY] ||
-				sc->data[SC__IGNORANCE]
+				sc->data[SC__IGNORANCE] ||
+				sc->data[SC_CURSEDCIRCLE_TARGET]
 			))
 				return 0;
 
@@ -3093,6 +3096,8 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
 		|| sc->data[SC_BERSERK]
 		|| sc->data[SC_TRICKDEAD]
 		|| sc->data[SC_BLEEDING]
+		|| sc->data[SC_MAGICMUSHROOM]
+		|| sc->data[SC_RAISINGDRAGON]
 	)	//No regen
 		regen->flag = 0;
 
@@ -3918,6 +3923,8 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
 		batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
 	if(sc->data[SC__BLOODYLUST])
 		batk += batk * 32 / 100;
+	if(sc->data[SC_GT_CHANGE])
+		batk += batk * sc->data[SC_GT_CHANGE]->val3 / 100;
 #if RE_EDP
 	/**
 	 * in RE EDP increases your base atk by atk x Skill Level.
@@ -4483,7 +4490,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
 				val = max( val, 75 );
 			if( sc->data[SC_CLOAKINGEXCEED] )
 				val = max( val, sc->data[SC_CLOAKINGEXCEED]->val3);
-
+			if( sc->data[SC_GT_REVITALIZE] )
+				val = max( val, sc->data[SC_GT_REVITALIZE]->val2 );
 			//FIXME: official items use a single bonus for this [ultramage]
 			if( sc->data[SC_SPEEDUP0] ) // temporary item-based speedup
 				val = max( val, 25 );
@@ -4709,6 +4717,12 @@ static unsigned int status_calc_maxhp(struct block_list *bl, struct status_chang
 		maxhp -= maxhp * sc->data[SC__WEAKNESS]->val2 / 100;
 	if(sc->data[SC_FORCEOFVANGUARD])
 		maxhp += maxhp * 3 * sc->data[SC_FORCEOFVANGUARD]->val1 / 100;
+	if(sc->data[SC_RAISINGDRAGON])
+		maxhp += maxhp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
+	if(sc->data[SC_GT_CHANGE])
+		maxhp -= maxhp * (2 * sc->data[SC_GT_CHANGE]->val1) / 100;
+	if(sc->data[SC_GT_REVITALIZE])
+		maxhp += maxhp * (3 * sc->data[SC_GT_REVITALIZE]->val1) / 100;
 	if(sc->data[SC_INSPIRATION]) //Custom value.
 		maxhp += maxhp * 3 * sc->data[SC_INSPIRATION]->val1 / 100;
 
@@ -4727,6 +4741,8 @@ static unsigned int status_calc_maxsp(struct block_list *bl, struct status_chang
 		maxsp += maxsp * sc->data[SC_SERVICE4U]->val2/100;
 	if(sc->data[SC_MERC_SPUP])
 		maxsp += maxsp * sc->data[SC_MERC_SPUP]->val2/100;
+	if(sc->data[SC_RAISINGDRAGON])
+		maxsp += maxsp * (2 + sc->data[SC_RAISINGDRAGON]->val1) / 100;
 
 	return cap_value(maxsp,1,UINT_MAX);
 }
@@ -6003,6 +6019,16 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 		if( type != SC_SHIELDSPELL_REF )
 			status_change_end(bl, SC_SHIELDSPELL_REF, INVALID_TIMER);
 		break;
+	case SC_GT_ENERGYGAIN:
+	case SC_GT_CHANGE:
+	case SC_GT_REVITALIZE:
+		if( type != SC_GT_REVITALIZE )
+			status_change_end(bl, SC_GT_REVITALIZE, INVALID_TIMER);
+		if( type != SC_GT_ENERGYGAIN )
+			status_change_end(bl, SC_GT_ENERGYGAIN, INVALID_TIMER);
+		if( type != SC_GT_CHANGE )
+			status_change_end(bl, SC_GT_CHANGE, INVALID_TIMER);
+		break;
 	}
 
 	//Check for overlapping fails
@@ -7461,6 +7487,8 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 		case SC_BITE:
 		case SC__MANHOLE:
 		case SC_CHAOS:
+		case SC_CURSEDCIRCLE_ATKER:
+		case SC_CURSEDCIRCLE_TARGET:
 			unit_stop_walking(bl,1);
 		break;
 		case SC_HIDING:
@@ -7742,6 +7770,9 @@ int status_change_start(struct block_list* bl,enum sc_type type,int rate,int val
 						clif_skillinfo(sd,TK_JUMPKICK, INF_SELF_SKILL);
 					break;
 			}
+		case SC_RAISINGDRAGON:
+			sce->val2 = status->max_hp / 100;// Officially tested its 1%hp drain. [Jobbie]
+			break;
 	}
 
 	if( opt_flag&2 && sd && sd->touching_id )
@@ -8258,7 +8289,6 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 				}
 			}
 			break;
-		/*
 		case SC_CURSEDCIRCLE_ATKER:
 			if( sce->val3 )
 				map_foreachinrange(status_change_timer_sub, bl, skill_get_splash(SR_CURSEDCIRCLE, sce->val1),BL_CHAR, bl, sce, SC_CURSEDCIRCLE_TARGET, gettick());
@@ -8276,7 +8306,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 					--i;
 				}
 			}
-			break;*/
+			break;
 		}
 
 	opt_flag = 1;
@@ -9341,6 +9371,12 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
 			status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
 		}
 		break;
+	case SC_CURSEDCIRCLE_TARGET:
+		if( tsc && tsc->data[SC_CURSEDCIRCLE_TARGET] && tsc->data[SC_CURSEDCIRCLE_TARGET]->val2 == src->id ) {
+			status_change_end(bl, type, -1);			
+			clif_bladestop(src, bl->id, 0);
+		}
+		break;
 	}
 	return 0;
 }
@@ -9415,6 +9451,8 @@ int status_change_clear_buffs (struct block_list* bl, int type)
 			case SC_VITALITYACTIVATION:
 			case SC_FIGHTINGSPIRIT:
 			case SC_ABUNDANCE:
+			case SC_CURSEDCIRCLE_ATKER:
+			case SC_CURSEDCIRCLE_TARGET:
 				continue;
 				
 			//Debuffs that can be removed.
diff --git a/src/map/unit.c b/src/map/unit.c
index 9df208e11..56deae9c7 100644
--- a/src/map/unit.c
+++ b/src/map/unit.c
@@ -1035,8 +1035,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, short skill_num, sh
 		sc = NULL; //Unneeded
 
 	//temp: used to signal combo-skills right now.
-	if (sc && sc->data[SC_COMBO] && (sc->data[SC_COMBO]->val1 == skill_num || skill_num == MO_EXTREMITYFIST))
-	{
+	if (sc && sc->data[SC_COMBO] && (sc->data[SC_COMBO]->val1 == skill_num ||
+		skill_num == MO_EXTREMITYFIST || skill_num == SR_DRAGONCOMBO )) {
 		if (sc->data[SC_COMBO]->val2)
 			target_id = sc->data[SC_COMBO]->val2;
 		else
-- 
cgit v1.2.3-70-g09d2