Procházet zdrojové kódy

Initial implementation of Shinkiro/Shiranui (#8947)

Taken from #7024

Co-authored-by: munkrej <schmunk@posteo.de>
Co-authored-by: Atemo <Atemo@users.noreply.github.com>
Lemongrass3110 před 3 měsíci
rodič
revize
435b2b63b6

+ 842 - 0
db/re/skill_db.yml

@@ -43774,6 +43774,848 @@ Body:
       ApCost: 150
       SpCost: 100
     Status: Sky_Enchant
+  - Id: 5476
+    Name: SS_TOKEDASU
+    Description: Melt Away
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Ground
+    DamageFlags:
+      Splash: true
+    Range: 5
+    Hit: Multi_Hit
+    HitCount: -2
+    Element: Dark
+    SplashArea: 2
+    Duration2: 2000
+    Cooldown:
+      - Level: 1
+        Time: 6000
+      - Level: 2
+        Time: 5000
+      - Level: 3
+        Time: 4000
+      - Level: 4
+        Time: 3000
+      - Level: 5
+        Time: 2000
+    Requires:
+      SpCost: 35
+    Knockback: 3
+    Status: Shadow_Clock
+  - Id: 5477
+    Name: SS_SHIMIRU
+    Description: Infiltrate
+    MaxLevel: 5
+    Type: Weapon
+    TargetType: Attack
+    DamageFlags:
+      Splash: true
+    Range: 11
+    Hit: Multi_Hit
+    HitCount: -2
+    SplashArea: 15
+    Element: Weapon
+    Duration2: 2000
+    Cooldown:
+      - Level: 1
+        Time: 1500
+      - Level: 2
+        Time: 1250
+      - Level: 3
+        Time: 1000
+      - Level: 4
+        Time: 750
+      - Level: 5
+        Time: 500
+    Requires:
+      SpCost: 40
+    Status: Shadow_Clock
+  - Id: 5478
+    Name: SS_AKUMUKESU
+    Description: Nightmare Erasion
+    MaxLevel: 1
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+      Splash: true
+    SplashArea: 7
+    CastTime: 1000
+    AfterCastActDelay: 250
+    Cooldown: 15000
+    Requires:
+      SpCost: 10
+  - Id: 5479
+    Name: SS_SHINKIROU
+    Description: Mirage
+    MaxLevel: 1
+    Type: Magic
+    TargetType: Ground
+    Range: 5
+    DamageFlags:
+      NoDamage: true
+    CastTime: 2000
+    Duration1: 20000
+    Cooldown: 3000
+    FixedCastTime: 700
+    Requires:
+      SpCost: 25
+    ActiveInstance: 3
+    Unit:
+      Id: SHINKIROU
+      Interval: -1
+    Status: Shinkirou_Call
+  - Id: 5480
+    Name: SS_KAGEGARI
+    Description: Shadow Hunting
+    MaxLevel: 10
+    Type: Weapon
+    TargetType: Ground
+    Range: 2
+    Hit: Single
+    HitCount: 1
+    GiveAp: 2
+    Element: Weapon
+    DamageFlags:
+      Splash: true
+    SplashArea: 2
+    AfterCastActDelay: 150
+    Duration2: 5000
+    Cooldown: 300
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 33
+        - Level: 2
+          Amount: 36
+        - Level: 3
+          Amount: 39
+        - Level: 4
+          Amount: 42
+        - Level: 5
+          Amount: 45
+        - Level: 6
+          Amount: 48
+        - Level: 7
+          Amount: 51
+        - Level: 8
+          Amount: 54
+        - Level: 9
+          Amount: 57
+        - Level: 10
+          Amount: 60
+    Status: Nightmare
+  - Id: 5481
+    Name: SS_KAGENOMAI
+    Description: Shadow Dance
+    MaxLevel: 10
+    Type: Weapon
+    TargetType: Self
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -5
+    GiveAp: 2
+    Element: Weapon
+    DamageFlags:
+      Splash: true
+    SplashArea:
+      - Level: 1
+        Area: 2
+      - Level: 2
+        Area: 2
+      - Level: 3
+        Area: 2
+      - Level: 4
+        Area: 2
+      - Level: 5
+        Area: 3
+      - Level: 6
+        Area: 3
+      - Level: 7
+        Area: 3
+      - Level: 8
+        Area: 3
+      - Level: 9
+        Area: 4
+      - Level: 10
+        Area: 4
+    AfterCastActDelay: 250
+    Cooldown: 500
+    FixedCastTime:
+      - Level: 1
+        Time: 1000
+      - Level: 2
+        Time: 920
+      - Level: 3
+        Time: 845
+      - Level: 4
+        Time: 765
+      - Level: 5
+        Time: 690
+      - Level: 6
+        Time: 610
+      - Level: 7
+        Time: 530
+      - Level: 8
+        Time: 455
+      - Level: 9
+        Time: 375
+      - Level: 10
+        Time: 300
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 38
+        - Level: 2
+          Amount: 41
+        - Level: 3
+          Amount: 44
+        - Level: 4
+          Amount: 47
+        - Level: 5
+          Amount: 50
+        - Level: 6
+          Amount: 53
+        - Level: 7
+          Amount: 56
+        - Level: 8
+          Amount: 59
+        - Level: 9
+          Amount: 62
+        - Level: 10
+          Amount: 65
+  - Id: 5482
+    Name: SS_KAGEGISSEN
+    Description: Shadow Flash
+    MaxLevel: 10
+    Type: Weapon
+    TargetType: Attack
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -4
+    GiveAp: 1
+    Element: Weapon
+    SplashArea: 1
+    ActiveInstance: 10
+    AfterCastActDelay: 250
+    Cooldown: 500
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 36
+        - Level: 2
+          Amount: 39
+        - Level: 3
+          Amount: 42
+        - Level: 4
+          Amount: 45
+        - Level: 5
+          Amount: 48
+        - Level: 6
+          Amount: 51
+        - Level: 7
+          Amount: 54
+        - Level: 8
+          Amount: 57
+        - Level: 9
+          Amount: 60
+        - Level: 10
+          Amount: 63
+  - Id: 5483
+    Name: SS_FUUMASHOUAKU
+    Description: Huuma Shuriken - Grasp
+    MaxLevel: 10
+    Type: Weapon
+    TargetType: Ground
+    Range: 9
+    Hit: Multi_Hit
+    HitCount: 1
+    GiveAp: 3
+    Element: Weapon
+    ActiveInstance: 2
+    CastTime: 1200
+    Duration1: 5000
+    Duration2: 5000
+    Cooldown: 1000
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 48
+        - Level: 2
+          Amount: 52
+        - Level: 3
+          Amount: 56
+        - Level: 4
+          Amount: 60
+        - Level: 5
+          Amount: 64
+        - Level: 6
+          Amount: 68
+        - Level: 7
+          Amount: 72
+        - Level: 8
+          Amount: 76
+        - Level: 9
+          Amount: 80
+        - Level: 10
+          Amount: 84
+      Ammo:
+        Kunai: true
+    Unit:
+      Id: FUUMASHOUAKU
+      Range:
+        - Level: 1
+          Size: 2
+        - Level: 2
+          Size: 2
+        - Level: 3
+          Size: 2
+        - Level: 4
+          Size: 2
+        - Level: 5
+          Size: 3
+        - Level: 6
+          Size: 3
+        - Level: 7
+          Size: 3
+        - Level: 8
+          Size: 3
+        - Level: 9
+          Size: 4
+        - Level: 10
+          Size: 4
+      Interval: 250
+      Target: Enemy
+      Flag:
+        PathCheck: true
+    Status: Nightmare
+  - Id: 5484
+    Name: SS_FUUMAKOUCHIKU
+    Description: Huuma Shuriken - Construct
+    MaxLevel: 10
+    Type: Weapon
+    TargetType: Ground
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -3
+    Element: Weapon
+    SplashArea: 2
+    ActiveInstance: 13
+    CastTime: 1200
+    Cooldown: 1000
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 29
+        - Level: 2
+          Amount: 33
+        - Level: 3
+          Amount: 37
+        - Level: 4
+          Amount: 41
+        - Level: 5
+          Amount: 45
+        - Level: 6
+          Amount: 49
+        - Level: 7
+          Amount: 53
+        - Level: 8
+          Amount: 57
+        - Level: 9
+          Amount: 61
+        - Level: 10
+          Amount: 65
+      Ammo:
+        Kunai: true
+  - Id: 5485
+    Name: SS_KUNAIWAIKYOKU
+    Description: Kunai - Distortion
+    MaxLevel: 10
+    Type: Weapon
+    TargetType: Ground
+    Range: 9
+    Hit: Multi_Hit
+    HitCount: -2
+    GiveAp: 2
+    Element: Weapon
+    DamageFlags:
+      Splash: true
+      IgnoreFlee: true
+    SplashArea: 2
+    AfterCastActDelay: 500
+    Duration1: 5000
+    Duration2: 5000
+    Cooldown: 300
+    CastTime: 200
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 36
+        - Level: 2
+          Amount: 38
+        - Level: 3
+          Amount: 40
+        - Level: 4
+          Amount: 42
+        - Level: 5
+          Amount: 44
+        - Level: 6
+          Amount: 46
+        - Level: 7
+          Amount: 48
+        - Level: 8
+          Amount: 50
+        - Level: 9
+          Amount: 52
+        - Level: 10
+          Amount: 54
+      Ammo:
+        Kunai: true
+      AmmoAmount: 2
+    Unit:
+      Id: KUNAIWAIKYOKU
+      Range: 2
+      Interval: 250
+      Target: Enemy
+      Flag:
+        PathCheck: true
+    Status: Nightmare
+  - Id: 5486
+    Name: SS_KUNAIKAITEN
+    Description: Kunai - Rotation
+    MaxLevel: 5
+    Type: Weapon
+    TargetType: Self
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -3
+    Element: Weapon
+    DamageFlags:
+      IgnoreFlee: true
+    ActiveInstance: 2
+    AfterCastActDelay: 500
+    Duration1: 2000
+    Duration2: 2000
+    Cooldown: 2000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 44
+        - Level: 2
+          Amount: 52
+        - Level: 3
+          Amount: 60
+        - Level: 4
+          Amount: 68
+        - Level: 5
+          Amount: 76
+      Ammo:
+        Kunai: true
+      AmmoAmount: 5
+    Unit:
+      Id: KUNAIKAITEN
+      Range:
+        - Level: 1
+          Size: 2
+        - Level: 2
+          Size: 2
+        - Level: 3
+          Size: 3
+        - Level: 4
+          Size: 3
+        - Level: 5
+          Size: 4
+      Interval: 500
+      Target: Enemy
+      Flag:
+        PathCheck: true
+    Status: Shadow_Clock
+  - Id: 5487
+    Name: SS_KUNAIKUSSETSU
+    Description: Kunai - Refraction
+    MaxLevel: 10
+    Type: Weapon
+    TargetType: Self
+    Range: 1
+    Hit: Single
+    HitCount: 1
+    Element: Weapon
+    DamageFlags:
+      Splash: true
+      IgnoreFlee: true
+    SplashArea: 7
+    CastTime: 1500
+    AfterCastActDelay: 500
+    Duration1: 2000
+    Duration2: 2000
+    Cooldown: 2000
+    FixedCastTime: 500
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 49
+        - Level: 2
+          Amount: 52
+        - Level: 3
+          Amount: 55
+        - Level: 4
+          Amount: 58
+        - Level: 5
+          Amount: 61
+        - Level: 6
+          Amount: 64
+        - Level: 7
+          Amount: 67
+        - Level: 8
+          Amount: 70
+        - Level: 9
+          Amount: 73
+        - Level: 10
+          Amount: 76
+      Ammo:
+        Kunai: true
+      AmmoAmount: 5
+    Unit:
+      Id: Dummyskill
+      Range: 2
+      Interval: 250
+      Target: Enemy
+      Flag:
+        PathCheck: true
+  - Id: 5488
+    Name: SS_SEKIENHOU
+    Description: Red Flame Cannon
+    MaxLevel: 10
+    Type: Magic
+    TargetType: Ground
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -3
+    ActiveInstance: 7
+    Element: Fire
+    DamageFlags:
+      Splash: true
+    SplashArea: 1
+    CastTime: 2000
+    Cooldown: 700
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 65
+        - Level: 2
+          Amount: 68
+        - Level: 3
+          Amount: 71
+        - Level: 4
+          Amount: 74
+        - Level: 5
+          Amount: 77
+        - Level: 6
+          Amount: 80
+        - Level: 7
+          Amount: 83
+        - Level: 8
+          Amount: 86
+        - Level: 9
+          Amount: 89
+        - Level: 10
+          Amount: 92
+      ItemCost:
+        - Item: SS_Charm_F
+          Amount: 1
+  - Id: 5489
+    Name: SS_REIKETSUHOU
+    Description: Cold Blooded Cannon
+    MaxLevel: 10
+    Type: Magic
+    TargetType: Ground
+    Range: 9
+    Hit: Multi_Hit
+    HitCount: -6
+    Element: Water
+    DamageFlags:
+      Splash: true
+    SplashArea:
+      - Level: 1
+        Area: 2
+      - Level: 2
+        Area: 2
+      - Level: 3
+        Area: 2
+      - Level: 4
+        Area: 2
+      - Level: 5
+        Area: 2
+      - Level: 6
+        Area: 3
+      - Level: 7
+        Area: 3
+      - Level: 8
+        Area: 3
+      - Level: 9
+        Area: 3
+      - Level: 10
+        Area: 4
+    CastTime: 3000
+    Cooldown: 500
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 52
+        - Level: 2
+          Amount: 56
+        - Level: 3
+          Amount: 60
+        - Level: 4
+          Amount: 64
+        - Level: 5
+          Amount: 68
+        - Level: 6
+          Amount: 72
+        - Level: 7
+          Amount: 76
+        - Level: 8
+          Amount: 80
+        - Level: 9
+          Amount: 84
+        - Level: 10
+          Amount: 88
+      ItemCost:
+        - Item: SS_Charm_W
+          Amount: 1
+  - Id: 5490
+    Name: SS_RAIDENPOU
+    Description: Thundering Cannon
+    MaxLevel: 10
+    Type: Magic
+    TargetType: Ground
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -2
+    ActiveInstance: 13
+    Element: Wind
+    DamageFlags:
+      Splash: true
+    SplashArea: 1
+    CastTime: 2000
+    Cooldown: 700
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 47
+        - Level: 2
+          Amount: 52
+        - Level: 3
+          Amount: 57
+        - Level: 4
+          Amount: 62
+        - Level: 5
+          Amount: 67
+        - Level: 6
+          Amount: 72
+        - Level: 7
+          Amount: 77
+        - Level: 8
+          Amount: 82
+        - Level: 9
+          Amount: 87
+        - Level: 10
+          Amount: 92
+      ItemCost:
+        - Item: SS_Charm_L
+          Amount: 1
+  - Id: 5491
+    Name: SS_KINRYUUHOU
+    Description: Golden Dragon Cannon
+    MaxLevel: 10
+    Type: Magic
+    TargetType: Attack
+    Range: 13
+    Hit: Single
+    HitCount: 1
+    Element: Earth
+    DamageFlags:
+      Splash: true
+    SplashArea:
+      - Level: 1
+        Area: 2
+      - Level: 2
+        Area: 2
+      - Level: 3
+        Area: 2
+      - Level: 4
+        Area: 2
+      - Level: 5
+        Area: 3
+      - Level: 6
+        Area: 3
+      - Level: 7
+        Area: 3
+      - Level: 8
+        Area: 3
+      - Level: 9
+        Area: 4
+      - Level: 10
+        Area: 4
+    CastTime: 3000
+    Cooldown: 300
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 52
+        - Level: 2
+          Amount: 56
+        - Level: 3
+          Amount: 60
+        - Level: 4
+          Amount: 64
+        - Level: 5
+          Amount: 68
+        - Level: 6
+          Amount: 72
+        - Level: 7
+          Amount: 76
+        - Level: 8
+          Amount: 80
+        - Level: 9
+          Amount: 84
+        - Level: 10
+          Amount: 88
+      ItemCost:
+        - Item: SS_Charm_G
+          Amount: 1
+  - Id: 5492
+    Name: SS_ANTENPOU
+    Description: Darkening Cannon
+    MaxLevel: 10
+    Type: Magic
+    TargetType: Self
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -2
+    GiveAp: 2
+    Element: Dark
+    DamageFlags:
+      Splash: true
+    SplashArea:
+      - Level: 1
+        Area: 2
+      - Level: 2
+        Area: 2
+      - Level: 3
+        Area: 2
+      - Level: 4
+        Area: 2
+      - Level: 5
+        Area: 2
+      - Level: 6
+        Area: 3
+      - Level: 7
+        Area: 3
+      - Level: 8
+        Area: 3
+      - Level: 9
+        Area: 3
+      - Level: 10
+        Area: 3
+    CastTime: 3000
+    Cooldown: 500
+    FixedCastTime: 1000
+    Duration2: 5000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 40
+        - Level: 2
+          Amount: 46
+        - Level: 3
+          Amount: 52
+        - Level: 4
+          Amount: 58
+        - Level: 5
+          Amount: 64
+        - Level: 6
+          Amount: 70
+        - Level: 7
+          Amount: 76
+        - Level: 8
+          Amount: 82
+        - Level: 9
+          Amount: 88
+        - Level: 10
+          Amount: 94
+      ItemCost:
+        - Item: SS_Charm
+          Amount: 1
+    Status: Nightmare
+  - Id: 5493
+    Name: SS_KAGEAKUMU
+    Description: Shadow - Nightmare
+    MaxLevel: 1
+    Type: Weapon
+    TargetType: Self
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -4
+    Element: Weapon
+    DamageFlags:
+      Splash: true
+    SplashArea: 6
+    CastTime: 2000
+    AfterCastActDelay: 500
+    Cooldown: 1000
+    FixedCastTime: 500
+    Requires:
+      SpCost: 70
+      ApCost: 20
+  - Id: 5494
+    Name: SS_HITOUAKUMU
+    Description: Kunai - Nightmare
+    MaxLevel: 1
+    Type: Weapon
+    TargetType: Self
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -8
+    Element: Weapon
+    DamageFlags:
+      Splash: true
+      IgnoreFlee: true
+    SplashArea: 6
+    CastTime: 2000
+    AfterCastActDelay: 500
+    Cooldown: 1000
+    FixedCastTime: 500
+    Requires:
+      SpCost: 70
+      ApCost: 20
+  - Id: 5495
+    Name: SS_ANKOKURYUUAKUMU
+    Description: Dark Dragon - Nightmare
+    MaxLevel: 1
+    Type: Magic
+    TargetType: Self
+    Range: 1
+    Hit: Multi_Hit
+    HitCount: -4
+    Element: Dark
+    DamageFlags:
+      Splash: true
+    SplashArea: 5
+    CastTime: 2000
+    AfterCastActDelay: 500
+    Cooldown: 1000
+    FixedCastTime: 1000
+    Requires:
+      SpCost: 120
+      ApCost: 20
   - Id: 5496
     Name: NW_THE_VIGILANTE_AT_NIGHT_GUN_GATLING
     Description: The Vigilante At Night Gun Gatling

+ 206 - 0
db/re/skill_tree.yml

@@ -8394,3 +8394,209 @@ Body:
       Star_Gladiator: true
       Star_Emperor: true
       Sky_Emperor: true
+  - Job: Shinkiro
+    Inherit:
+      Novice: true
+      Ninja: true
+      Kagerou: true
+    Tree:
+      - Name: SS_SHINKIROU
+        MaxLevel: 1
+      - Name: SS_SEKIENHOU
+        MaxLevel: 10
+      - Name: SS_SHIMIRU
+        MaxLevel: 5
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+      - Name: SS_KUNAIWAIKYOKU
+        MaxLevel: 10
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+      - Name: SS_KAGEGARI
+        MaxLevel: 10
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+      - Name: SS_REIKETSUHOU
+        MaxLevel: 10
+      - Name: SS_TOKEDASU
+        MaxLevel: 5
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+      - Name: SS_KUNAIKAITEN
+        MaxLevel: 5
+        Requires:
+          - Name: SS_KUNAIWAIKYOKU
+            Level: 3
+      - Name: SS_FUUMASHOUAKU
+        MaxLevel: 10
+        Requires:
+          - Name: SS_KUNAIWAIKYOKU
+            Level: 3
+      - Name: SS_KAGENOMAI
+        MaxLevel: 10
+        Requires:
+          - Name: SS_KAGEGARI
+            Level: 3
+      - Name: SS_RAIDENPOU
+        MaxLevel: 10
+      - Name: SS_AKUMUKESU
+        MaxLevel: 1
+      - Name: SS_KUNAIKUSSETSU
+        MaxLevel: 10
+        Requires:
+          - Name: SS_KUNAIKAITEN
+            Level: 5
+      - Name: SS_FUUMAKOUCHIKU
+        MaxLevel: 10
+        Requires:
+          - Name: SS_FUUMASHOUAKU
+            Level: 5
+      - Name: SS_KAGEGISSEN
+        MaxLevel: 10
+        Requires:
+          - Name: SS_KAGENOMAI
+            Level: 5
+      - Name: SS_KINRYUUHOU
+        MaxLevel: 10
+      - Name: SS_HITOUAKUMU
+        MaxLevel: 1
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+          - Name: SS_KUNAIWAIKYOKU
+            Level: 5
+          - Name: SS_KUNAIKAITEN
+            Level: 5
+          - Name: SS_KUNAIKUSSETSU
+            Level: 5
+      - Name: SS_KAGEAKUMU
+        MaxLevel: 1
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+          - Name: SS_KAGEGISSEN
+            Level: 7
+      - Name: SS_ANTENPOU
+        MaxLevel: 10
+      - Name: SS_ANKOKURYUUAKUMU
+        MaxLevel: 1
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+          - Name: SS_SEKIENHOU
+            Level: 5
+          - Name: SS_REIKETSUHOU
+            Level: 5
+          - Name: SS_RAIDENPOU
+            Level: 5
+          - Name: SS_KINRYUUHOU
+            Level: 5
+          - Name: SS_ANTENPOU
+            Level: 5
+  - Job: Shiranui
+    Inherit:
+      Novice: true
+      Ninja: true
+      Oboro: true
+    Tree:
+      - Name: SS_SHINKIROU
+        MaxLevel: 1
+      - Name: SS_SEKIENHOU
+        MaxLevel: 10
+      - Name: SS_SHIMIRU
+        MaxLevel: 5
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+      - Name: SS_KUNAIWAIKYOKU
+        MaxLevel: 10
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+      - Name: SS_KAGEGARI
+        MaxLevel: 10
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+      - Name: SS_REIKETSUHOU
+        MaxLevel: 10
+      - Name: SS_TOKEDASU
+        MaxLevel: 5
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+      - Name: SS_KUNAIKAITEN
+        MaxLevel: 5
+        Requires:
+          - Name: SS_KUNAIWAIKYOKU
+            Level: 3
+      - Name: SS_FUUMASHOUAKU
+        MaxLevel: 10
+        Requires:
+          - Name: SS_KUNAIWAIKYOKU
+            Level: 3
+      - Name: SS_KAGENOMAI
+        MaxLevel: 10
+        Requires:
+          - Name: SS_KAGEGARI
+            Level: 3
+      - Name: SS_RAIDENPOU
+        MaxLevel: 10
+      - Name: SS_AKUMUKESU
+        MaxLevel: 1
+      - Name: SS_KUNAIKUSSETSU
+        MaxLevel: 10
+        Requires:
+          - Name: SS_KUNAIKAITEN
+            Level: 5
+      - Name: SS_FUUMAKOUCHIKU
+        MaxLevel: 10
+        Requires:
+          - Name: SS_FUUMASHOUAKU
+            Level: 5
+      - Name: SS_KAGEGISSEN
+        MaxLevel: 10
+        Requires:
+          - Name: SS_KAGENOMAI
+            Level: 5
+      - Name: SS_KINRYUUHOU
+        MaxLevel: 10
+      - Name: SS_HITOUAKUMU
+        MaxLevel: 1
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+          - Name: SS_KUNAIWAIKYOKU
+            Level: 5
+          - Name: SS_KUNAIKAITEN
+            Level: 5
+          - Name: SS_KUNAIKUSSETSU
+            Level: 5
+      - Name: SS_KAGEAKUMU
+        MaxLevel: 1
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+          - Name: SS_KAGEGISSEN
+            Level: 7
+      - Name: SS_ANTENPOU
+        MaxLevel: 10
+      - Name: SS_ANKOKURYUUAKUMU
+        MaxLevel: 1
+        Requires:
+          - Name: SS_SHINKIROU
+            Level: 1
+          - Name: SS_SEKIENHOU
+            Level: 5
+          - Name: SS_REIKETSUHOU
+            Level: 5
+          - Name: SS_RAIDENPOU
+            Level: 5
+          - Name: SS_KINRYUUHOU
+            Level: 5
+          - Name: SS_ANTENPOU
+            Level: 5

+ 17 - 0
db/re/status.yml

@@ -9756,3 +9756,20 @@ Body:
       NoBanishingBuster: true
       NoDispell: true
       NoClearance: true
+  - Status: Shadow_Clock
+    Icon: EFST_SHADOW_CLOCK
+    DurationLookup: SS_TOKEDASU
+    CalcFlags:
+      Speed: true
+  - Status: Shinkirou_Call
+    Icon: EFST_SBUNSHIN
+    DurationLookup: SS_SHINKIROU
+    CalcFlags:
+      Speed: true
+  - Status: Nightmare
+    Icon: EFST_NIGHTMARE
+    DurationLookup: SS_KAGEGARI
+    Flags:
+      Debuff: true
+      BlEffect: true
+      DisplayPc: true

+ 157 - 6
src/map/battle.cpp

@@ -1771,6 +1771,10 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		}
 #endif
 
