Initial implementation of Night Watch (#8150)
Taken from #7024 Co-authored-by: munkrej <schmunk@posteo.de> Co-authored-by: Atemo <Atemo@users.noreply.github.com>
This commit is contained in:
parent
37d9196a4e
commit
4124cdaa4a
@ -41379,6 +41379,473 @@ Body:
|
||||
SplashArea: 6
|
||||
Requires:
|
||||
SpCost: 1
|
||||
- Id: 5401
|
||||
Name: NW_P_F_I
|
||||
Description: P.F.I
|
||||
MaxLevel: 10
|
||||
- Id: 5402
|
||||
Name: NW_GRENADE_MASTERY
|
||||
Description: Grenade Mastery
|
||||
MaxLevel: 10
|
||||
- Id: 5403
|
||||
Name: NW_INTENSIVE_AIM
|
||||
Description: Intensive Aim
|
||||
MaxLevel: 1
|
||||
Type: Weapon
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
NoDamage: true
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Duration1: -1
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 10
|
||||
Status: Intensive_Aim
|
||||
- Id: 5404
|
||||
Name: NW_GRENADE_FRAGMENT
|
||||
Description: Grenade Fragment
|
||||
MaxLevel: 7
|
||||
Type: Weapon
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
NoDamage: true
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Duration1: 300000
|
||||
Cooldown: 2000
|
||||
Requires:
|
||||
SpCost: 50
|
||||
- Id: 5405
|
||||
Name: NW_THE_VIGILANTE_AT_NIGHT
|
||||
Description: The Vigilante at Night
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
Hit: Multi_Hit
|
||||
HitCount: 4
|
||||
Element: Weapon
|
||||
SplashArea:
|
||||
- Level: 1
|
||||
Area: 2
|
||||
- Level: 2
|
||||
Area: 2
|
||||
- Level: 3
|
||||
Area: 2
|
||||
- Level: 4
|
||||
Area: 3
|
||||
- Level: 5
|
||||
Area: 3
|
||||
GiveAp: 1
|
||||
AfterCastActDelay: 1000
|
||||
Cooldown: 500
|
||||
CastCancel: true
|
||||
FixedCastTime: 1500
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 49
|
||||
- Level: 2
|
||||
Amount: 53
|
||||
- Level: 3
|
||||
Amount: 57
|
||||
- Level: 4
|
||||
Amount: 61
|
||||
- Level: 5
|
||||
Amount: 65
|
||||
Weapon:
|
||||
Gatling: true
|
||||
Shotgun: true
|
||||
Ammo:
|
||||
Bullet: true
|
||||
AmmoAmount: 10
|
||||
- Id: 5406
|
||||
Name: NW_ONLY_ONE_BULLET
|
||||
Description: Only One Bullet
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
Critical: true
|
||||
Range: -9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Weapon
|
||||
GiveAp: 1
|
||||
AfterCastActDelay: 500
|
||||
Cooldown: 300
|
||||
CastCancel: true
|
||||
FixedCastTime: 1000
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 39
|
||||
- Level: 2
|
||||
Amount: 43
|
||||
- Level: 3
|
||||
Amount: 47
|
||||
- Level: 4
|
||||
Amount: 51
|
||||
- Level: 5
|
||||
Amount: 55
|
||||
Weapon:
|
||||
Revolver: true
|
||||
Rifle: true
|
||||
Ammo:
|
||||
Bullet: true
|
||||
AmmoAmount: 1
|
||||
- Id: 5407
|
||||
Name: NW_SPIRAL_SHOOTING
|
||||
Description: Spiral Shooting
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
Critical: true
|
||||
Splash: true
|
||||
Range: -9
|
||||
Hit: Multi_Hit
|
||||
HitCount: 1
|
||||
Element: Weapon
|
||||
SplashArea:
|
||||
- Level: 1
|
||||
Area: 2
|
||||
- Level: 2
|
||||
Area: 2
|
||||
- Level: 3
|
||||
Area: 2
|
||||
- Level: 4
|
||||
Area: 3
|
||||
- Level: 5
|
||||
Area: 3
|
||||
GiveAp: 1
|
||||
AfterCastActDelay: 1000
|
||||
Cooldown: 500
|
||||
CastCancel: true
|
||||
FixedCastTime: 1000
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 48
|
||||
- Level: 2
|
||||
Amount: 53
|
||||
- Level: 3
|
||||
Amount: 58
|
||||
- Level: 4
|
||||
Amount: 63
|
||||
- Level: 5
|
||||
Amount: 68
|
||||
Weapon:
|
||||
Grenade: true
|
||||
Rifle: true
|
||||
Ammo:
|
||||
Bullet: true
|
||||
AmmoAmount: 6
|
||||
- Id: 5408
|
||||
Name: NW_MAGAZINE_FOR_ONE
|
||||
Description: Magazine for One
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
Critical: true
|
||||
Range: -9
|
||||
Hit: Multi_Hit
|
||||
HitCount: 6
|
||||
Element: Weapon
|
||||
GiveAp: 1
|
||||
AfterCastActDelay: 1000
|
||||
Cooldown: 500
|
||||
CastCancel: true
|
||||
FixedCastTime: 1000
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 42
|
||||
- Level: 2
|
||||
Amount: 46
|
||||
- Level: 3
|
||||
Amount: 50
|
||||
- Level: 4
|
||||
Amount: 54
|
||||
- Level: 5
|
||||
Amount: 58
|
||||
Weapon:
|
||||
Revolver: true
|
||||
Gatling: true
|
||||
Ammo:
|
||||
Bullet: true
|
||||
AmmoAmount: 6
|
||||
- Id: 5409
|
||||
Name: NW_WILD_FIRE
|
||||
Description: Wild Fire
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Ground
|
||||
Range: -9
|
||||
Hit: Single
|
||||
HitCount: -3
|
||||
Element: Weapon
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
SplashArea:
|
||||
- Level: 1
|
||||
Area: 2
|
||||
- Level: 2
|
||||
Area: 2
|
||||
- Level: 3
|
||||
Area: 2
|
||||
- Level: 4
|
||||
Area: 3
|
||||
- Level: 5
|
||||
Area: 3
|
||||
GiveAp: 1
|
||||
AfterCastActDelay: 1000
|
||||
Cooldown: 500
|
||||
CastCancel: true
|
||||
FixedCastTime: 1000
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 51
|
||||
- Level: 2
|
||||
Amount: 55
|
||||
- Level: 3
|
||||
Amount: 59
|
||||
- Level: 4
|
||||
Amount: 63
|
||||
- Level: 5
|
||||
Amount: 67
|
||||
Weapon:
|
||||
Shotgun: true
|
||||
Grenade: true
|
||||
Ammo:
|
||||
Bullet: true
|
||||
AmmoAmount: 5
|
||||
- Id: 5410
|
||||
Name: NW_BASIC_GRENADE
|
||||
Description: Basic Grenade
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Ground
|
||||
Range: -9
|
||||
Hit: Single
|
||||
HitCount: -2
|
||||
Element: Weapon
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
SplashArea:
|
||||
- Level: 1
|
||||
Area: 1
|
||||
- Level: 2
|
||||
Area: 1
|
||||
- Level: 3
|
||||
Area: 1
|
||||
- Level: 4
|
||||
Area: 2
|
||||
- Level: 5
|
||||
Area: 2
|
||||
GiveAp: 2
|
||||
Cooldown: 300
|
||||
CastCancel: true
|
||||
FixedCastTime: 1000
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 36
|
||||
- Level: 2
|
||||
Amount: 42
|
||||
- Level: 3
|
||||
Amount: 48
|
||||
- Level: 4
|
||||
Amount: 54
|
||||
- Level: 5
|
||||
Amount: 60
|
||||
ItemCost:
|
||||
- Item: Nw_Grenade
|
||||
Amount: 1
|
||||
- Id: 5411
|
||||
Name: NW_HASTY_FIRE_IN_THE_HOLE
|
||||
Description: Hasty Fire in the Hole
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Ground
|
||||
Range: -9
|
||||
Hit: Multi_Hit
|
||||
HitCount: -2
|
||||
Element: Weapon
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
SplashArea: 2
|
||||
GiveAp: 3
|
||||
Cooldown: 1000
|
||||
CastCancel: true
|
||||
FixedCastTime: 1000
|
||||
AfterCastActDelay: 1500
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 50
|
||||
- Level: 2
|
||||
Amount: 53
|
||||
- Level: 3
|
||||
Amount: 56
|
||||
- Level: 4
|
||||
Amount: 59
|
||||
- Level: 5
|
||||
Amount: 62
|
||||
ItemCost:
|
||||
- Item: Nw_Grenade
|
||||
Amount: 3
|
||||
- Id: 5412
|
||||
Name: NW_GRENADES_DROPPING
|
||||
Description: Grenades Dropping
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Ground
|
||||
Range: -9
|
||||
Hit: Multi_Hit
|
||||
HitCount: 3
|
||||
Element: Weapon
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
SplashArea:
|
||||
- Level: 1
|
||||
Area: 5
|
||||
- Level: 2
|
||||
Area: 5
|
||||
- Level: 3
|
||||
Area: 5
|
||||
- Level: 4
|
||||
Area: 4
|
||||
- Level: 5
|
||||
Area: 4
|
||||
GiveAp: 5
|
||||
Cooldown: 4500
|
||||
CastCancel: true
|
||||
FixedCastTime: 1000
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 60
|
||||
- Level: 2
|
||||
Amount: 66
|
||||
- Level: 3
|
||||
Amount: 72
|
||||
- Level: 4
|
||||
Amount: 78
|
||||
- Level: 5
|
||||
Amount: 84
|
||||
ItemCost:
|
||||
- Item: Nw_Grenade
|
||||
Amount: 15
|
||||
Duration1: 4000
|
||||
Duration2: 100
|
||||
Unit:
|
||||
Id: Grenades_Dropping
|
||||
Layout: 0
|
||||
Range:
|
||||
- Level: 1
|
||||
Size: 1
|
||||
- Level: 2
|
||||
Size: 1
|
||||
- Level: 3
|
||||
Size: 1
|
||||
- Level: 4
|
||||
Size: 2
|
||||
- Level: 5
|
||||
Size: 2
|
||||
Interval: 250
|
||||
Target: Enemy
|
||||
Flag:
|
||||
NoOverlap: true
|
||||
PathCheck: true
|
||||
- Id: 5413
|
||||
Name: NW_AUTO_FIRING_LAUNCHER
|
||||
Description: Auto Firing Launcher
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
NoDamage: true
|
||||
Duration1:
|
||||
- Level: 1
|
||||
Time: 120000
|
||||
- Level: 2
|
||||
Time: 150000
|
||||
- Level: 3
|
||||
Time: 180000
|
||||
- Level: 4
|
||||
Time: 210000
|
||||
- Level: 5
|
||||
Time: 240000
|
||||
Cooldown: 30000
|
||||
CastCancel: true
|
||||
FixedCastTime: 3000
|
||||
Requires:
|
||||
SpCost:
|
||||
- Level: 1
|
||||
Amount: 90
|
||||
- Level: 2
|
||||
Amount: 100
|
||||
- Level: 3
|
||||
Amount: 110
|
||||
- Level: 4
|
||||
Amount: 120
|
||||
- Level: 5
|
||||
Amount: 130
|
||||
Status: Auto_Firing_Launcher
|
||||
- Id: 5414
|
||||
Name: NW_HIDDEN_CARD
|
||||
Description: Hidden Card
|
||||
MaxLevel: 10
|
||||
Type: Weapon
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
NoDamage: true
|
||||
Duration1: 300000
|
||||
Cooldown: 60000
|
||||
CastCancel: true
|
||||
FixedCastTime: 2000
|
||||
Requires:
|
||||
SpCost: 150
|
||||
ApCost: 150
|
||||
Status: Hidden_Card
|
||||
- Id: 5415
|
||||
Name: NW_MISSION_BOMBARD
|
||||
Description: Mission Bombard
|
||||
MaxLevel: 10
|
||||
Type: Weapon
|
||||
TargetType: Ground
|
||||
Range: -9
|
||||
Hit: Multi_Hit
|
||||
HitCount: -3
|
||||
Element: Weapon
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
SplashArea: 4
|
||||
Cooldown: 10000
|
||||
CastCancel: true
|
||||
FixedCastTime: 1000
|
||||
Requires:
|
||||
SpCost: 100
|
||||
ApCost: 35
|
||||
ItemCost:
|
||||
- Item: Nw_Grenade
|
||||
Amount: 15
|
||||
Duration1: 10000
|
||||
Unit:
|
||||
Id: Mission_Bombard
|
||||
Layout: 0
|
||||
Range: 2
|
||||
Interval: 250
|
||||
Target: Enemy
|
||||
Flag:
|
||||
NoOverlap: true
|
||||
PathCheck: true
|
||||
- Id: 5449
|
||||
Name: HN_SELFSTUDY_TATICS
|
||||
Description: Self Study Tactics
|
||||
@ -42159,6 +42626,16 @@ Body:
|
||||
SpCost: 150
|
||||
ApCost: 150
|
||||
Status: Rulebreak
|
||||
- Id: 5496
|
||||
Name: NW_THE_VIGILANTE_AT_NIGHT_GUN_GATLING
|
||||
Description: The Vigilante At Night Gun Gatling
|
||||
MaxLevel: 5
|
||||
CastCancel: true
|
||||
- Id: 5497
|
||||
Name: NW_THE_VIGILANTE_AT_NIGHT_GUN_SHOTGUN
|
||||
Description: The Vigilante At Night Gun Shotgun
|
||||
MaxLevel: 5
|
||||
CastCancel: true
|
||||
- Id: 6001
|
||||
Name: DK_DRAGONIC_BREATH
|
||||
Description: Dragonic Breath
|
||||
|
@ -7864,6 +7864,95 @@ Body:
|
||||
Royal_Guard: true
|
||||
Royal_Guard_T: true
|
||||
Imperial_Guard: true
|
||||
- Job: Night_Watch
|
||||
Inherit:
|
||||
Novice: true
|
||||
Gunslinger: true
|
||||
Rebellion: true
|
||||
Tree:
|
||||
- Name: NW_P_F_I
|
||||
MaxLevel: 10
|
||||
- Name: NW_GRENADE_MASTERY
|
||||
MaxLevel: 10
|
||||
- Name: NW_INTENSIVE_AIM
|
||||
MaxLevel: 1
|
||||
Requires:
|
||||
- Name: NW_P_F_I
|
||||
Level: 1
|
||||
- Name: NW_HIDDEN_CARD
|
||||
MaxLevel: 10
|
||||
Requires:
|
||||
- Name: NW_P_F_I
|
||||
Level: 5
|
||||
- Name: NW_INTENSIVE_AIM
|
||||
Level: 1
|
||||
- Name: NW_BASIC_GRENADE
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_GRENADE_MASTERY
|
||||
Level: 3
|
||||
- Name: NW_GRENADE_FRAGMENT
|
||||
MaxLevel: 7
|
||||
Requires:
|
||||
- Name: NW_GRENADE_MASTERY
|
||||
Level: 1
|
||||
- Name: NW_THE_VIGILANTE_AT_NIGHT
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_P_F_I
|
||||
Level: 3
|
||||
- Name: NW_INTENSIVE_AIM
|
||||
Level: 1
|
||||
- Name: NW_ONLY_ONE_BULLET
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_P_F_I
|
||||
Level: 3
|
||||
- Name: NW_INTENSIVE_AIM
|
||||
Level: 1
|
||||
- Name: NW_SPIRAL_SHOOTING
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_P_F_I
|
||||
Level: 3
|
||||
- Name: NW_INTENSIVE_AIM
|
||||
Level: 1
|
||||
- Name: NW_MAGAZINE_FOR_ONE
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_P_F_I
|
||||
Level: 3
|
||||
- Name: NW_INTENSIVE_AIM
|
||||
Level: 1
|
||||
- Name: NW_WILD_FIRE
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_P_F_I
|
||||
Level: 3
|
||||
- Name: NW_INTENSIVE_AIM
|
||||
Level: 1
|
||||
- Name: NW_HASTY_FIRE_IN_THE_HOLE
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_BASIC_GRENADE
|
||||
Level: 3
|
||||
- Name: NW_GRENADES_DROPPING
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_HASTY_FIRE_IN_THE_HOLE
|
||||
Level: 3
|
||||
- Name: NW_AUTO_FIRING_LAUNCHER
|
||||
MaxLevel: 5
|
||||
Requires:
|
||||
- Name: NW_GRENADES_DROPPING
|
||||
Level: 3
|
||||
- Name: NW_MISSION_BOMBARD
|
||||
MaxLevel: 10
|
||||
Requires:
|
||||
- Name: NW_GRENADE_MASTERY
|
||||
Level: 5
|
||||
- Name: NW_GRENADES_DROPPING
|
||||
Level: 3
|
||||
- Job: Hyper_Novice
|
||||
Inherit:
|
||||
Novice: true
|
||||
|
@ -8787,3 +8787,92 @@ Body:
|
||||
- Status: Rulebreak
|
||||
Icon: EFST_RULEBREAK
|
||||
DurationLookup: HN_RULEBREAK
|
||||
- Status: Intensive_Aim
|
||||
Icon: EFST_INTENSIVE_AIM
|
||||
States:
|
||||
NoMove: true
|
||||
CalcFlags:
|
||||
Batk: true
|
||||
Hit: true
|
||||
Cri: true
|
||||
Flags:
|
||||
BlEffect: true
|
||||
DisplayPc: true
|
||||
SendVal1: true
|
||||
NoSave: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
- Status: Intensive_Aim_Count
|
||||
Icon: EFST_INTENSIVE_AIM_COUNT
|
||||
Flags:
|
||||
DisplayPc: true
|
||||
SendVal1: true
|
||||
NoSave: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
- Status: Grenade_Fragment_1
|
||||
Icon: EFST_GRENADE_FRAGMENT_1
|
||||
DurationLookup: NW_GRENADE_FRAGMENT
|
||||
EndOnStart:
|
||||
Grenade_Fragment_2: true
|
||||
Grenade_Fragment_3: true
|
||||
Grenade_Fragment_4: true
|
||||
Grenade_Fragment_5: true
|
||||
Grenade_Fragment_6: true
|
||||
- Status: Grenade_Fragment_2
|
||||
Icon: EFST_GRENADE_FRAGMENT_2
|
||||
DurationLookup: NW_GRENADE_FRAGMENT
|
||||
EndOnStart:
|
||||
Grenade_Fragment_1: true
|
||||
Grenade_Fragment_3: true
|
||||
Grenade_Fragment_4: true
|
||||
Grenade_Fragment_5: true
|
||||
Grenade_Fragment_6: true
|
||||
- Status: Grenade_Fragment_3
|
||||
Icon: EFST_GRENADE_FRAGMENT_3
|
||||
DurationLookup: NW_GRENADE_FRAGMENT
|
||||
EndOnStart:
|
||||
Grenade_Fragment_1: true
|
||||
Grenade_Fragment_2: true
|
||||
Grenade_Fragment_4: true
|
||||
Grenade_Fragment_5: true
|
||||
Grenade_Fragment_6: true
|
||||
- Status: Grenade_Fragment_4
|
||||
Icon: EFST_GRENADE_FRAGMENT_4
|
||||
DurationLookup: NW_GRENADE_FRAGMENT
|
||||
EndOnStart:
|
||||
Grenade_Fragment_1: true
|
||||
Grenade_Fragment_2: true
|
||||
Grenade_Fragment_3: true
|
||||
Grenade_Fragment_5: true
|
||||
Grenade_Fragment_6: true
|
||||
- Status: Grenade_Fragment_5
|
||||
Icon: EFST_GRENADE_FRAGMENT_5
|
||||
DurationLookup: NW_GRENADE_FRAGMENT
|
||||
EndOnStart:
|
||||
Grenade_Fragment_1: true
|
||||
Grenade_Fragment_2: true
|
||||
Grenade_Fragment_3: true
|
||||
Grenade_Fragment_4: true
|
||||
Grenade_Fragment_6: true
|
||||
- Status: Grenade_Fragment_6
|
||||
Icon: EFST_GRENADE_FRAGMENT_6
|
||||
DurationLookup: NW_GRENADE_FRAGMENT
|
||||
EndOnStart:
|
||||
Grenade_Fragment_1: true
|
||||
Grenade_Fragment_2: true
|
||||
Grenade_Fragment_3: true
|
||||
Grenade_Fragment_4: true
|
||||
Grenade_Fragment_5: true
|
||||
- Status: Auto_Firing_Launcher
|
||||
Icon: EFST_AUTO_FIRING_LAUNCHEREFST
|
||||
DurationLookup: NW_AUTO_FIRING_LAUNCHER
|
||||
Flags:
|
||||
SendVal1: true
|
||||
- Status: Hidden_Card
|
||||
Icon: EFST_HIDDEN_CARD
|
||||
DurationLookup: NW_HIDDEN_CARD
|
||||
CalcFlags:
|
||||
All: true
|
||||
|
@ -2585,12 +2585,20 @@ void battle_consume_ammo(map_session_data*sd, int skill, int lv)
|
||||
{
|
||||
int qty = 1;
|
||||
|
||||
if( sd == nullptr ){
|
||||
return;
|
||||
}
|
||||
|
||||
if (!battle_config.arrow_decrement)
|
||||
return;
|
||||
|
||||
if (skill) {
|
||||
qty = skill_get_ammo_qty(skill, lv);
|
||||
if (!qty) qty = 1;
|
||||
|
||||
if( skill == NW_MAGAZINE_FOR_ONE && sd->weapontype1 == W_GATLING ){
|
||||
qty += 4;
|
||||
}
|
||||
}
|
||||
|
||||
if (sd->equip_index[EQI_AMMO] >= 0) //Qty check should have been done in skill_check_condition
|
||||
@ -2621,6 +2629,7 @@ static int battle_range_type(struct block_list *src, struct block_list *target,
|
||||
case BO_ACIDIFIED_ZONE_FIRE_ATK:
|
||||
case BO_ACIDIFIED_ZONE_GROUND_ATK:
|
||||
case BO_ACIDIFIED_ZONE_WIND_ATK:
|
||||
case NW_THE_VIGILANTE_AT_NIGHT:
|
||||
return BF_LONG;
|
||||
case NJ_KIRIKAGE: // Cast range mimics NJ_SHADOWJUMP but damage is considered melee
|
||||
case GC_CROSSIMPACT: // Cast range is 7 cells and player jumps to target but skill is considered melee
|
||||
@ -2997,6 +3006,18 @@ static bool is_attack_critical(struct Damage* wd, struct block_list *src, struct
|
||||
case WH_GALESTORM:
|
||||
if (sc && !sc->getSCE(SC_CALAMITYGALE))
|
||||
return false;
|
||||
break;
|
||||
case NW_ONLY_ONE_BULLET:
|
||||
case NW_SPIRAL_SHOOTING:
|
||||
if( sd == nullptr || sd->weapontype1 != W_RIFLE ){
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
case NW_MAGAZINE_FOR_ONE:
|
||||
if( sd == nullptr || sd->weapontype1 != W_REVOLVER ){
|
||||
return false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if(tsd && tsd->bonus.critical_def)
|
||||
cri = cri * ( 100 - tsd->bonus.critical_def ) / 100;
|
||||
@ -3282,8 +3303,25 @@ static bool attack_ignores_def(struct Damage* wd, struct block_list *src, struct
|
||||
if (sc && sc->getSCE(SC_FUSION))
|
||||
return true;
|
||||
|
||||
if (skill_id == RK_WINDCUTTER && sd && sd->status.weapon == W_2HSWORD)
|
||||
return true;
|
||||
if( sd != nullptr ){
|
||||
switch( skill_id ){
|
||||
case RK_WINDCUTTER:
|
||||
if( sd->status.weapon == W_2HSWORD ){
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case NW_THE_VIGILANTE_AT_NIGHT:
|
||||
if( sd->status.weapon == W_GATLING ){
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
case NW_ONLY_ONE_BULLET:
|
||||
if( sd->status.weapon == W_REVOLVER ){
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (skill_id != CR_GRANDCROSS && skill_id != NPC_GRANDDARKNESS)
|
||||
{ //Ignore Defense?
|
||||
@ -3427,6 +3465,27 @@ int battle_get_weapon_element(struct Damage* wd, struct block_list *src, struct
|
||||
if (sd && sd->flicker) //Force RL_H_MINE deals fire damage if activated by RL_FLICKER
|
||||
element = ELE_FIRE;
|
||||
break;
|
||||
case NW_BASIC_GRENADE:
|
||||
case NW_HASTY_FIRE_IN_THE_HOLE:
|
||||
case NW_GRENADES_DROPPING:
|
||||
case NW_MISSION_BOMBARD:
|
||||
// Night Watch Grenade Fragment elementals affecting those skills.
|
||||
if( sc != nullptr ){
|
||||
if( sc->getSCE( SC_GRENADE_FRAGMENT_1 ) != nullptr ){
|
||||
element = ELE_WATER;
|
||||
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_2 ) != nullptr ){
|
||||
element = ELE_WIND;
|
||||
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_3 ) != nullptr ){
|
||||
element = ELE_EARTH;
|
||||
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_4 ) != nullptr ){
|
||||
element = ELE_FIRE;
|
||||
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_5 ) != nullptr ){
|
||||
element = ELE_DARK;
|
||||
}else if( sc->getSCE( SC_GRENADE_FRAGMENT_6 ) != nullptr ){
|
||||
element = ELE_HOLY;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (sc && sc->getSCE(SC_GOLDENE_FERSE) && ((!skill_id && (rnd() % 100 < sc->getSCE(SC_GOLDENE_FERSE)->val4)) || skill_id == MH_STAHL_HORN))
|
||||
@ -4186,6 +4245,18 @@ static void battle_calc_multi_attack(struct Damage* wd, struct block_list *src,s
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
case NW_SPIRAL_SHOOTING:
|
||||
if (sd && sd->weapontype1 == W_GRENADE)
|
||||
wd->div_ += 1;
|
||||
break;
|
||||
case NW_MAGAZINE_FOR_ONE:
|
||||
if (sd && sd->weapontype1 == W_GATLING)
|
||||
wd->div_ += 4;
|
||||
break;
|
||||
case NW_THE_VIGILANTE_AT_NIGHT:
|
||||
if (sd && sd->weapontype1 == W_GATLING)
|
||||
wd->div_ += 3;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -5864,6 +5935,85 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
|
||||
skillratio += 5 * sstatus->pow;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_HASTY_FIRE_IN_THE_HOLE:
|
||||
skillratio += -100 + 1500 + 1050 * skill_lv;
|
||||
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 20;
|
||||
skillratio += 5 * sstatus->con;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_BASIC_GRENADE:
|
||||
skillratio += -100 + 1000 + 950 * skill_lv;
|
||||
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 50;
|
||||
skillratio += 5 * sstatus->con;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_GRENADES_DROPPING:
|
||||
skillratio += -100 + 550 + 850 * skill_lv;
|
||||
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 30;
|
||||
skillratio += 5 * sstatus->con;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_WILD_FIRE:
|
||||
skillratio += -100 + 1000 + 2300 * skill_lv;
|
||||
skillratio += 5 * sstatus->con;
|
||||
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
||||
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 500 * skill_lv;
|
||||
if (sd && sd->weapontype1 == W_SHOTGUN)
|
||||
skillratio += 150 * skill_lv;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_MAGAZINE_FOR_ONE:
|
||||
skillratio += -100 + 100 + 450 * ( skill_lv - 1 );
|
||||
skillratio += 5 * sstatus->con;
|
||||
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
||||
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 100 * skill_lv;
|
||||
if (sd && sd->weapontype1 == W_REVOLVER)
|
||||
skillratio += 50 + 100 * (skill_lv-1);
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_SPIRAL_SHOOTING:
|
||||
skillratio += -100 + 1000 + 1500 * skill_lv;
|
||||
skillratio += 5 * sstatus->con;
|
||||
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
||||
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 150 * skill_lv;
|
||||
if (sd && sd->weapontype1 == W_RIFLE)
|
||||
skillratio += 200 + 200 * skill_lv;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_ONLY_ONE_BULLET:
|
||||
skillratio += -100 + 800 + 1350 * skill_lv;
|
||||
skillratio += 5 * sstatus->con;
|
||||
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
||||
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 350 * skill_lv;
|
||||
if (sd && sd->weapontype1 == W_REVOLVER) {
|
||||
skillratio += 150 * skill_lv;
|
||||
}
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_THE_VIGILANTE_AT_NIGHT:
|
||||
if (sd && sd->weapontype1 == W_GATLING) {
|
||||
skillratio += -100 + 300 * skill_lv;
|
||||
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
||||
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 100 * skill_lv;
|
||||
} else {
|
||||
skillratio += -100 + 800 + 700 * skill_lv;
|
||||
if (sc && sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
||||
skillratio += sc->getSCE(SC_INTENSIVE_AIM_COUNT)->val1 * 200 * skill_lv;
|
||||
}
|
||||
skillratio += 5 * sstatus->con;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
case NW_MISSION_BOMBARD:
|
||||
if( wd->miscflag&SKILL_ALTDMG_FLAG ){
|
||||
skillratio += -100 + 5000 + 1800 * skill_lv;
|
||||
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 100;
|
||||
}else{
|
||||
skillratio += -100 + 800 + 200 * skill_lv;
|
||||
skillratio += pc_checkskill( sd, NW_GRENADE_MASTERY ) * 30;
|
||||
}
|
||||
skillratio += 5 * sstatus->con;
|
||||
RE_LVL_DMOD(100);
|
||||
break;
|
||||
}
|
||||
return skillratio;
|
||||
}
|
||||
@ -6089,6 +6239,8 @@ static void battle_attack_sc_bonus(struct Damage* wd, struct block_list *src, st
|
||||
|
||||
if (sc->getSCE(SC_MIRACLE))
|
||||
anger_id = 2; // Always treat all monsters as star flagged monster when in miracle state
|
||||
if (sc->getSCE(SC_HIDDEN_CARD) && (wd->flag&BF_LONG) == BF_LONG)
|
||||
RE_ALLATK_ADDRATE(wd, sc->getSCE(SC_HIDDEN_CARD)->val3);
|
||||
}
|
||||
|
||||
if ((wd->flag&(BF_LONG|BF_MAGIC)) == BF_LONG) {
|
||||
@ -9773,6 +9925,113 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
|
||||
if( sc->getSCE( SC_AUTO_FIRING_LAUNCHER ) ){
|
||||
uint16 skill_id;
|
||||
uint16 skill_lv;
|
||||
|
||||
switch( sc->getSCE( SC_AUTO_FIRING_LAUNCHER )->val1 ){
|
||||
case 1:
|
||||
skill_id = NW_BASIC_GRENADE;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 6, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 2:
|
||||
skill_id = NW_BASIC_GRENADE;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 7, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
skill_id = NW_HASTY_FIRE_IN_THE_HOLE;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 3, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
|
||||
skill_id = NW_BASIC_GRENADE;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 8, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
skill_id = NW_HASTY_FIRE_IN_THE_HOLE;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 5, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
|
||||
skill_id = NW_BASIC_GRENADE;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 9, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
skill_id = NW_GRENADES_DROPPING;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 3, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
|
||||
skill_id = NW_HASTY_FIRE_IN_THE_HOLE;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 7, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
|
||||
skill_id = NW_BASIC_GRENADE;
|
||||
skill_lv = pc_checkskill( sd, skill_id );
|
||||
|
||||
if( skill_lv > 0 && rnd_chance( 10, 100 ) ){
|
||||
sd->state.autocast = 1;
|
||||
skill_castend_pos2( src, target->x, target->y, skill_id, skill_lv, tick, flag );
|
||||
battle_autocast_aftercast( src, skill_id, skill_lv, tick );
|
||||
sd->state.autocast = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Autocasted skills from super elemental supportive buffs.
|
||||
if (sc->getSCE(SC_FLAMETECHNIC_OPTION) && rnd() % 100 < 7)
|
||||
battle_autocast_elembuff_skill(sd, target, MG_FIREBOLT, tick, flag);
|
||||
|
@ -1900,6 +1900,16 @@
|
||||
export_constant(SC_GROUNDGRAVITY);
|
||||
export_constant(SC_BREAKINGLIMIT);
|
||||
export_constant(SC_RULEBREAK);
|
||||
export_constant(SC_INTENSIVE_AIM);
|
||||
export_constant(SC_INTENSIVE_AIM_COUNT);
|
||||
export_constant(SC_GRENADE_FRAGMENT_1);
|
||||
export_constant(SC_GRENADE_FRAGMENT_2);
|
||||
export_constant(SC_GRENADE_FRAGMENT_3);
|
||||
export_constant(SC_GRENADE_FRAGMENT_4);
|
||||
export_constant(SC_GRENADE_FRAGMENT_5);
|
||||
export_constant(SC_GRENADE_FRAGMENT_6);
|
||||
export_constant(SC_AUTO_FIRING_LAUNCHER);
|
||||
export_constant(SC_HIDDEN_CARD);
|
||||
|
||||
#ifdef RENEWAL
|
||||
export_constant(SC_EXTREMITYFIST2);
|
||||
|
@ -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;
|
||||
|
||||
|
@ -41,6 +41,8 @@ class status_change;
|
||||
|
||||
/// To control alternative skill scalings
|
||||
#define SKILL_ALTDMG_FLAG 0x10
|
||||
/// Make skill ignore requirement consumption [Muh]
|
||||
#define SKILL_NOCONSUME_REQ 0x20
|
||||
|
||||
/// Constants to identify a skill's nk value (damage properties)
|
||||
/// The NK value applies only to non INF_GROUND_SKILL skills
|
||||
|
@ -4169,6 +4169,10 @@ int status_calc_pc_sub(map_session_data* sd, uint8 opt)
|
||||
base_status->mdef++;
|
||||
}
|
||||
|
||||
// ----- CONCENTRATION CALCULATION -----
|
||||
if ((skill = pc_checkskill(sd, NW_GRENADE_MASTERY)) > 0)
|
||||
base_status->con += skill;
|
||||
|
||||
// ------ ATTACK CALCULATION ------
|
||||
|
||||
// Base batk value is set in status_calc_misc
|
||||
@ -4383,6 +4387,8 @@ int status_calc_pc_sub(map_session_data* sd, uint8 opt)
|
||||
base_status->patk += skill;
|
||||
if ((skill = pc_checkskill(sd, HN_SELFSTUDY_SOCERY)) > 0)
|
||||
base_status->smatk += skill;
|
||||
if ((skill = pc_checkskill(sd, NW_P_F_I)) > 0 && (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
|
||||
base_status->patk += skill + 2;
|
||||
|
||||
// 2-Handed Staff Mastery
|
||||
if( sd->status.weapon == W_2HSTAFF && ( skill = pc_checkskill( sd, AG_TWOHANDSTAFF ) ) > 0 ){
|
||||
@ -4759,6 +4765,8 @@ int status_calc_pc_sub(map_session_data* sd, uint8 opt)
|
||||
sd->bonus.short_attack_atk_rate += 5 * sc->getSCE( SC_RUSH_QUAKE2 )->val1;
|
||||
sd->bonus.long_attack_atk_rate += 5 * sc->getSCE( SC_RUSH_QUAKE2 )->val1;
|
||||
}
|
||||
if (sc->getSCE(SC_HIDDEN_CARD))
|
||||
sd->bonus.long_attack_atk_rate += sc->getSCE(SC_HIDDEN_CARD)->val3;
|
||||
if (sc->getSCE(SC_DEADLY_DEFEASANCE))
|
||||
sd->special_state.no_magic_damage = 0;
|
||||
if (sc->getSCE(SC_CLIMAX_DES_HU))
|
||||
@ -7070,6 +7078,8 @@ static unsigned short status_calc_batk(struct block_list *bl, status_change *sc,
|
||||
batk += 20;
|
||||
if(sc->getSCE(SC_SKF_ATK))
|
||||
batk += sc->getSCE(SC_SKF_ATK)->val1;
|
||||
if (sc->getSCE(SC_INTENSIVE_AIM))
|
||||
batk += 150;
|
||||
|
||||
return (unsigned short)cap_value(batk,0,USHRT_MAX);
|
||||
}
|
||||
@ -7386,6 +7396,8 @@ static signed short status_calc_critical(struct block_list *bl, status_change *s
|
||||
critical += sc->getSCE(SC_MTF_HITFLEE)->val1;
|
||||
if (sc->getSCE(SC_PACKING_ENVELOPE9))
|
||||
critical += sc->getSCE(SC_PACKING_ENVELOPE9)->val1 * 10;
|
||||
if (sc->getSCE(SC_INTENSIVE_AIM))
|
||||
critical += 300;
|
||||
|
||||
return (short)cap_value(critical,10,SHRT_MAX);
|
||||
}
|
||||
@ -7462,6 +7474,8 @@ static signed short status_calc_hit(struct block_list *bl, status_change *sc, in
|
||||
hit += sc->getSCE(SC_LIMIT_POWER_BOOSTER)->val1;
|
||||
if (sc->getSCE(SC_ACARAJE))
|
||||
hit += 5;
|
||||
if (sc->getSCE(SC_INTENSIVE_AIM))
|
||||
hit += 250;
|
||||
|
||||
return (short)cap_value(hit,1,SHRT_MAX);
|
||||
}
|
||||
@ -8518,6 +8532,8 @@ static signed short status_calc_patk(struct block_list *bl, status_change *sc, i
|
||||
if( sc->getSCE( SC_ATTACK_STANCE ) ){
|
||||
patk += sc->getSCE( SC_ATTACK_STANCE )->val3;
|
||||
}
|
||||
if (sc->getSCE(SC_HIDDEN_CARD))
|
||||
patk += sc->getSCE(SC_HIDDEN_CARD)->val2;
|
||||
|
||||
return (short)cap_value(patk, 0, SHRT_MAX);
|
||||
}
|
||||
@ -12741,6 +12757,13 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_WEAPONBREAKER:
|
||||
val2 = val1 * 2 * 100; // Chance to break weapon
|
||||
break;
|
||||
case SC_INTENSIVE_AIM:
|
||||
tick = 500;
|
||||
break;
|
||||
case SC_HIDDEN_CARD:
|
||||
val2 = 3 * val1;
|
||||
val3 = 10 * val1;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (calc_flag.none() && scdb->skill_id == 0 && scdb->icon == EFST_BLANK && scdb->opt1 == OPT1_NONE && scdb->opt2 == OPT2_NONE && scdb->state.none() && scdb->flag.none() && scdb->endonstart.empty() && scdb->endreturn.empty() && scdb->fail.empty() && scdb->endonend.empty()) {
|
||||
@ -14891,6 +14914,15 @@ TIMER_FUNC(status_change_timer){
|
||||
if (sce->val4 >= 0)
|
||||
skill_castend_damage_id( bl, bl, NPC_KILLING_AURA, sce->val1, tick, 0 );
|
||||
break;
|
||||
case SC_INTENSIVE_AIM:
|
||||
if (!sc || !sc->getSCE(SC_INTENSIVE_AIM_COUNT))
|
||||
sce->val4 = 0;
|
||||
if (sce->val4 < 10) {
|
||||
sce->val4++;
|
||||
sc_start(bl, bl, SC_INTENSIVE_AIM_COUNT, 100, sce->val4, INFINITE_TICK);
|
||||
}
|
||||
sc_timer_next(500 + tick);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// If status has an interval and there is at least 100ms remaining time, wait for next interval
|
||||
|
@ -1293,6 +1293,18 @@ enum sc_type : int16 {
|
||||
SC_BREAKINGLIMIT,
|
||||
SC_RULEBREAK,
|
||||
|
||||
// Night Watch
|
||||
SC_INTENSIVE_AIM,
|
||||
SC_INTENSIVE_AIM_COUNT,
|
||||
SC_GRENADE_FRAGMENT_1,
|
||||
SC_GRENADE_FRAGMENT_2,
|
||||
SC_GRENADE_FRAGMENT_3,
|
||||
SC_GRENADE_FRAGMENT_4,
|
||||
SC_GRENADE_FRAGMENT_5,
|
||||
SC_GRENADE_FRAGMENT_6,
|
||||
SC_AUTO_FIRING_LAUNCHER,
|
||||
SC_HIDDEN_CARD,
|
||||
|
||||
#ifdef RENEWAL
|
||||
SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user