diff --git a/db/re/skill_db.txt b/db/re/skill_db.txt index 238945919a..425201d1cc 100644 --- a/db/re/skill_db.txt +++ b/db/re/skill_db.txt @@ -1325,10 +1325,10 @@ 5012,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, WL_TELEKINESIS_INTENSE,Intense Telekinesis 5013,0,6,4,0,0x3,0,5,1,no,0,0,0,none,0,0x0, LG_KINGS_GRACE,King's Grace 5014,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, ALL_FULL_THROTTLE,Full Throttle -5015,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SR_FLASHCOMBO_ATK_STEP1,Flash Combo Attack Step 1 -5016,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SR_FLASHCOMBO_ATK_STEP2,Flash Combo Attack Step 2 -5017,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SR_FLASHCOMBO_ATK_STEP3,Flash Combo Attack Step 3 -5018,0,6,4,0,0x1,0,5,1,no,0,0,0,none,0,0x0, SR_FLASHCOMBO_ATK_STEP4,Flash Combo Attack Step 4 +5015,-2,8,1,-1,0,0,10,-2,no,0,0,0,weapon,0,0x0, SR_FLASHCOMBO_ATK_STEP1,Flash Combo Attack Step 1 +5016,-2,8,4,-1,0,0,5,-2,no,0,0x200,0,weapon,0,0x0, SR_FLASHCOMBO_ATK_STEP2,Flash Combo Attack Step 2 +5017,-2,6,1,-1,0x42,1:1:1:1:1:2:2:2:2:2,10,1,yes,0,0,0,weapon,0,0x0, SR_FLASHCOMBO_ATK_STEP3,Flash Combo Attack Step 3 +5018,0,8,4,-1,0x2,2,5,-3,no,0,0,0,weapon,3,0x0, SR_FLASHCOMBO_ATK_STEP4,Flash Combo Attack Step 4 //**** // Homunculus S diff --git a/db/re/skill_require_db.txt b/db/re/skill_require_db.txt index 7b962bdfbb..5ffe78dde2 100644 --- a/db/re/skill_require_db.txt +++ b/db/re/skill_require_db.txt @@ -759,7 +759,7 @@ 2327,0,0,8:9:10:11:12,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_SKYNETBLOW 2328,0,0,36:40:44:48:52,0,0,0,99,0,0,none,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_EARTHSHAKER 2329,0,0,20:30:40:50:60,0,0,0,99,0,0,none,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FALLENEMPIRE -2330,0,0,1:2:3:4:5:6:7:8:9:10,0,0,0,99,0,0,none,SC_EXPLOSIONSPIRITS,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_TIGERCANNON +2330,0,0,1:2:3:4:5:6:7:8:9:10,-12:-14:-16:-18:-20:-22:-24:-26:-28:-30,-6:-7:-8:-9:-10:-11:-12:-13:-14:-15,0,99,0,0,none,SC_EXPLOSIONSPIRITS,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_TIGERCANNON 2331,0,0,1,0,-11:-12:-13:-14:-15:-16:-17:-18:-19:-20,0,99,0,0,none,0,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_HELLGATE 2332,0,0,150,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_RAMPAGEBLASTER 2333,0,0,80,0,0,0,99,0,0,none,0,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_CRESCENTELBOW @@ -971,10 +971,10 @@ 5012,0,0,100:150:200:250:300,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //WL_TELEKINESIS_INTENSE 5013,0,0,200:180:160:140:120,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //LG_KINGS_GRACE 5014,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //ALL_FULL_THROTTLE -5015,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FLASHCOMBO_ATK_STEP1 //All 4 steps are using temp req SP values for now. -5016,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FLASHCOMBO_ATK_STEP2 -5017,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FLASHCOMBO_ATK_STEP3 -5018,0,0,1,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FLASHCOMBO_ATK_STEP4 +5015,0,0,0,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FLASHCOMBO_ATK_STEP1 //All 4 steps are using temp req SP values for now. +5016,0,0,0,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FLASHCOMBO_ATK_STEP2 +5017,0,0,0,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FLASHCOMBO_ATK_STEP3 +5018,0,0,0,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //SR_FLASHCOMBO_ATK_STEP4 8001,0,0,13:16:19:22:25,0,0,0,99,0,0,none,0,0,545,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //HLIF_HEAL 8002,0,0,20:25:30:35:40,0,0,0,99,0,0,none,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 //HLIF_AVOID diff --git a/src/map/battle.c b/src/map/battle.c index 0503970d08..7c9e7d0090 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -3881,17 +3881,6 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s if( sc && sc->data[SC_INSPIRATION] ) skillratio += 600; break; - case SR_DRAGONCOMBO: - skillratio += 40 * skill_lv; - RE_LVL_DMOD(100); - break; - case SR_SKYNETBLOW: - //ATK [{(Skill Level x 80) + (Caster AGI)} x Caster Base Level / 100] % - skillratio = 80 * skill_lv + status_get_agi(src); - if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO )//ATK [{(Skill Level x 100) + (Caster AGI) + 150} x Caster Base Level / 100] % - skillratio = 100 * skill_lv + status_get_agi(src) + 150; - RE_LVL_DMOD(100); - break; case SR_EARTHSHAKER: if( tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] || // [(Skill Level x 150) x (Caster Base Level / 100) + (Caster INT x 3)] % tsc->data[SC_CHASEWALK] || tsc->data[SC_CLOAKINGEXCEED] || tsc->data[SC__INVISIBILITY]) ){ @@ -3904,21 +3893,43 @@ static int battle_calc_attack_skill_ratio(struct Damage wd, struct block_list *s skillratio += status_get_int(src) * 2; } break; - case SR_FALLENEMPIRE:// ATK [(Skill Level x 150 + 100) x Caster Base Level / 150] % - skillratio += 150 *skill_lv; + + case SR_DRAGONCOMBO: + case SR_FLASHCOMBO_ATK_STEP1: + skillratio += 40 * skill_lv; + RE_LVL_DMOD(100); + break; + case SR_FALLENEMPIRE: + case SR_FLASHCOMBO_ATK_STEP2: + // ATK [(Skill Level x 150 + 100) x Caster Base Level / 150] % + skillratio += 150 * skill_lv; RE_LVL_DMOD(150); break; - case SR_TIGERCANNON:// ATK [((Caster consumed HP + SP) / 4) x Caster Base Level / 100] % + case SR_TIGERCANNON: + case SR_FLASHCOMBO_ATK_STEP3: { - int hp = (int64)status_get_max_hp(src) * (10 + 2 * skill_lv) / 100, - sp = (int64)status_get_max_sp(src) * (5 + 1 * skill_lv) / 100; - if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // ATK [((Caster consumed HP + SP) / 2) x Caster Base Level / 100] % - skillratio = ((int64)hp+sp) / 2; + int hp = sstatus->max_hp * (10 + 2 * skill_lv) / 100, // skill_get_hp_rate(SR_TIGERCANNON, skill_lv) + sp = sstatus->max_sp * (5 + 1 * skill_lv) / 100; // skill_get_sp_rate(SR_TIGERCANNON, skill_lv) + if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) + // Base_Damage = [((Caster consumed HP + SP) / 2) x Caster Base Level / 100] % + skillratio += ((hp+sp) / 2); else - skillratio = ((int64)hp+sp) / 4; + // Base_Damage = [((Caster consumed HP + SP) / 4) x Caster Base Level / 100] % + skillratio += ((hp+sp) / 4); RE_LVL_DMOD(100); } break; + case SR_SKYNETBLOW: + case SR_FLASHCOMBO_ATK_STEP4: + if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_DRAGONCOMBO ) + //ATK [{(Skill Level x 100) + (Caster AGI) + 150} x Caster Base Level / 100] % + skillratio += (100 * skill_lv + sstatus->agi + 150); + else + //ATK [{(Skill Level x 80) + (Caster AGI)} x Caster Base Level / 100] % + skillratio += (80 * skill_lv + sstatus->agi); + RE_LVL_DMOD(100); + break; + case SR_RAMPAGEBLASTER: skillratio = 20 * skill_lv * ((sd) ? sd->spiritball_old : 5); if( sc && sc->data[SC_EXPLOSIONSPIRITS] ) { @@ -4245,16 +4256,20 @@ static int battle_calc_skill_constant_addition(struct Damage wd, struct block_li atk = damagevalue; } break; - case SR_TIGERCANNON: // (Tiger Cannon skill level x 240) + (Target Base Level x 40) - if( sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE ) // (Tiger Cannon skill level x 500) + (Target Base Level x 40) + case SR_TIGERCANNON: + case SR_FLASHCOMBO_ATK_STEP3: + // (Tiger Cannon skill level x 240) + (Target Base Level x 40) + if( skill_id == SR_FLASHCOMBO_ATK_STEP3 || (sc && sc->data[SC_COMBO] && sc->data[SC_COMBO]->val1 == SR_FALLENEMPIRE) ) atk = ( skill_lv * 500 + status_get_lv(target) * 40 ); else atk = ( skill_lv * 240 + status_get_lv(target) * 40 ); break; - case SR_FALLENEMPIRE:// [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)] - atk = ( ((tstatus->size+1)*2 + skill_lv - 1) * status_get_str(src)); + case SR_FALLENEMPIRE: + case SR_FLASHCOMBO_ATK_STEP2: + // [(Target Size value + Skill Level - 1) x Caster STR] + [(Target current weight x Caster DEX / 120)] + atk = ( ((tstatus->size+1)*2 + skill_lv - 1) * sstatus->str); if( tsd && tsd->weight ) - atk += ( (tsd->weight/10) * status_get_dex(src) / 120 ); + atk += ( (tsd->weight/10) * sstatus->dex / 120 ); else atk += ( status_get_lv(target) * 50 ); //mobs break; @@ -4399,6 +4414,14 @@ struct Damage battle_attack_sc_bonus(struct Damage wd, struct block_list *src, s break; } } + + if (sc->data[SC_FLASHCOMBO]) { + ATK_ADD(wd.damage, wd.damage2, sc->data[SC_FLASHCOMBO]->val2); +#ifdef RENEWAL + ATK_ADD(wd.equipAtk, wd.equipAtk2, sc->data[SC_FLASHCOMBO]->val2); +#endif + } + if((wd.flag&(BF_LONG|BF_MAGIC)) == BF_LONG) { // Monster Transformation bonus if (sc->data[SC_MTF_RANGEATK]) { ATK_ADDRATE(wd.damage, wd.damage2, sc->data[SC_MTF_RANGEATK]->val1); @@ -5140,7 +5163,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl // check if we're landing a hit if(!is_attack_hitting(wd, src, target, skill_id, skill_lv, true)) wd.dmg_lv = ATK_FLEE; - else if(!is_infinite_defense(target, wd.flag)) { //no need for math against plants + else if(wd.miscflag&8 || !is_infinite_defense(target, wd.flag)) { //no need for math against plants int ratio, i = 0; wd = battle_calc_skill_base_damage(wd, src, target, skill_id, skill_lv); // base skill damage @@ -5382,7 +5405,7 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl DAMAGE_DIV_FIX_RENEWAL(wd, wd.div_); #endif // only do 1 dmg to plant, no need to calculate rest - if(is_infinite_defense(target, wd.flag)) + if(!(wd.miscflag&8) && is_infinite_defense(target, wd.flag)) return battle_calc_attack_plant(wd, src, target, skill_id, skill_lv); //Apply DAMAGE_DIV_FIX and check for min damage diff --git a/src/map/battle.h b/src/map/battle.h index a8806613b3..8bf2f7a32d 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -81,6 +81,7 @@ struct block_list; // Damage Calculation struct Damage battle_calc_attack(int attack_type,struct block_list *bl,struct block_list *target,uint16 skill_id,uint16 skill_lv,int flag); +struct Damage battle_calc_attack_plant(struct Damage wd, struct block_list *src,struct block_list *target, uint16 skill_id, uint16 skill_lv); int64 battle_calc_return_damage(struct block_list *bl, struct block_list *src, int64 *, int flag, uint16 skill_id, bool status_reflect); diff --git a/src/map/skill.c b/src/map/skill.c index eb0585fc57..155b1cb9bf 100755 --- a/src/map/skill.c +++ b/src/map/skill.c @@ -1464,10 +1464,12 @@ 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); break; case SR_DRAGONCOMBO: - sc_start(src,bl, SC_STUN, 1 + skill_lv, skill_lv, skill_get_time(skill_id, skill_lv)); + case SR_FLASHCOMBO_ATK_STEP1: + sc_start(src,bl, SC_STUN, 1 + skill_lv, skill_lv, skill_get_time(SR_DRAGONCOMBO, skill_lv)); break; case SR_FALLENEMPIRE: - sc_start(src,bl, SC_STOP, 100, skill_lv, skill_get_time(skill_id, skill_lv)); + case SR_FLASHCOMBO_ATK_STEP2: + sc_start(src,bl, SC_STOP, 100, skill_lv, skill_get_time(SR_FALLENEMPIRE, skill_lv)); break; case SR_WINDMILL: if( dstsd ) @@ -2421,6 +2423,7 @@ int skill_strip_equip(struct block_list *src,struct block_list *bl, unsigned sho * [2] counts how many targets have been processed. counter is added in skill_area_sub if the foreach function flag is: flag&(SD_SPLASH|SD_PREAMBLE) */ static int skill_area_temp[8]; +static int64 skill_area_temp_i64[1]; /** Used to knock back players, monsters, traps, etc @@ -2891,8 +2894,10 @@ void skill_attack_blow(struct block_list *src, struct block_list *dsrc, struct b * flag&1 * flag&2 - Disable re-triggered by double casting * flag&4 - Skip to blow target (because already knocked back before skill_attack somewhere) + * flag&8 - Force assume the target is not as is_infinite_defense() on in battle_calc_attack() first. + * Once it's done, store the damage to skill_area_temp_i64[0] then re-calcuate for real against 'plant'. * - * flag&0xFFF is passed to the underlying battle_calc_attack for processing + * flag&0xFFF is passed to the underlying battle_calc_attack for processing. * (usually holds number of targets, or just 1 for simple splash attacks) * * flag&0xF000 - Values from enum e_skill_display @@ -3059,6 +3064,14 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list * 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; + } + } + if( damage && tsc && tsc->data[SC_GENSOU] && dmg.flag&BF_MAGIC ){ struct block_list *nbl; nbl = battle_getenemyarea(bl,bl->x,bl->y,2,BL_CHAR,bl->id); @@ -3760,10 +3773,10 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) case WL_TETRAVORTEX_WIND: case WL_TETRAVORTEX_GROUND: // For SR_FLASHCOMBO - case SR_DRAGONCOMBO: - case SR_FALLENEMPIRE: - case SR_TIGERCANNON: - case SR_SKYNETBLOW: + case SR_FLASHCOMBO_ATK_STEP1: + case SR_FLASHCOMBO_ATK_STEP2: + case SR_FLASHCOMBO_ATK_STEP3: + case SR_FLASHCOMBO_ATK_STEP4: break; // Exceptions default: continue; // Caster is Dead @@ -3913,14 +3926,15 @@ static int skill_timerskill(int tid, unsigned int tick, int id, intptr_t data) break; } // For SR_FLASHCOMBO - case SR_DRAGONCOMBO: - case SR_FALLENEMPIRE: - case SR_TIGERCANNON: - case SR_SKYNETBLOW: + 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 ) break; - skill_castend_damage_id(src, target, skl->skill_id, pc_checkskill(((TBL_PC *)src), skl->skill_id), tick, 0); + 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); } break; case SC_ESCAPE: @@ -4041,10 +4055,10 @@ int skill_cleartimerskill (struct block_list *src) case WL_TETRAVORTEX_WIND: case WL_TETRAVORTEX_GROUND: // For SR_FLASHCOMBO - case SR_DRAGONCOMBO: - case SR_FALLENEMPIRE: - case SR_TIGERCANNON: - case SR_SKYNETBLOW: + case SR_FLASHCOMBO_ATK_STEP1: + case SR_FLASHCOMBO_ATK_STEP2: + case SR_FLASHCOMBO_ATK_STEP3: + case SR_FLASHCOMBO_ATK_STEP4: continue; } delete_timer(ud->skilltimerskill[i]->timer, skill_timerskill); @@ -4237,6 +4251,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case LG_OVERBRAND: case LG_OVERBRAND_BRANDISH: case SR_FALLENEMPIRE: + case SR_FLASHCOMBO_ATK_STEP2: case SR_CRESCENTELBOW_AUTOSPELL: case SR_GATEOFHELL: case SR_GENTLETOUCH_QUIET: @@ -4467,6 +4482,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint case LG_EARTHDRIVE: case SR_RAMPAGEBLASTER: case SR_SKYNETBLOW: + case SR_FLASHCOMBO_ATK_STEP4: case SR_WINDMILL: case SR_RIDEINLIGHTNING: case WM_SOUND_OF_DESTRUCTION: @@ -5247,6 +5263,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint break; case SR_DRAGONCOMBO: + case SR_FLASHCOMBO_ATK_STEP1: skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag); break; @@ -5298,17 +5315,30 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint break; case SR_TIGERCANNON: - if ( flag&1 ) { - 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 ) { - int hpcost = 10 + 2 * skill_lv, spcost = 5 + 1 * skill_lv; - if (!status_charge(src, status_get_max_hp(src) * hpcost / 100, status_get_max_sp(src) * spcost / 100)) { - if (sd) - clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0); - break; + 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); + } } - 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|1, skill_castend_damage_id); + 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; @@ -6557,6 +6587,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui case NC_AXETORNADO: case GC_COUNTERSLASH: case SR_SKYNETBLOW: + case SR_FLASHCOMBO_ATK_STEP4: case SR_RAMPAGEBLASTER: case SR_HOWLINGOFLION: case KO_HAPPOKUNAI: @@ -9519,14 +9550,15 @@ 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))); break; case SR_FLASHCOMBO: { - const int combo[] = { SR_DRAGONCOMBO, SR_FALLENEMPIRE, SR_TIGERCANNON, SR_SKYNETBLOW }; + const int combo[] = { SR_FLASHCOMBO_ATK_STEP1, SR_FLASHCOMBO_ATK_STEP2, SR_FLASHCOMBO_ATK_STEP3, SR_FLASHCOMBO_ATK_STEP4 }; + const int delay[] = { 0, 250, 500, 2000 }; if (sd) 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 + 500 * i,bl->id,0,0,combo[i],skill_lv,BF_WEAPON,flag|SD_LEVEL); + skill_addtimerskill(src,tick + delay[i],bl->id,0,0,combo[i],skill_lv,BF_WEAPON,flag|SD_LEVEL); } break; @@ -15820,6 +15852,8 @@ int skill_delayfix (struct block_list *bl, uint16 skill_id, uint16 skill_lv) case CH_CHAINCRUSH: case SR_DRAGONCOMBO: 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 (time == 0) time = 1000; diff --git a/src/map/skill.h b/src/map/skill.h index 3c35943fe5..958752256e 100644 --- a/src/map/skill.h +++ b/src/map/skill.h @@ -1720,10 +1720,10 @@ enum e_skill { WL_TELEKINESIS_INTENSE, LG_KINGS_GRACE, ALL_FULL_THROTTLE, - SR_FLASHCOMBO_ATK_STEP1, - SR_FLASHCOMBO_ATK_STEP2, - SR_FLASHCOMBO_ATK_STEP3, - SR_FLASHCOMBO_ATK_STEP4, + SR_FLASHCOMBO_ATK_STEP1, // SR_DRAGONCOMBO + SR_FLASHCOMBO_ATK_STEP2, // SR_FALLENEMPIRE + SR_FLASHCOMBO_ATK_STEP3, // SR_TIGERCANNON + SR_FLASHCOMBO_ATK_STEP4, // SR_SKYNETBLOW HLIF_HEAL = 8001, HLIF_AVOID, diff --git a/src/map/status.c b/src/map/status.c index 4a764f1de6..51b23f1fd9 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -709,7 +709,8 @@ void initChangeTables(void) 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_WATK|SCB_MDEF|SCB_ASPD ); set_sc( SR_GENTLETOUCH_REVITALIZE , SC_GT_REVITALIZE , SI_GENTLETOUCH_REVITALIZE , SCB_MAXHP|SCB_REGEN ); - set_sc( SR_FLASHCOMBO , SC_FLASHCOMBO , SI_FLASHCOMBO , SCB_WATK ); + set_sc( SR_FLASHCOMBO , SC_FLASHCOMBO , SI_FLASHCOMBO , SCB_NONE ); + add_sc( SR_FLASHCOMBO_ATK_STEP1 , SC_STUN ); /* Wanderer / Minstrel */ set_sc( WA_SWING_DANCE , SC_SWINGDANCE , SI_SWINGDANCE , SCB_SPEED|SCB_ASPD ); @@ -5467,8 +5468,6 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan watk += sc->data[SC_PYROCLASTIC]->val2; if(sc->data[SC_ANGRIFFS_MODUS]) watk += watk * sc->data[SC_ANGRIFFS_MODUS]->val2/100; - if( sc->data[SC_FLASHCOMBO] ) - watk += sc->data[SC_FLASHCOMBO]->val2; if(sc->data[SC_ODINS_POWER]) watk += 40 + 30 * sc->data[SC_ODINS_POWER]->val1;