+		if( tsc->getSCE( SC_SHADOW_CLOCK ) != nullptr && ( flag&(BF_WEAPON|BF_MAGIC) ) ){
+			damage = damage * 85 / 100;
+		}
+
 		if (tsc->getSCE(SC_DEFENDER) &&
 			skill_id != NJ_ZENYNAGE && skill_id != KO_MUCHANAGE &&
 #ifdef RENEWAL
@@ -2622,6 +2626,10 @@ static int32 battle_range_type(struct block_list *src, struct block_list *target
 		case BO_ACIDIFIED_ZONE_GROUND_ATK:
 		case BO_ACIDIFIED_ZONE_WIND_ATK:
 		case NW_THE_VIGILANTE_AT_NIGHT:
+		case SS_FUUMAKOUCHIKU:
+		case SS_KUNAIKAITEN:
+		case SS_KUNAIKUSSETSU:
+		case SS_HITOUAKUMU:
 			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
@@ -2634,6 +2642,7 @@ static int32 battle_range_type(struct block_list *src, struct block_list *target
 		case MH_THE_ONE_FIGHTER_RISES: // 7 cell cast range.
 		//case ABC_DEFT_STAB: // 2 cell cast range???
 		case NPC_MAXPAIN_ATK:
+		case SS_SHIMIRU: // 11 cell cast range.
 			return BF_SHORT;
 		case CD_PETITIO: { // Skill range is 2 but damage is melee with books and ranged with mace.
 			map_session_data *sd = BL_CAST(BL_PC, src);
@@ -2848,14 +2857,33 @@ bool is_infinite_defense(struct block_list *target, int32 flag)
  */
 static bool is_skill_using_arrow(struct block_list *src, int32 skill_id)
 {
-	if(src != nullptr) {
+	if (src == nullptr)
+		return false;
+
+	map_session_data *sd = BL_CAST(BL_PC, src);
+
+	if (sd != nullptr && sd->state.arrow_atk)
+		return true;
+
+	if (sd == nullptr && skill_id != 0) {
+		if (skill_get_ammotype(skill_id) != 0)
+			return true;
+
 		status_data* sstatus = status_get_status_data(*src);
-		map_session_data *sd = BL_CAST(BL_PC, src);
 
-		return ((sd && sd->state.arrow_atk) || (!sd && ((skill_id && skill_get_ammotype(skill_id)) || sstatus->rhw.range>3))
-			|| skill_id == HT_FREEZINGTRAP || (skill_id == HT_PHANTASMIC) || (skill_id == GS_GROUNDDRIFT));
-	} else
-		return false;
+		if (sstatus->rhw.range > 3)
+			return true;
+	}
+
+	switch( skill_id ) {
+		case HT_PHANTASMIC:
+		case GS_GROUNDDRIFT:
+		case SS_KUNAIKUSSETSU:
+		case SS_KUNAIKAITEN:
+			return true;
+	}
+
+	return false;
 }
 
 /*=========================================
@@ -3528,6 +3556,12 @@ int32 battle_get_weapon_element(struct Damage* wd, struct block_list *src, struc
 				}
 			}
 			break;
+		case SS_FUUMASHOUAKU:
+		case SS_FUUMAKOUCHIKU:
+			if( sd != nullptr ){
+				element = sd->bonus.arrow_ele;
+			}
+			break;
 	}
 
 	if (sc && sc->getSCE(SC_GOLDENE_FERSE) && ((!skill_id && (rnd() % 100 < sc->getSCE(SC_GOLDENE_FERSE)->val4)) || skill_id == MH_STAHL_HORN))
@@ -3629,6 +3663,10 @@ int32 battle_get_magic_element(struct block_list* src, struct block_list* target
 				}
 			}
 			break;
+		case SS_ANKOKURYUUAKUMU:
+			if (mflag & SKILL_ALTDMG_FLAG)
+				element = ELE_FIRE;
+			break;
 	}
 
 	return element;
@@ -6481,6 +6519,78 @@ static int32 battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list
 			skillratio += 5 * sstatus->pow;
 			RE_LVL_DMOD(100);
 			break;
+		case SS_SHIMIRU:
+			skillratio += -100 + 700 * skill_lv;
+			skillratio += 5 * sstatus->con;
+			RE_LVL_DMOD(100);
+			break;
+		case SS_KAGEGARI:
+			skillratio += -100 + 500 + 400 * skill_lv;
+			skillratio += pc_checkskill( sd, SS_KAGEGISSEN ) * 5 * skill_lv;
+			skillratio += 5 * sstatus->pow;
+			RE_LVL_DMOD(100);
+			break;
+		case SS_KAGEAKUMU:
+		case SS_HITOUAKUMU:
+			skillratio += -100 + 18000 + 5 * sstatus->pow;
+
+			if( tsc != nullptr && tsc->getSCE( SC_NIGHTMARE ) != nullptr ){
+				skillratio += skillratio / 2;
+			}
+
+			RE_LVL_DMOD(100);
+			break;
+		case SS_KAGENOMAI:
+			skillratio += -100 + 400 + 550 * skill_lv;
+			skillratio += pc_checkskill( sd, SS_KAGEGARI ) * 50 * skill_lv;
+			skillratio += 5 * sstatus->pow;
+			RE_LVL_DMOD(100);
+			if (wd->miscflag & SKILL_ALTDMG_FLAG)
+				skillratio = skillratio * 3 / 10;
+			break;
+		case SS_FUUMASHOUAKU:
+			skillratio += -100 + 700 + 200 * skill_lv;
+			skillratio += pc_checkskill( sd, SS_FUUMAKOUCHIKU ) * 5 * skill_lv;
+			skillratio += 5 * sstatus->pow;
+			RE_LVL_DMOD(100);
+			break;
+		case SS_FUUMAKOUCHIKU:
+			skillratio += -100 + 600 + 400 * skill_lv;
+			if( wd->miscflag&SKILL_ALTDMG_FLAG ){
+				skillratio += 200;
+			}
+			skillratio += pc_checkskill( sd, SS_FUUMASHOUAKU ) * 30 * skill_lv;
+			skillratio += 5 * sstatus->pow;
+			RE_LVL_DMOD(100);
+			break;
+		case SS_KUNAIWAIKYOKU:
+			skillratio += -100 + 300 + 600 * skill_lv;
+			skillratio += pc_checkskill( sd, SS_KUNAIKUSSETSU ) * 10 * skill_lv;
+			skillratio += 5 * sstatus->pow;
+			RE_LVL_DMOD(100);
+			if (wd->miscflag & SKILL_ALTDMG_FLAG)
+				skillratio = skillratio * 3 / 10;
+			break;
+		case SS_KUNAIKUSSETSU:
+			skillratio += -100 + 200 + 360 * skill_lv;
+			skillratio += pc_checkskill( sd, SS_KUNAIKAITEN ) * 10 * skill_lv;
+			skillratio += 5 * sstatus->pow;
+			RE_LVL_DMOD(100);
+			break;
+		case SS_KUNAIKAITEN:
+			skillratio += -100 + 800 + 700 * skill_lv;
+			skillratio += pc_checkskill( sd, SS_KUNAIWAIKYOKU ) * 70 * skill_lv;
+			skillratio += 5 * sstatus->pow;
+			RE_LVL_DMOD(100);
+			break;
+		case SS_KAGEGISSEN:
+			skillratio += -100 + 1600 + 700 * skill_lv;
+			skillratio += pc_checkskill( sd, SS_KAGENOMAI ) * 100 * skill_lv;
+			skillratio += 5 * sstatus->pow;
+			RE_LVL_DMOD(100);
+			if (wd->miscflag & SKILL_ALTDMG_FLAG)
+				skillratio = skillratio * 3 / 10;
+			break;
 	}
 	return skillratio;
 }
@@ -9067,6 +9177,47 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						}
 						RE_LVL_DMOD(100);
 						break;
+					case SS_TOKEDASU:
+						skillratio += -100 + 700 * skill_lv;
+						skillratio += 5 * sstatus->con;
+						RE_LVL_DMOD(100);
+						break;
+					case SS_SEKIENHOU:
+						skillratio += -100 + 850 + 1250 * skill_lv;
+						skillratio += 70 * pc_checkskill( sd, SS_ANTENPOU ) * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						break;
+					case SS_REIKETSUHOU:
+						skillratio += -100 + 250 + 550 * skill_lv;
+						skillratio += 40 * pc_checkskill( sd, SS_ANTENPOU ) * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						break;
+					case SS_KINRYUUHOU:
+						skillratio += -100 + 300 + 400 * skill_lv;
+						skillratio += 15 * pc_checkskill( sd, SS_ANTENPOU ) * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						break;
+					case SS_ANKOKURYUUAKUMU:
+						skillratio += -100 + 15500 * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						break;
+					case SS_RAIDENPOU:
+						skillratio += -100 + 600 + 1300 * skill_lv;
+						skillratio += 70 * pc_checkskill( sd, SS_ANTENPOU ) * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						break;
+					case SS_ANTENPOU:
+						skillratio += -100 + 450 + 950 * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						if (mflag & SKILL_ALTDMG_FLAG)
+							skillratio = skillratio * 3 / 10;
+						break;
 				}
 
 				if (sc) {// Insignia's increases the damage of offensive magic by a fixed percentage depending on the element.

+ 1 - 1
src/map/party.cpp

@@ -408,7 +408,7 @@ bool party_invite( map_session_data& sd, map_session_data *tsd ){
 		return false;
 	}
 
-	if( tsd == NULL ){
+	if( tsd == nullptr ){
 		clif_party_invite_reply( sd, "", PARTY_REPLY_OFFLINE );
 		return false;
 	}

+ 5 - 0
src/map/script_constants.hpp

@@ -1964,6 +1964,10 @@
 	export_constant(SC_STAR_BURST);
 	export_constant(SC_SKY_ENCHANT);
 	export_constant(SC_WILD_WALK);
+	export_constant(SC_SHADOW_CLOCK);
+	export_constant(SC_SHINKIROU_CALL);
+	export_constant(SC_NIGHTMARE);
+	export_constant(SC_SBUNSHIN);
 
 /// Do not modify code below this, until the end of the API hook, since it will be automatically generated again
 /// @APIHOOK_START(EFST_CONST)
@@ -10289,6 +10293,7 @@
 	export_constant(UNT_GROUND_GRAVITATION);
 	export_constant(UNT_KUNAIWAIKYOKU);
 	export_constant(UNT_STAR_BURST);
+	export_constant(UNT_KUNAIKAITEN);
 	export_constant(UNT_GD_LEADERSHIP);
 	export_constant(UNT_GD_GLORYWOUNDS);
 	export_constant(UNT_GD_SOULCOLD);

+ 303 - 1
src/map/skill.cpp

@@ -2231,6 +2231,17 @@ int32 skill_additional_effect( struct block_list* src, struct block_list *bl, ui
 	case SH_HOWLING_OF_CHUL_HO:
 		sc_start(src, bl, skill_get_sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
 		break;
+	case SS_KAGEGARI:
+	case SS_FUUMASHOUAKU:
+	case SS_KUNAIWAIKYOKU:
+	case SS_ANTENPOU:
+		sc_start(src, bl, skill_get_sc(skill_id), 100, skill_lv, skill_get_time2(skill_id, skill_lv));
+		break;
+	case SS_KAGEAKUMU:
+	case SS_HITOUAKUMU:
+	case SS_ANKOKURYUUAKUMU:
+		status_change_end(bl, SC_NIGHTMARE);
+		break;
 	} //end switch skill_id
 
 	if (md && battle_config.summons_trigger_autospells && md->master_id && md->special_state.ai && md->special_state.ai != AI_ABR && md->special_state.ai != AI_BIONIC)
@@ -5137,6 +5148,70 @@ static int32 skill_tarotcard(struct block_list* src, struct block_list *target,
 	return card;
 }
 
+bool skill_mirage_cast( block_list& src, block_list* bl, uint16 skill_id, uint16 skill_lv, int16 x, int16 y, t_tick tick, int32 flag ){
+	unit_data* ud = unit_bl2ud( &src );
+
+	if( ud == nullptr || src.type != BL_PC || (flag&1) ){
+		return false;
+	}
+
+	for( const std::shared_ptr<s_skill_unit_group>& sug : ud->skillunits ){
+		if( sug->skill_id != SS_SHINKIROU ){
+			continue;
+		}
+
+		skill_unit* su = sug->unit;
+
+		if( su == nullptr ){
+			continue;
+		}
+
+		switch( skill_id ){
+			case SS_KUNAIWAIKYOKU: {
+				if( distance_xy( x, y, su->bl.x, su->bl.y ) > skill_get_range( skill_id, skill_lv ) ){
+					continue;
+				}
+				clif_skill_poseffect( su->bl, skill_id, skill_lv, x, y, tick );
+				int32 range = skill_get_splash( skill_id, skill_lv );
+				map_foreachinallarea( skill_area_sub, src.m, x - range, y - range, x + range, y + range, BL_CHAR, &src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SKILL_ALTDMG_FLAG | 1, skill_castend_damage_id );
+				} break;
+			case SS_KAGENOMAI://nodamage splash
+			case SS_ANTENPOU://nodamage splash
+				clif_skill_nodamage( &su->bl, su->bl, skill_id, skill_lv, tick );
+				map_foreachinrange( skill_area_sub, &su->bl, skill_get_splash( skill_id, skill_lv ), BL_CHAR, &src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | SD_ANIMATION | SKILL_ALTDMG_FLAG | 1, skill_castend_damage_id );
+				break;
+			case SS_KAGEGISSEN://damage splash
+				x = bl->x;
+				y = bl->y;
+				skill_area_temp[1] = 0;
+				clif_skill_nodamage( &su->bl, *bl, skill_id, skill_lv, tick );
+				if (battle_config.skill_eightpath_algorithm) {
+					//Use official AoE algorithm
+					map_foreachindir( skill_attack_area, su->bl.m, su->bl.x, su->bl.y, x, y, skill_get_splash( skill_id, skill_lv ), skill_get_maxcount( skill_id, skill_lv ), 0, splash_target( &src ), skill_get_type( skill_id ), &src, &src, skill_id, skill_lv, tick, SKILL_ALTDMG_FLAG, BCT_ENEMY );
+				} else {
+					map_foreachinpath( skill_attack_area, su->bl.m, su->bl.x, su->bl.y, x, y, skill_get_splash( skill_id, skill_lv ), skill_get_maxcount( skill_id, skill_lv ), splash_target( &src ), skill_get_type( skill_id ), &src, &src, skill_id, skill_lv, tick, SKILL_ALTDMG_FLAG, BCT_ENEMY );
+				}
+				break;
+		}
+	}
+
+	return true;
+}
+
+int32 skill_shimiru_check_cell( block_list* target, va_list ap ){
+	if( target != nullptr && target->type == BL_SKILL ){
+		skill_unit* su = reinterpret_cast<skill_unit*>( target );
+
+		if( su->group != nullptr && su->group->skill_id == SS_SHINKIROU ){
+			return 1;
+		}
+
+		return 0;
+	}
+
+	return 1;
+}
+
 /*==========================================
  *
  *
@@ -5318,6 +5393,7 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 	case SKE_MIDNIGHT_KICK:
 	case SKE_DAWN_BREAK:
 	case SKE_RISING_MOON:
+	case SS_FUUMAKOUCHIKU:
 		skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
 		break;
 	case DK_DRAGONIC_AURA:
@@ -5450,6 +5526,10 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 		}
 		break;
 
+	case SS_KAGEGISSEN:
+		skill_mirage_cast(*src, bl, skill_id, skill_lv, 0, 0, tick, flag);
+		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+		[[fallthrough]];
 	case NC_FLAMELAUNCHER:
 		skill_area_temp[1] = bl->id;
 		if (battle_config.skill_eightpath_algorithm) {
@@ -5797,6 +5877,7 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 	case SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS:
 	case SKE_SUNSET_BLAST:
 	case SKE_NOON_BLAST:
+	case SS_KINRYUUHOU:
 		if( flag&1 ) {//Recursive invocation
 			int32 sflag = skill_area_temp[0] & 0xFFF;
 			int32 heal = 0;
@@ -6024,6 +6105,10 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 					skill_area_temp[0] = map_foreachinallrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, BCT_ENEMY, skill_area_sub_count);
 					sc_start(src,src,skill_get_sc(skill_id),100,skill_lv,skill_get_time(skill_id,skill_lv));
 					break;
+				case SS_KINRYUUHOU:
+					skill_mirage_cast(*src, nullptr, SS_ANTENPOU, skill_lv, 0, 0, tick, flag | BCT_WOS);
+					clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+					break;
 			}
 
 			// if skill damage should be split among targets, count them
@@ -6151,6 +6236,83 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 		skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
 		break;
 
+	case SS_KAGEGARI:
+	case SS_TOKEDASU:
+	case SS_KAGEAKUMU:
+	case SS_HITOUAKUMU:
+	case SS_KAGENOMAI:
+	case SS_ANTENPOU:
+	case SS_REIKETSUHOU:
+	case SS_KUNAIWAIKYOKU:
+		if (flag & 1)
+			skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+		break;
+	case SS_ANKOKURYUUAKUMU:
+		if (flag & 1) {
+			skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+
+			if( tsc != nullptr && tsc->getSCE( SC_NIGHTMARE ) != nullptr ){
+				skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag | SKILL_ALTDMG_FLAG);
+			}
+		}
+		break;
+	case SS_SHIMIRU: {
+		struct unit_data *ud = unit_bl2ud(src);
+
+		if (!check_distance_bl(src, bl, 0)) {
+			uint8 dir = map_calc_dir(src, bl->x, bl->y);
+			int16 x, y;
+
+			if (dir > DIR_NORTH && dir < DIR_SOUTH)
+				x = -1;
+			else if (dir > DIR_SOUTH)
+				x = 1;
+			else
+				x = 0;
+
+			if (dir > DIR_WEST && dir < DIR_EAST)
+				y = -1;
+			else if (dir == DIR_NORTHEAST || dir < DIR_WEST)
+				y = 1;
+			else
+				y = 0;
+
+			if (battle_check_target(src, bl, BCT_ENEMY) > 0 && unit_movepos(src, bl->x + x, bl->y + y, 2, true)) {// Display movement + animation.
+				dir = dir < 4 ? dir+4 : dir-4; // change direction [Celest]
+				unit_setdir(bl,dir);
+				clif_blown(src);
+			} else if (sd) {
+				clif_skill_fail( *sd, skill_id, USESKILL_FAIL_TARGET_SHADOW_SPACE );
+				break;
+			}
+		}
+
+		if (ud == nullptr)
+			break;
+
+		for (const std::shared_ptr<s_skill_unit_group>& sug : ud->skillunits) {
+			skill_unit* su = sug->unit;
+			std::shared_ptr<s_skill_unit_group> sg = su->group;
+			int16 dx = src->x - su->bl.x;
+			int16 dy = src->y - su->bl.y;
+
+			for( size_t count = 0; count < 1000; count++ ){
+				if (map_foreachincell(skill_shimiru_check_cell, src->m, su->bl.x + dx, su->bl.y + dy, BL_CHAR|BL_SKILL) == 0)
+					break;
+				dx += rnd() % 3 - 1;
+				dy += rnd() % 3 - 1;
+			}
+
+			if (sug->skill_id == SS_SHINKIROU)
+				skill_unit_move_unit_group(sg, src->m, dx,dy);
+		}
+
+		skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+
+		sc_start(src, src, skill_get_sc(skill_id), 100, skill_lv, skill_get_time2(skill_id, skill_lv));
+		break;
+	}
+
 	//Place units around target
 	case NJ_BAKUENRYU:
 		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
@@ -13443,6 +13605,32 @@ int32 skill_castend_nodamage_id (struct block_list *src, struct block_list *bl,
 		clif_skill_nodamage(src, *src, skill_id, skill_lv);
 		break;
 
+
+	case SS_ANTENPOU:
+	case SS_KAGENOMAI:
+		skill_mirage_cast(*src, nullptr,skill_id, skill_lv, 0, 0, tick, flag | BCT_WOS);
+		[[fallthrough]];
+	case SS_KAGEAKUMU:
+	case SS_ANKOKURYUUAKUMU:
+	case SS_HITOUAKUMU: {
+		int32 range = skill_get_splash( skill_id, skill_lv );
+
+		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+
+		map_foreachinrange( skill_area_sub, bl, range, BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_damage_id );
+		} break;
+	case SS_AKUMUKESU:
+		if (flag & 1) {
+			status_change_end(bl, SC_NIGHTMARE);
+		} else {
+			int32 range = skill_get_splash( skill_id, skill_lv );
+
+			clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+
+			map_foreachinrange( skill_area_sub, bl, range, BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | 1, skill_castend_nodamage_id );
+		}
+		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);
@@ -14487,6 +14675,7 @@ int32 skill_castend_pos2(struct block_list* src, int32 x, int32 y, uint16 skill_
 	case GS_GROUNDDRIFT: //Ammo should be deleted right away.
 	case GN_WALLOFTHORN:
 	case GN_DEMONIC_FIRE:
+	case SS_FUUMASHOUAKU:
 		skill_unitsetting(src,skill_id,skill_lv,x,y,0);
 		break;
 
@@ -15338,6 +15527,88 @@ int32 skill_castend_pos2(struct block_list* src, int32 x, int32 y, uint16 skill_
 			}
 		} break;
 
+	case SS_KUNAIKUSSETSU:
+		map_foreachinallrange(skill_detonator, src, skill_get_splash(skill_id, skill_lv), BL_SKILL, src, skill_lv);
+		clif_skill_nodamage(src, *src, skill_id, skill_lv);
+		break;
+	case SS_RAIDENPOU:
+	case SS_SEKIENHOU:
+		skill_area_temp[1] = 0;
+		skill_mirage_cast(*src, nullptr, SS_ANTENPOU, skill_lv, x, y, tick, flag | BCT_WOS);
+		if (map_getcell(src->m, x, y, CELL_CHKLANDPROTECTOR)) {
+			clif_skill_fail( *sd, skill_id, USESKILL_FAIL );
+			return 0;
+		}
+		clif_skill_nodamage(src, *src, skill_id, skill_lv);
+		if (battle_config.skill_eightpath_algorithm) {
+			//Use official AoE algorithm
+			map_foreachindir(skill_attack_area, src->m, src->x, src->y, x, y,
+				skill_get_splash(skill_id, skill_lv), skill_get_maxcount(skill_id, skill_lv), 0, splash_target(src),
+				skill_get_type(skill_id), src, src, skill_id, skill_lv, tick, flag, BCT_ENEMY);
+		}
+		else {
+			map_foreachinpath(skill_attack_area, src->m, src->x, src->y, x, y,
+				skill_get_splash(skill_id, skill_lv), skill_get_maxcount(skill_id, skill_lv), splash_target(src),
+				skill_get_type(skill_id), src, src, skill_id, skill_lv, tick, flag, BCT_ENEMY);
+		}
+		break;
+	case SS_SHINKIROU:
+		flag |= 1;
+		clif_skill_nodamage(src, *src, skill_id, skill_lv);
+		sc_start(src, src, skill_get_sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
+		skill_unitsetting(src, skill_id, skill_lv, x, y, 0);
+		break;
+	case SS_KAGEGARI:
+		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);
+		break;
+	case SS_REIKETSUHOU:
+		skill_mirage_cast(*src, nullptr, SS_ANTENPOU, skill_lv, 0, 0, tick, flag | BCT_WOS);
+		if (map_getcell(src->m, x, y, CELL_CHKLANDPROTECTOR)) {
+			clif_skill_fail( *sd, skill_id, USESKILL_FAIL );
+			return 0;
+		}
+		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);
+		break;
+	case SS_KUNAIWAIKYOKU:
+		skill_mirage_cast(*src, nullptr, skill_id, skill_lv, x, y, tick, flag | BCT_WOS);
+		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);
+		skill_unitsetting(src, skill_id, skill_lv, x, y, UNIT_NOCONSUME_AMMO);
+		break;
+	case SS_KUNAIKAITEN:
+		sc_start(src, src, skill_get_sc(skill_id), 100, skill_lv, skill_get_time2(skill_id, skill_lv));
+		skill_unitsetting(src, skill_id, skill_lv, x, y, UNIT_NOCONSUME_AMMO);
+		skill_unitsetting(src, SS_KUNAIWAIKYOKU, skill_lv, x, y, UNIT_NOCONSUME_AMMO);
+		break;
+	case SS_FUUMAKOUCHIKU:
+		skill_area_temp[1] = 0;
+		if (battle_config.skill_eightpath_algorithm) {
+			//Use official AoE algorithm
+			map_foreachindir(skill_attack_area, src->m, src->x, src->y, x, y,
+				skill_get_splash(skill_id, skill_lv), skill_get_maxcount(skill_id, skill_lv), 0, BL_CHAR | BL_SKILL,
+				skill_get_type(skill_id), src, src, skill_id, skill_lv, tick, flag, BCT_ENEMY);
+		}
+		else {
+			map_foreachinpath(skill_attack_area, src->m, src->x, src->y, x, y,
+				skill_get_splash(skill_id, skill_lv), skill_get_maxcount(skill_id, skill_lv), BL_CHAR | BL_SKILL,
+				skill_get_type(skill_id), src, src, skill_id, skill_lv, tick, flag, BCT_ENEMY);
+		}
+		break;
+	case SS_TOKEDASU:
+		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);
+		sc_start(src, src, skill_get_sc(skill_id), 100, skill_lv, skill_get_time2(skill_id, skill_lv));
+		unit_setdir(src, map_calc_dir_xy(src->x, src->y, x, y, unit_getdir(src)));
+		skill_blown(src, src, skill_get_blewcount(skill_id, skill_lv), unit_getdir(src), (enum e_skill_blown)(BLOWN_IGNORE_NO_KNOCKBACK | BLOWN_DONT_SEND_PACKET));
+		clif_blown(src);
+		break;
+
 	default:
 		ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skill_id);
 		return 1;
@@ -16023,7 +16294,8 @@ std::shared_ptr<s_skill_unit_group> skill_unitsetting(struct block_list *src, ui
 	group->link_group_id = link_group_id;
 	group->target_flag = target;
 	group->bl_flag = skill_get_unit_bl_target(skill_id);
-	group->state.ammo_consume = (sd && sd->state.arrow_atk && skill_id != GS_GROUNDDRIFT); //Store if this skill needs to consume ammo.
+	// Store if this skill needs to consume ammo.
+	group->state.ammo_consume = ( sd != nullptr && sd->state.arrow_atk && skill_id != GS_GROUNDDRIFT && !( flag&UNIT_NOCONSUME_AMMO ) );
 	group->state.song_dance = (((skill->unit_flag[UF_DANCE] || skill->unit_flag[UF_SONG])?1:0)|(skill->unit_flag[UF_ENSEMBLE]?2:0)); //Signals if this is a song/dance/duet
 	group->state.guildaura = ( skill_id >= GD_LEADERSHIP && skill_id <= GD_HAWKEYES )?1:0;
 	group->item_id = req_item;
@@ -16653,6 +16925,8 @@ int32 skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t
 		case UNT_STAR_BURST:
 		case UNT_GRENADES_DROPPING:
 		case UNT_MISSION_BOMBARD:
+		case UNT_FUUMASHOUAKU:
+		case UNT_KUNAIKAITEN:
 			skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
 			break;
 #ifdef RENEWAL
@@ -20728,6 +21002,21 @@ int32 skill_attack_area(struct block_list *bl, va_list ap)
 		return (int32)skill_attack(atk_type,src,dsrc,bl,skill_id,skill_lv,tick,flag);
 	}
 
+	if (skill_id == SS_FUUMAKOUCHIKU && bl->type == BL_SKILL) {
+		skill_unit* unit = reinterpret_cast<skill_unit*>( bl );
+
+		if( unit->group == nullptr ){
+			return 0;
+		}
+
+		if (unit->group->skill_id == SS_FUUMASHOUAKU) {
+			map_foreachinallrange(skill_area_sub, bl, skill_get_splash(SS_FUUMAKOUCHIKU,skill_lv), BL_CHAR,
+				src, SS_FUUMAKOUCHIKU, skill_lv, tick, flag | BCT_ENEMY | SD_SPLASH | SKILL_ALTDMG_FLAG | 1, skill_castend_damage_id);
+			skill_delunit(unit);
+			return 1;
+		}
+	}
+
 	if(battle_check_target(dsrc,bl,type) <= 0 ||
 		!status_check_skilluse(nullptr, bl, skill_id, 2))
 		return 0;
@@ -20896,6 +21185,7 @@ int32 skill_detonator(struct block_list *bl, va_list ap)
 
 	block_list *src = va_arg(ap, block_list *);
 	skill_unit *unit = (skill_unit *)bl;
+	int32 flag = va_arg( ap, int32 );
 
 	if (unit == nullptr)
 		return 0;
@@ -20937,6 +21227,11 @@ int32 skill_detonator(struct block_list *bl, va_list ap)
 			group->limit = DIFF_TICK(gettick(),group->tick) +
 				(unit_id == UNT_TALKIEBOX ? 5000 : (unit_id == UNT_CLUSTERBOMB || unit_id == UNT_ICEBOUNDTRAP? 2500 : (unit_id == UNT_FIRINGTRAP ? 0 : 1500)) );
 			break;
+
+		case UNT_KUNAIWAIKYOKU:
+			skill_delunit(unit);
+			skill_unitsetting(src, SS_KUNAIKUSSETSU, flag, bl->x, bl->y, UNIT_NOCONSUME_AMMO);
+			break;
 	}
 	return 0;
 }
@@ -21101,6 +21396,13 @@ static int32 skill_cell_overlap(struct block_list *bl, va_list ap)
 				}
 			}
 			break;
+
+		case SS_KUNAIWAIKYOKU:
+			if (unit->group->skill_id == skill_id) {
+				skill_delunit(unit);
+				return 1;
+			}
+			break;
 	}
 
 	std::bitset<INF2_MAX> inf2 = skill_db.find(skill_id)->inf2;

+ 4 - 3
src/map/skill.hpp

@@ -43,6 +43,8 @@ class status_change;
 #define SKILL_ALTDMG_FLAG 0x10
 /// Make skill ignore requirement consumption [Muh]
 #define SKILL_NOCONSUME_REQ 0x20
+/// Make skill consume ammo, but not the unit [Muh]
+#define UNIT_NOCONSUME_AMMO 0x40
 
 /// Constants to identify a skill's nk value (damage properties)
 /// The NK value applies only to non INF_GROUND_SKILL skills
@@ -2347,7 +2349,6 @@ enum e_skill {
 
 	NW_THE_VIGILANTE_AT_NIGHT_GUN_GATLING,
 	NW_THE_VIGILANTE_AT_NIGHT_GUN_SHOTGUN,
-	SS_FUUMAKOUCHIKU_BLASTING,
 
 	SS_FOUR_CHARM = 5499,
 	NW_WILD_SHOT,
@@ -2732,8 +2733,8 @@ enum e_skill_unit_id : uint16 {
 	UNT_SHINKIROU, // Mirage
 	UNT_JACK_FROST_NOVA,
 	UNT_GROUND_GRAVITATION,
-
-	UNT_KUNAIWAIKYOKU = 298, // Kunai - Distortion
+	UNT_KUNAIKAITEN, // Shows Nothing
+	UNT_KUNAIWAIKYOKU, // Kunai - Distortion
 
 	UNT_STAR_BURST = 2409,
 

+ 3 - 0
src/map/status.cpp

@@ -7902,6 +7902,9 @@ static uint16 status_calc_speed(struct block_list *bl, status_change *sc, int32
 				val = max(val, 20);
 			if (sc->getSCE(SC_GROUNDGRAVITY))
 				val = max(val, 20);
+			if( sc->getSCE( SC_SHADOW_CLOCK ) != nullptr ){
+				val = max( val, 30 );
+			}
 
 			if( sd && sd->bonus.speed_rate + sd->bonus.speed_add_rate > 0 ) // Permanent item-based speedup
 				val = max( val, sd->bonus.speed_rate + sd->bonus.speed_add_rate );

+ 6 - 0
src/map/status.hpp

@@ -1416,6 +1416,12 @@ enum sc_type : int16 {
 	SC_SKY_ENCHANT,
 	SC_WILD_WALK,
 
+	// Shinkiro/Shiranui
+	SC_SHADOW_CLOCK,
+	SC_SHINKIROU_CALL,
+	SC_NIGHTMARE,
+	SC_SBUNSHIN,
+
 	SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
 };