summaryrefslogtreecommitdiff
path: root/src/map
diff options
context:
space:
mode:
authorshennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-02-18 17:34:59 +0000
committershennetsind <shennetsind@54d463be-8e91-2dee-dedb-b68131a5f0ec>2012-02-18 17:34:59 +0000
commite901cc96b0095e523bae56da43766c9c821e6a91 (patch)
treec226b7d568d7685d933475dad687b8cb77433acd /src/map
parent991cacb6b346fad774395b4c192864f224f2d53b (diff)
downloadhercules-e901cc96b0095e523bae56da43766c9c821e6a91.tar.gz
hercules-e901cc96b0095e523bae56da43766c9c821e6a91.tar.bz2
hercules-e901cc96b0095e523bae56da43766c9c821e6a91.tar.xz
hercules-e901cc96b0095e523bae56da43766c9c821e6a91.zip
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
Diffstat (limited to 'src/map')
-rw-r--r--src/map/battle.c70
-rw-r--r--src/map/map.c67
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/skill.c322
-rw-r--r--src/map/status.c70
-rw-r--r--src/map/unit.c4
6 files changed, 441 insertions, 93 deletions
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) // 有?かどうかチェック
+ {
+ 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