|
@@ -4794,6 +4794,29 @@ static TIMER_FUNC(skill_timerskill){
|
|
|
skill_unitsetting(src, skl->skill_id, skl->skill_lv, tmpx, tmpy, skill_get_unit_interval(skl->skill_id));
|
|
|
}
|
|
|
break;
|
|
|
+ case NW_HASTY_FIRE_IN_THE_HOLE:
|
|
|
+ skill_castend_pos2(src, skl->x, skl->y, skl->skill_id, skl->skill_lv, tick, skl->flag);
|
|
|
+ break;
|
|
|
+ case NW_GRENADES_DROPPING: {
|
|
|
+ int area = skill_get_splash(skl->skill_id, skl->skill_lv);
|
|
|
+ short tmpx = 0, tmpy = 0;
|
|
|
+
|
|
|
+ tmpx = skl->x - area + rnd() % (area * 2 + 1);
|
|
|
+ tmpy = skl->y - area + rnd() % (area * 2 + 1);
|
|
|
+ skill_unitsetting(src, skl->skill_id, skl->skill_lv, tmpx, tmpy, skl->flag);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case NW_MISSION_BOMBARD: {
|
|
|
+ int area = skill_get_unit_range(skl->skill_id, skl->skill_lv);
|
|
|
+ int range = skill_get_splash(skl->skill_id, skl->skill_lv);
|
|
|
+ short tmpx = 0, tmpy = 0;
|
|
|
+
|
|
|
+ tmpx = skl->x - range + rnd() % (range * 2 + 1);
|
|
|
+ tmpy = skl->y - range + rnd() % (range * 2 + 1);
|
|
|
+ map_foreachinarea(skill_area_sub, src->m, tmpx - range, tmpy - range, tmpx + range, tmpy + range, BL_CHAR,
|
|
|
+ src, skl->skill_id, skl->skill_lv, tick, skl->flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
|
|
|
+ }
|
|
|
+ break;
|
|
|
}
|
|
|
}
|
|
|
} while (0);
|
|
@@ -5235,6 +5258,10 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
|
case ABR_DUAL_CANNON_FIRE:
|
|
|
case ABR_INFINITY_BUSTER:
|
|
|
case MT_TRIPLE_LASER:
|
|
|
+ case NW_MISSION_BOMBARD:
|
|
|
+ case NW_HASTY_FIRE_IN_THE_HOLE:
|
|
|
+ case NW_BASIC_GRENADE:
|
|
|
+ case NW_WILD_FIRE:
|
|
|
skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
|
|
|
break;
|
|
|
case DK_DRAGONIC_AURA:
|
|
@@ -5916,6 +5943,24 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
|
}
|
|
|
}
|
|
|
break;
|
|
|
+ case NW_THE_VIGILANTE_AT_NIGHT:
|
|
|
+ if (flag & 1)
|
|
|
+ skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
|
|
|
+ break;
|
|
|
+ case NW_SPIRAL_SHOOTING:
|
|
|
+ if (flag & 1) {
|
|
|
+ skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
|
|
|
+ } else {
|
|
|
+ int splash = skill_get_splash(skill_id, skill_lv);
|
|
|
+
|
|
|
+ if (sd && sd->weapontype1 == W_GRENADE)
|
|
|
+ splash += 2;
|
|
|
+ clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
|
|
|
+ map_foreachinrange(skill_area_sub, bl, splash, BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
|
|
|
+ if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
|
|
+ status_change_end(src, SC_INTENSIVE_AIM_COUNT);
|
|
|
+ }
|
|
|
+ break;
|
|
|
|
|
|
//Place units around target
|
|
|
case NJ_BAKUENRYU:
|
|
@@ -7077,6 +7122,13 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
+ case NW_MAGAZINE_FOR_ONE:
|
|
|
+ case NW_ONLY_ONE_BULLET:
|
|
|
+ skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
|
|
|
+ if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
|
|
+ status_change_end(src, SC_INTENSIVE_AIM_COUNT);
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
ShowWarning("skill_castend_damage_id: Unknown skill used:%d\n",skill_id);
|
|
|
clif_skill_damage(src, bl, tick, status_get_amotion(src), tstatus->dmotion,
|
|
@@ -7101,7 +7153,8 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
|
|
|
}
|
|
|
|
|
|
// perform skill requirement consumption
|
|
|
- skill_consume_requirement(sd,skill_id,skill_lv,2);
|
|
|
+ if (!(flag&SKILL_NOCONSUME_REQ))
|
|
|
+ skill_consume_requirement(sd,skill_id,skill_lv,2);
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -7297,6 +7350,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
|
|
|
type = skill_get_sc(skill_id);
|
|
|
tsc = status_get_sc(bl);
|
|
|
+ status_change* sc = status_get_sc(src);
|
|
|
tsce = (tsc && type != SC_NONE)?tsc->getSCE(type):NULL;
|
|
|
|
|
|
if (src!=bl && type > SC_NONE &&
|
|
@@ -7651,8 +7705,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
return 1;
|
|
|
}
|
|
|
|
|
|
- status_change* sc = status_get_sc(src);
|
|
|
-
|
|
|
if( sc && tsc )
|
|
|
{
|
|
|
if( !sc->getSCE(SC_MARIONETTE) && !tsc->getSCE(SC_MARIONETTE2) )
|
|
@@ -8025,7 +8077,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
sc_start(src, bl, type, 100, skill_lv, skill_get_time2(skill_id, skill_lv));
|
|
|
} else {
|
|
|
uint16 climax_lv = 0, splash_size = skill_get_splash(skill_id, skill_lv);
|
|
|
- status_change *sc = status_get_sc(src);
|
|
|
|
|
|
if (sc && sc->getSCE(SC_CLIMAX))
|
|
|
climax_lv = sc->getSCE(SC_CLIMAX)->val1;
|
|
@@ -8566,7 +8617,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
case ABC_ABYSS_DAGGER:
|
|
|
case BO_EXPLOSIVE_POWDER:
|
|
|
{
|
|
|
- status_change *sc = status_get_sc(src);
|
|
|
int starget = BL_CHAR|BL_SKILL;
|
|
|
|
|
|
if (skill_id == SR_HOWLINGOFLION)
|
|
@@ -11176,8 +11226,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
case WL_SUMMONWB:
|
|
|
case WL_SUMMONSTONE:
|
|
|
{
|
|
|
- status_change *sc = status_get_sc(src);
|
|
|
-
|
|
|
if (sc == nullptr)
|
|
|
break;
|
|
|
|
|
@@ -11687,7 +11735,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
case WM_LERADS_DEW:
|
|
|
case WM_UNLIMITED_HUMMING_VOICE:
|
|
|
if( flag&1 ) { // These affect to to all party members near the caster.
|
|
|
- status_change *sc = status_get_sc(src);
|
|
|
if( sc && sc->getSCE(type) ) {
|
|
|
sc_start2(src,bl,type,100,skill_lv,pc_checkskill(sd, WM_LESSON),skill_get_time(skill_id,skill_lv));
|
|
|
}
|
|
@@ -12094,9 +12141,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
s_elemental_data *ele = BL_CAST(BL_ELEM, src);
|
|
|
if( ele ) {
|
|
|
sc_type type2 = (sc_type)(type-1);
|
|
|
- status_change *sc = status_get_sc(&ele->bl);
|
|
|
+ status_change *esc = status_get_sc(&ele->bl);
|
|
|
|
|
|
- if( (sc && sc->getSCE(type2)) || (tsc && tsc->getSCE(type)) ) {
|
|
|
+ if( (esc && esc->getSCE(type2)) || (tsc && tsc->getSCE(type)) ) {
|
|
|
status_change_end(src,type);
|
|
|
status_change_end(bl,type2);
|
|
|
} else {
|
|
@@ -12121,11 +12168,11 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
case EL_WATER_SCREEN: {
|
|
|
s_elemental_data *ele = BL_CAST(BL_ELEM, src);
|
|
|
if( ele ) {
|
|
|
- status_change *sc = status_get_sc(&ele->bl);
|
|
|
+ status_change *esc = status_get_sc(&ele->bl);
|
|
|
sc_type type2 = (sc_type)(type-1);
|
|
|
|
|
|
clif_skill_nodamage(src,src,skill_id,skill_lv,1);
|
|
|
- if( (sc && sc->getSCE(type2)) || (tsc && tsc->getSCE(type)) ) {
|
|
|
+ if( (esc && esc->getSCE(type2)) || (tsc && tsc->getSCE(type)) ) {
|
|
|
status_change_end(bl,type);
|
|
|
status_change_end(src,type2);
|
|
|
} else {
|
|
@@ -12865,6 +12912,54 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | 1, skill_castend_damage_id);
|
|
|
break;
|
|
|
|
|
|
+ case NW_THE_VIGILANTE_AT_NIGHT:
|
|
|
+ i = skill_get_splash(skill_id, skill_lv);
|
|
|
+ skill_area_temp[0] = 0;
|
|
|
+ skill_area_temp[1] = bl->id;
|
|
|
+ skill_area_temp[2] = 0;
|
|
|
+
|
|
|
+ if (sd && sd->weapontype1 == W_GATLING) {
|
|
|
+ i += 3;
|
|
|
+ clif_skill_nodamage(src, bl, NW_THE_VIGILANTE_AT_NIGHT_GUN_GATLING, skill_lv, 1);
|
|
|
+ } else
|
|
|
+ clif_skill_nodamage(src, bl, NW_THE_VIGILANTE_AT_NIGHT_GUN_SHOTGUN, skill_lv, 1);
|
|
|
+ map_foreachinrange(skill_area_sub, bl, i, BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id);
|
|
|
+ if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
|
|
+ status_change_end(src, SC_INTENSIVE_AIM_COUNT);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case NW_INTENSIVE_AIM:
|
|
|
+ if (tsc && tsc->getSCE(type)) {
|
|
|
+ status_change_end(src, SC_INTENSIVE_AIM_COUNT);
|
|
|
+ status_change_end(bl, type);
|
|
|
+ } else {
|
|
|
+ status_change_end(src, SC_INTENSIVE_AIM_COUNT);
|
|
|
+ sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
|
|
|
+ }
|
|
|
+ clif_skill_nodamage(src, src, skill_id, skill_lv, 1);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case NW_HIDDEN_CARD:
|
|
|
+ case NW_AUTO_FIRING_LAUNCHER:
|
|
|
+ sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
|
|
|
+ clif_skill_nodamage(src, src, skill_id, skill_lv, 1);
|
|
|
+ break;
|
|
|
+
|
|
|
+ case NW_GRENADE_FRAGMENT:
|
|
|
+ status_change_end(src, type);
|
|
|
+ if (skill_lv < 7)
|
|
|
+ sc_start(src, bl, (sc_type)(SC_GRENADE_FRAGMENT_1 -1 + skill_lv), 100, skill_lv, skill_get_time(skill_id, skill_lv));
|
|
|
+ else if (skill_lv == 7) {
|
|
|
+ status_change_end(src, SC_GRENADE_FRAGMENT_1);
|
|
|
+ status_change_end(src, SC_GRENADE_FRAGMENT_2);
|
|
|
+ status_change_end(src, SC_GRENADE_FRAGMENT_3);
|
|
|
+ status_change_end(src, SC_GRENADE_FRAGMENT_4);
|
|
|
+ status_change_end(src, SC_GRENADE_FRAGMENT_5);
|
|
|
+ status_change_end(src, SC_GRENADE_FRAGMENT_6);
|
|
|
+ }
|
|
|
+ clif_skill_nodamage(src, src, skill_id, skill_lv, 1);
|
|
|
+ break;
|
|
|
+
|
|
|
default: {
|
|
|
std::shared_ptr<s_skill_db> skill = skill_db.find(skill_id);
|
|
|
ShowWarning("skill_castend_nodamage_id: missing code case for skill %s(%d)\n", skill ? skill->name : "UNKNOWN", skill_id);
|
|
@@ -12875,8 +12970,6 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
}
|
|
|
|
|
|
if (skill_id != SR_CURSEDCIRCLE && skill_id != NPC_SR_CURSEDCIRCLE) {
|
|
|
- status_change *sc = status_get_sc(src);
|
|
|
-
|
|
|
if (sc && sc->getSCE(SC_CURSEDCIRCLE_ATKER)) // Should only remove after the skill had been casted.
|
|
|
status_change_end(src,SC_CURSEDCIRCLE_ATKER);
|
|
|
}
|
|
@@ -12896,7 +12989,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
|
|
}
|
|
|
skill_onskillusage(sd, bl, skill_id, tick);
|
|
|
// perform skill requirement consumption
|
|
|
- skill_consume_requirement(sd,skill_id,skill_lv,2);
|
|
|
+ if (!(flag&SKILL_NOCONSUME_REQ))
|
|
|
+ skill_consume_requirement(sd,skill_id,skill_lv,2);
|
|
|
}
|
|
|
|
|
|
map_freeblock_unlock();
|
|
@@ -13603,6 +13697,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
|
|
case SU_CN_METEOR:
|
|
|
case NPC_RAINOFMETEOR:
|
|
|
case HN_METEOR_STORM_BUSTER:
|
|
|
+ case NW_GRENADES_DROPPING:
|
|
|
break; //Effect is displayed on respective switch case.
|
|
|
default:
|
|
|
if(skill_get_inf(skill_id)&INF_SELF_SKILL)
|
|
@@ -13643,6 +13738,7 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
|
|
break;
|
|
|
|
|
|
case SR_RIDEINLIGHTNING:
|
|
|
+ case NW_BASIC_GRENADE:
|
|
|
i = skill_get_splash(skill_id, skill_lv);
|
|
|
map_foreachinallarea(skill_area_sub, src->m, x-i, y-i, x+i, y+i, BL_CHAR,
|
|
|
src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_damage_id);
|
|
@@ -14545,6 +14641,53 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
|
|
}
|
|
|
break;
|
|
|
|
|
|
+ case NW_WILD_FIRE:
|
|
|
+ i = skill_get_splash(skill_id, skill_lv);
|
|
|
+ if (sd && sd->status.weapon == W_GRENADE)
|
|
|
+ i += 2;
|
|
|
+ map_foreachinallarea(skill_area_sub,
|
|
|
+ src->m, x - i, y - i, x + i, y + i, BL_CHAR,
|
|
|
+ src, skill_id, skill_lv, tick, flag | BCT_ENEMY | 1,
|
|
|
+ skill_castend_damage_id);
|
|
|
+ if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
|
|
+ status_change_end(src, SC_INTENSIVE_AIM_COUNT);
|
|
|
+ break;
|
|
|
+ case NW_HASTY_FIRE_IN_THE_HOLE:
|
|
|
+ i = skill_get_splash(skill_id, skill_lv);
|
|
|
+ if (flag & 1){
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ if (flag & 2){
|
|
|
+ i++;
|
|
|
+ }
|
|
|
+ map_foreachinallarea(skill_area_sub,
|
|
|
+ src->m, x - i, y - i, x + i, y + i, BL_CHAR,
|
|
|
+ src, skill_id, skill_lv, tick, flag | BCT_ENEMY | 1,
|
|
|
+ skill_castend_damage_id);
|
|
|
+ if (!(flag & 1)) {
|
|
|
+ skill_addtimerskill(src, tick + 300, 0, x, y, skill_id, skill_lv, 0, flag | 1 | SKILL_NOCONSUME_REQ);
|
|
|
+ skill_addtimerskill(src, tick + 600, 0, x, y, skill_id, skill_lv, 0, flag | 3 | SKILL_NOCONSUME_REQ);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ case NW_GRENADES_DROPPING: {
|
|
|
+ uint16 splash = skill_get_splash(skill_id, skill_lv);
|
|
|
+ uint16 tmpx = rnd_value( x - splash, x + splash );
|
|
|
+ uint16 tmpy = rnd_value( y - splash, y + splash );
|
|
|
+ skill_unitsetting(src, skill_id, skill_lv, tmpx, tmpy, flag);
|
|
|
+ for (i = 0; i <= (skill_get_time(skill_id, skill_lv) / skill_get_unit_interval(skill_id)); i++) {
|
|
|
+ skill_addtimerskill(src, tick + (t_tick)i*skill_get_unit_interval(skill_id), 0, x, y, skill_id, skill_lv, 0, flag);
|
|
|
+ }
|
|
|
+ } break;
|
|
|
+ case NW_MISSION_BOMBARD:
|
|
|
+ i = skill_get_splash(skill_id,skill_lv);
|
|
|
+ map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,BL_CHAR|BL_SKILL,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|SKILL_ALTDMG_FLAG|1,skill_castend_damage_id);
|
|
|
+ skill_unitsetting(src, skill_id, skill_lv, x, y, flag);
|
|
|
+
|
|
|
+ for (i = 1; i <= (skill_get_time(skill_id, skill_lv) / skill_get_unit_interval(skill_id)); i++) {
|
|
|
+ skill_addtimerskill(src, tick + (t_tick)i*skill_get_unit_interval(skill_id), 0, x, y, skill_id, skill_lv, 0, flag);
|
|
|
+ }
|
|
|
+ break;
|
|
|
+
|
|
|
default:
|
|
|
ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skill_id);
|
|
|
return 1;
|
|
@@ -14563,7 +14706,8 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
|
|
|
}
|
|
|
skill_onskillusage(sd, NULL, skill_id, tick);
|
|
|
// perform skill requirement consumption
|
|
|
- skill_consume_requirement(sd,skill_id,skill_lv,2);
|
|
|
+ if (!(flag&SKILL_NOCONSUME_REQ))
|
|
|
+ skill_consume_requirement(sd,skill_id,skill_lv,2);
|
|
|
}
|
|
|
|
|
|
return 0;
|
|
@@ -15211,6 +15355,10 @@ std::shared_ptr<s_skill_unit_group> skill_unitsetting(struct block_list *src, ui
|
|
|
case WH_FLAMETRAP:
|
|
|
limit += 3000 * (sd ? pc_checkskill(sd, WH_ADVANCED_TRAP) : 5);
|
|
|
break;
|
|
|
+
|
|
|
+ case NW_GRENADES_DROPPING:
|
|
|
+ limit = skill_get_time2(skill_id,skill_lv);
|
|
|
+ break;
|
|
|
}
|
|
|
|
|
|
// Init skill unit group
|
|
@@ -18711,6 +18859,8 @@ struct s_skill_condition skill_get_requirement(map_session_data* sd, uint16 skil
|
|
|
req.mhp = skill->require.mhp[skill_lv-1];
|
|
|
req.weapon = skill->require.weapon;
|
|
|
req.ammo_qty = skill->require.ammo_qty[skill_lv-1];
|
|
|
+ if (skill_id == NW_MAGAZINE_FOR_ONE && sd->weapontype1 == W_GATLING)
|
|
|
+ req.ammo_qty += 4;
|
|
|
if (req.ammo_qty)
|
|
|
req.ammo = skill->require.ammo;
|
|
|
|