|
@@ -416,14 +416,6 @@ unsigned short skill_dummy2skill_id(unsigned short skill_id) {
|
|
return GN_HELLS_PLANT;
|
|
return GN_HELLS_PLANT;
|
|
case GN_SLINGITEM_RANGEMELEEATK:
|
|
case GN_SLINGITEM_RANGEMELEEATK:
|
|
return GN_SLINGITEM;
|
|
return GN_SLINGITEM;
|
|
- case SR_FLASHCOMBO_ATK_STEP1:
|
|
|
|
- return SR_DRAGONCOMBO;
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP2:
|
|
|
|
- return SR_FALLENEMPIRE;
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP3:
|
|
|
|
- return SR_TIGERCANNON;
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP4:
|
|
|
|
- return SR_SKYNETBLOW;
|
|
|
|
case RL_R_TRIP_PLUSATK:
|
|
case RL_R_TRIP_PLUSATK:
|
|
return RL_R_TRIP;
|
|
return RL_R_TRIP;
|
|
}
|
|
}
|
|
@@ -1553,12 +1545,10 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
|
|
skill_castend_damage_id(src,bl,LG_PINPOINTATTACK,rnd_value(1, pc_checkskill(sd,LG_PINPOINTATTACK)),tick,0);
|
|
skill_castend_damage_id(src,bl,LG_PINPOINTATTACK,rnd_value(1, pc_checkskill(sd,LG_PINPOINTATTACK)),tick,0);
|
|
break;
|
|
break;
|
|
case SR_DRAGONCOMBO:
|
|
case SR_DRAGONCOMBO:
|
|
- case SR_FLASHCOMBO_ATK_STEP1:
|
|
|
|
- sc_start(src,bl, SC_STUN, 1 + skill_lv, skill_lv, skill_get_time(SR_DRAGONCOMBO, skill_lv));
|
|
|
|
|
|
+ sc_start(src,bl, SC_STUN, skill_lv, skill_lv, skill_get_time(skill_id, skill_lv));
|
|
break;
|
|
break;
|
|
case SR_FALLENEMPIRE:
|
|
case SR_FALLENEMPIRE:
|
|
- case SR_FLASHCOMBO_ATK_STEP2:
|
|
|
|
- sc_start(src,bl, SC_STOP, 100, skill_lv, skill_get_time(SR_FALLENEMPIRE, skill_lv));
|
|
|
|
|
|
+ sc_start(src,bl, SC_STOP, 100, skill_lv, skill_get_time(skill_id, skill_lv));
|
|
break;
|
|
break;
|
|
case SR_WINDMILL:
|
|
case SR_WINDMILL:
|
|
if( dstsd )
|
|
if( dstsd )
|
|
@@ -3124,17 +3114,36 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
|
|
|
|
|
damage = dmg.damage + dmg.damage2;
|
|
damage = dmg.damage + dmg.damage2;
|
|
|
|
|
|
- if( (skill_id == AL_INCAGI || skill_id == AL_BLESSING ||
|
|
|
|
- skill_id == CASH_BLESSING || skill_id == CASH_INCAGI ||
|
|
|
|
- skill_id == MER_INCAGI || skill_id == MER_BLESSING) && tsd->sc.data[SC_CHANGEUNDEAD] )
|
|
|
|
- damage = 1;
|
|
|
|
-
|
|
|
|
- if (flag&8) {
|
|
|
|
- skill_area_temp_i64[0] = damage;
|
|
|
|
- if (is_infinite_defense(bl, dmg.flag)) {
|
|
|
|
- dmg = battle_calc_attack_plant(dmg, src, bl, skill_id, skill_lv);
|
|
|
|
- damage = dmg.damage + dmg.damage2;
|
|
|
|
- }
|
|
|
|
|
|
+ switch(skill_id) {
|
|
|
|
+ case AL_INCAGI:
|
|
|
|
+ case CASH_INCAGI:
|
|
|
|
+ case MER_INCAGI:
|
|
|
|
+ case AL_BLESSING:
|
|
|
|
+ case CASH_BLESSING:
|
|
|
|
+ case MER_BLESSING:
|
|
|
|
+ if (tsc && tsc->data[SC_CHANGEUNDEAD])
|
|
|
|
+ damage = 1;
|
|
|
|
+ break;
|
|
|
|
+ case SR_TIGERCANNON:
|
|
|
|
+ if (skill_area_temp[1] == bl->id)
|
|
|
|
+ dsrc->damage = damage;
|
|
|
|
+ else {
|
|
|
|
+ dmg.damage = battle_attr_fix(src, bl, dsrc->damage, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
|
|
|
|
+ if (!dmg.damage) {
|
|
|
|
+ if (dmg.miscflag&4)
|
|
|
|
+ dmg.damage = skill_lv * 500 + status_get_lv(bl) * 40;
|
|
|
|
+ else
|
|
|
|
+ dmg.damage = skill_lv * 240 + status_get_lv(bl) * 40;
|
|
|
|
+ }
|
|
|
|
+ if (is_infinite_defense(bl, dmg.flag))
|
|
|
|
+ dmg = battle_calc_attack_plant(dmg, src, bl, skill_id, skill_lv);
|
|
|
|
+ else {
|
|
|
|
+ dmg = battle_calc_attack_gvg_bg(dmg, src, bl, skill_id, skill_lv);
|
|
|
|
+ battle_do_reflect(BF_WEAPON, &dmg, src, bl, skill_id, skill_lv);
|
|
|
|
+ }
|
|
|
|
+ damage = dmg.damage;
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
|
|
|
|
if( damage && tsc && tsc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){
|
|
if( damage && tsc && tsc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){
|
|
@@ -3263,6 +3272,7 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
|
case KO_BAKURETSU:
|
|
case KO_BAKURETSU:
|
|
case GN_CRAZYWEED_ATK:
|
|
case GN_CRAZYWEED_ATK:
|
|
case NC_MAGMA_ERUPTION:
|
|
case NC_MAGMA_ERUPTION:
|
|
|
|
+ case SR_TIGERCANNON:
|
|
dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,5);
|
|
dmg.dmotion = clif_skill_damage(src,bl,tick,dmg.amotion,dmg.dmotion,damage,dmg.div_,skill_id,-1,5);
|
|
break;
|
|
break;
|
|
case GN_FIRE_EXPANSION_ACID:
|
|
case GN_FIRE_EXPANSION_ACID:
|
|
@@ -3443,6 +3453,9 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
|
|
case WM_METALICSOUND:
|
|
case WM_METALICSOUND:
|
|
status_zap(bl, 0, damage*100/(100*(110-((sd) ? pc_checkskill(sd,WM_LESSON) : skill_get_max(WM_LESSON))*10)));
|
|
status_zap(bl, 0, damage*100/(100*(110-((sd) ? pc_checkskill(sd,WM_LESSON) : skill_get_max(WM_LESSON))*10)));
|
|
break;
|
|
break;
|
|
|
|
+ case SR_TIGERCANNON:
|
|
|
|
+ status_zap(bl, 0, damage / 10); // 10% of damage dealt
|
|
|
|
+ break;
|
|
}
|
|
}
|
|
if( sd )
|
|
if( sd )
|
|
skill_onskillusage(sd, bl, skill_id, tick);
|
|
skill_onskillusage(sd, bl, skill_id, tick);
|
|
@@ -3846,14 +3859,17 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
|
|
break; // Source not on Map
|
|
break; // Source not on Map
|
|
if(skl->target_id) {
|
|
if(skl->target_id) {
|
|
target = map_id2bl(skl->target_id);
|
|
target = map_id2bl(skl->target_id);
|
|
- if( ( skl->skill_id == RG_INTIMIDATE || skl->skill_id == SC_FATALMENACE ) && (!target || target->prev == NULL || !check_distance_bl(src,target,AREA_SIZE)) )
|
|
|
|
|
|
+ if ((skl->skill_id == RG_INTIMIDATE || skl->skill_id == SC_FATALMENACE) && (!target || target->prev == NULL || !check_distance_bl(src,target,AREA_SIZE)))
|
|
target = src; //Required since it has to warp.
|
|
target = src; //Required since it has to warp.
|
|
- if(target == NULL)
|
|
|
|
- break; // Target offline?
|
|
|
|
- if(target->prev == NULL)
|
|
|
|
- break; // Target not on Map
|
|
|
|
- if(src->m != target->m)
|
|
|
|
- break; // Different Maps
|
|
|
|
|
|
+ if (!target || target->prev == NULL || src->m != target->m) {
|
|
|
|
+ if (skl->skill_id == SR_SKYNETBLOW) {
|
|
|
|
+ clif_skill_damage(src, src, tick, status_get_amotion(src), 0, -30000, 1, skl->skill_id, skl->skill_lv, DMG_SKILL);
|
|
|
|
+ skill_area_temp[1] = 0;
|
|
|
|
+ map_foreachinrange(skill_area_sub, src, skill_get_splash(skl->skill_id, skl->skill_lv), splash_target(src), src,
|
|
|
|
+ skl->skill_id, skl->skill_lv, tick, skl->flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
|
|
|
|
+ }
|
|
|
|
+ break; // Target offline, not on map, or in different maps
|
|
|
|
+ }
|
|
if(status_isdead(src)) {
|
|
if(status_isdead(src)) {
|
|
switch(skl->skill_id) {
|
|
switch(skl->skill_id) {
|
|
case WL_CHAINLIGHTNING_ATK:
|
|
case WL_CHAINLIGHTNING_ATK:
|
|
@@ -3862,10 +3878,10 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
|
|
case WL_TETRAVORTEX_WIND:
|
|
case WL_TETRAVORTEX_WIND:
|
|
case WL_TETRAVORTEX_GROUND:
|
|
case WL_TETRAVORTEX_GROUND:
|
|
// For SR_FLASHCOMBO
|
|
// For SR_FLASHCOMBO
|
|
- case SR_FLASHCOMBO_ATK_STEP1:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP2:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP3:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP4:
|
|
|
|
|
|
+ case SR_DRAGONCOMBO:
|
|
|
|
+ case SR_FALLENEMPIRE:
|
|
|
|
+ case SR_TIGERCANNON:
|
|
|
|
+ case SR_SKYNETBLOW:
|
|
break; // Exceptions
|
|
break; // Exceptions
|
|
default:
|
|
default:
|
|
continue; // Caster is Dead
|
|
continue; // Caster is Dead
|
|
@@ -4029,15 +4045,17 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data)
|
|
break;
|
|
break;
|
|
}
|
|
}
|
|
// For SR_FLASHCOMBO
|
|
// For SR_FLASHCOMBO
|
|
- case SR_FLASHCOMBO_ATK_STEP1:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP2:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP3:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP4:
|
|
|
|
- if( src->type == BL_PC ) {
|
|
|
|
- const int use_skill_lv[] = { SR_DRAGONCOMBO, SR_FALLENEMPIRE, SR_TIGERCANNON, SR_SKYNETBLOW };
|
|
|
|
- if( distance_xy(src->x, src->y, target->x, target->y) >= 3 )
|
|
|
|
|
|
+ case SR_DRAGONCOMBO:
|
|
|
|
+ case SR_FALLENEMPIRE:
|
|
|
|
+ case SR_TIGERCANNON:
|
|
|
|
+ case SR_SKYNETBLOW:
|
|
|
|
+ if (src->type == BL_PC) {
|
|
|
|
+ if (distance_xy(src->x, src->y, target->x, target->y) >= 3)
|
|
break;
|
|
break;
|
|
- skill_castend_damage_id(src, target, skl->skill_id, pc_checkskill(((TBL_PC *)src), use_skill_lv[skl->skill_id-SR_FLASHCOMBO_ATK_STEP1]), tick, 0);
|
|
|
|
|
|
+ if (skl->skill_id == SR_TIGERCANNON)
|
|
|
|
+ skill_castend_nodamage_id(src, target, skl->skill_id, pc_checkskill(((TBL_PC *)src), skl->skill_id), tick, skl->flag);
|
|
|
|
+ else
|
|
|
|
+ skill_castend_damage_id(src, target, skl->skill_id, pc_checkskill(((TBL_PC *)src), skl->skill_id), tick, 0);
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
case RL_SLUGSHOT:
|
|
case RL_SLUGSHOT:
|
|
@@ -4166,10 +4184,10 @@ int skill_cleartimerskill (struct block_list *src)
|
|
case WL_TETRAVORTEX_WIND:
|
|
case WL_TETRAVORTEX_WIND:
|
|
case WL_TETRAVORTEX_GROUND:
|
|
case WL_TETRAVORTEX_GROUND:
|
|
// For SR_FLASHCOMBO
|
|
// For SR_FLASHCOMBO
|
|
- case SR_FLASHCOMBO_ATK_STEP1:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP2:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP3:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP4:
|
|
|
|
|
|
+ case SR_DRAGONCOMBO:
|
|
|
|
+ case SR_FALLENEMPIRE:
|
|
|
|
+ case SR_TIGERCANNON:
|
|
|
|
+ case SR_SKYNETBLOW:
|
|
continue;
|
|
continue;
|
|
}
|
|
}
|
|
delete_timer(ud->skilltimerskill[i]->timer, skill_timerskill);
|
|
delete_timer(ud->skilltimerskill[i]->timer, skill_timerskill);
|
|
@@ -4362,7 +4380,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
case LG_OVERBRAND:
|
|
case LG_OVERBRAND:
|
|
case LG_OVERBRAND_BRANDISH:
|
|
case LG_OVERBRAND_BRANDISH:
|
|
case SR_FALLENEMPIRE:
|
|
case SR_FALLENEMPIRE:
|
|
- case SR_FLASHCOMBO_ATK_STEP2:
|
|
|
|
case SR_CRESCENTELBOW_AUTOSPELL:
|
|
case SR_CRESCENTELBOW_AUTOSPELL:
|
|
case SR_GATEOFHELL:
|
|
case SR_GATEOFHELL:
|
|
case SR_GENTLETOUCH_QUIET:
|
|
case SR_GENTLETOUCH_QUIET:
|
|
@@ -4590,9 +4607,9 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
case GC_COUNTERSLASH:
|
|
case GC_COUNTERSLASH:
|
|
case LG_MOONSLASHER:
|
|
case LG_MOONSLASHER:
|
|
case LG_EARTHDRIVE:
|
|
case LG_EARTHDRIVE:
|
|
|
|
+ case SR_TIGERCANNON:
|
|
case SR_RAMPAGEBLASTER:
|
|
case SR_RAMPAGEBLASTER:
|
|
case SR_SKYNETBLOW:
|
|
case SR_SKYNETBLOW:
|
|
- case SR_FLASHCOMBO_ATK_STEP4:
|
|
|
|
case SR_WINDMILL:
|
|
case SR_WINDMILL:
|
|
case SR_RIDEINLIGHTNING:
|
|
case SR_RIDEINLIGHTNING:
|
|
case WM_REVERBERATION_MELEE:
|
|
case WM_REVERBERATION_MELEE:
|
|
@@ -4624,6 +4641,17 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
if( skill_area_temp[1] != bl->id && !(skill_get_inf2(skill_id)&INF2_NPC_SKILL) )
|
|
if( skill_area_temp[1] != bl->id && !(skill_get_inf2(skill_id)&INF2_NPC_SKILL) )
|
|
sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills)
|
|
sflag |= SD_ANIMATION; // original target gets no animation (as well as all NPC skills)
|
|
|
|
|
|
|
|
+ if (skill_area_temp[1] == bl->id && skill_id == SR_TIGERCANNON)
|
|
|
|
+ break; // Already done in 'skill_castend_nodamage_id' [exneval]
|
|
|
|
+ switch(skill_id) {
|
|
|
|
+ case SR_TIGERCANNON:
|
|
|
|
+ sflag |= 8;
|
|
|
|
+ // Fall through
|
|
|
|
+ case SR_SKYNETBLOW:
|
|
|
|
+ sflag |= flag&4;
|
|
|
|
+ break;
|
|
|
|
+ break;
|
|
|
|
+ }
|
|
heal = (int)skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, sflag);
|
|
heal = (int)skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, sflag);
|
|
if( skill_id == NPC_VAMPIRE_GIFT && heal > 0 ) {
|
|
if( skill_id == NPC_VAMPIRE_GIFT && heal > 0 ) {
|
|
clif_skill_nodamage(NULL, src, AL_HEAL, heal, 1);
|
|
clif_skill_nodamage(NULL, src, AL_HEAL, heal, 1);
|
|
@@ -5357,7 +5385,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
break;
|
|
break;
|
|
|
|
|
|
case SR_DRAGONCOMBO:
|
|
case SR_DRAGONCOMBO:
|
|
- case SR_FLASHCOMBO_ATK_STEP1:
|
|
|
|
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
|
|
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -5409,34 +5436,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
|
|
- case SR_TIGERCANNON:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP3:
|
|
|
|
- if (flag&1) {
|
|
|
|
- if (skill_area_temp[3] == skill_id && skill_area_temp_i64[0]) { // Safe check
|
|
|
|
- if (skill_area_temp[1] != bl->id) {
|
|
|
|
- int64 dmg = skill_area_temp_i64[0];
|
|
|
|
- bool infdef = is_infinite_defense(bl, skill_get_type(skill_id));
|
|
|
|
- if (infdef)
|
|
|
|
- dmg = 1;
|
|
|
|
- status_damage(src, bl, dmg, 0, 0, 0);
|
|
|
|
- status_zap(bl, 0, status_get_max_sp(bl) * 10 / 100);
|
|
|
|
- clif_skill_damage(src, bl, tick, status_get_amotion(bl), 0, dmg, 1, skill_id, skill_lv, 6);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else { // Somehow, we failed
|
|
|
|
- skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
|
|
|
|
- status_zap(bl, 0, status_get_max_sp(bl) * 10 / 100);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else if (sd) {
|
|
|
|
- skill_area_temp[1] = bl->id;
|
|
|
|
- skill_area_temp[3] = skill_id;
|
|
|
|
- skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag|8); // Only do attack calculation once
|
|
|
|
- status_zap(bl, 0, status_get_max_sp(bl) * 10 / 100);
|
|
|
|
- map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
case SO_POISON_BUSTER: {
|
|
case SO_POISON_BUSTER: {
|
|
struct status_change *tsc2 = status_get_sc(bl);
|
|
struct status_change *tsc2 = status_get_sc(bl);
|
|
if( tsc2 && tsc2->data[SC_POISON] ) {
|
|
if( tsc2 && tsc2->data[SC_POISON] ) {
|
|
@@ -6703,8 +6702,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
case RK_STORMBLAST:
|
|
case RK_STORMBLAST:
|
|
case NC_AXETORNADO:
|
|
case NC_AXETORNADO:
|
|
case GC_COUNTERSLASH:
|
|
case GC_COUNTERSLASH:
|
|
- case SR_SKYNETBLOW:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP4:
|
|
|
|
case SR_RAMPAGEBLASTER:
|
|
case SR_RAMPAGEBLASTER:
|
|
case SR_HOWLINGOFLION:
|
|
case SR_HOWLINGOFLION:
|
|
case KO_HAPPOKUNAI:
|
|
case KO_HAPPOKUNAI:
|
|
@@ -6718,7 +6715,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
else
|
|
else
|
|
i = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src),
|
|
i = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src),
|
|
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
|
|
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
|
|
- if( !i && ( skill_id == NC_AXETORNADO || skill_id == SR_SKYNETBLOW || skill_id == KO_HAPPOKUNAI ) )
|
|
|
|
|
|
+ if( !i && ( skill_id == NC_AXETORNADO || skill_id == KO_HAPPOKUNAI ) )
|
|
clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
|
|
clif_skill_damage(src,src,tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, 6);
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -9608,6 +9605,37 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
clif_skill_nodamage(bl,src,skill_id,skill_lv,
|
|
clif_skill_nodamage(bl,src,skill_id,skill_lv,
|
|
sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
|
|
sc_start(src,bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
|
|
break;
|
|
break;
|
|
|
|
+
|
|
|
|
+ case SR_SKYNETBLOW: {
|
|
|
|
+ struct status_change *sc = status_get_sc(src);
|
|
|
|
+
|
|
|
|
+ clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, DMG_SKILL);
|
|
|
|
+ skill_area_temp[1] = 0;
|
|
|
|
+ if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO)
|
|
|
|
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1|4, skill_castend_damage_id);
|
|
|
|
+ else
|
|
|
|
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
|
|
+
|
|
|
|
+ case SR_TIGERCANNON:
|
|
|
|
+ clif_skill_damage(src, bl, tick, status_get_amotion(src), 0, -30000, 1, skill_id, skill_lv, DMG_SKILL);
|
|
|
|
+ skill_area_temp[1] = bl->id;
|
|
|
|
+ if (flag&2) { // For SR_FLASHCOMBO
|
|
|
|
+ skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
|
|
|
|
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
|
|
|
|
+ } else {
|
|
|
|
+ struct status_change *sc = status_get_sc(src);
|
|
|
|
+
|
|
|
|
+ if (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE) {
|
|
|
|
+ skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag|4);
|
|
|
|
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1|4, skill_castend_damage_id);
|
|
|
|
+ } else {
|
|
|
|
+ skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
|
|
|
|
+ map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), splash_target(src), src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ break;
|
|
case SR_CURSEDCIRCLE:
|
|
case SR_CURSEDCIRCLE:
|
|
if( flag&1 ) {
|
|
if( flag&1 ) {
|
|
if( is_boss(bl) ) break;
|
|
if( is_boss(bl) ) break;
|
|
@@ -9702,15 +9730,17 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
|
|
sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
|
|
break;
|
|
break;
|
|
case SR_FLASHCOMBO: {
|
|
case SR_FLASHCOMBO: {
|
|
- const int combo[] = { SR_FLASHCOMBO_ATK_STEP1, SR_FLASHCOMBO_ATK_STEP2, SR_FLASHCOMBO_ATK_STEP3, SR_FLASHCOMBO_ATK_STEP4 };
|
|
|
|
|
|
+ const int combo[] = { SR_DRAGONCOMBO, SR_FALLENEMPIRE, SR_TIGERCANNON, SR_SKYNETBLOW };
|
|
const int delay[] = { 0, 250, 500, 2000 };
|
|
const int delay[] = { 0, 250, 500, 2000 };
|
|
|
|
|
|
if (sd)
|
|
if (sd)
|
|
sd->ud.attackabletime = sd->canuseitem_tick = sd->ud.canact_tick;
|
|
sd->ud.attackabletime = sd->canuseitem_tick = sd->ud.canact_tick;
|
|
- clif_skill_nodamage(src,bl,skill_id,skill_lv,
|
|
|
|
- sc_start2(src,bl,type,100,skill_lv,bl->id,skill_get_time(skill_id,skill_lv)));
|
|
|
|
- for (i = 0; i < ARRAYLENGTH(combo); i++)
|
|
|
|
- skill_addtimerskill(src,tick + delay[i],bl->id,0,0,combo[i],skill_lv,BF_WEAPON,flag|SD_LEVEL);
|
|
|
|
|
|
+ clif_skill_nodamage(src, bl, skill_id, skill_lv, sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv)));
|
|
|
|
+ for (i = 0; i < ARRAYLENGTH(combo); i++) {
|
|
|
|
+ if (combo[i] == SR_TIGERCANNON)
|
|
|
|
+ flag |= 2;
|
|
|
|
+ skill_addtimerskill(src, tick + delay[i], bl->id, 0, 0, combo[i], skill_lv, BF_WEAPON, flag);
|
|
|
|
+ }
|
|
}
|
|
}
|
|
break;
|
|
break;
|
|
|
|
|
|
@@ -15388,7 +15418,10 @@ bool skill_check_condition_castend(struct map_session_data* sd, uint16 skill_id,
|
|
require = skill_get_requirement(sd,skill_id,skill_lv);
|
|
require = skill_get_requirement(sd,skill_id,skill_lv);
|
|
|
|
|
|
if( require.hp > 0 && status->hp <= (unsigned int)require.hp) {
|
|
if( require.hp > 0 && status->hp <= (unsigned int)require.hp) {
|
|
- clif_skill_fail(sd,skill_id,USESKILL_FAIL_HP_INSUFFICIENT,0);
|
|
|
|
|
|
+ if (skill_id == SR_TIGERCANNON)
|
|
|
|
+ clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
|
|
|
|
+ else
|
|
|
|
+ clif_skill_fail(sd, skill_id, USESKILL_FAIL_HP_INSUFFICIENT, 0);
|
|
return false;
|
|
return false;
|
|
}
|
|
}
|
|
|
|
|
|
@@ -16133,8 +16166,6 @@ int skill_delayfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv)
|
|
case CH_CHAINCRUSH:
|
|
case CH_CHAINCRUSH:
|
|
case SR_DRAGONCOMBO:
|
|
case SR_DRAGONCOMBO:
|
|
case SR_FALLENEMPIRE:
|
|
case SR_FALLENEMPIRE:
|
|
- case SR_FLASHCOMBO_ATK_STEP1:
|
|
|
|
- case SR_FLASHCOMBO_ATK_STEP2:
|
|
|
|
//If delay not specified, it will be 1000 - 4*agi - 2*dex
|
|
//If delay not specified, it will be 1000 - 4*agi - 2*dex
|
|
if (time == 0)
|
|
if (time == 0)
|
|
time = 1000;
|
|
time = 1000;
|