Przeglądaj źródła

Initial implementation of Soul Ascetic (#8162)

Taken from #7024

Co-authored-by: munkrej <schmunk@posteo.de>
Co-authored-by: Atemo <Atemo@users.noreply.github.com>
Lemongrass3110 4 miesięcy temu
rodzic
commit
14fa654679

+ 719 - 0
db/re/skill_db.yml

@@ -41913,6 +41913,725 @@ Body:
       Flag:
         NoOverlap: true
         PathCheck: true
+  - Id: 5416
+    Name: SOA_TALISMAN_MASTERY
+    Description: Talisman Mastery
+    MaxLevel: 10
+  - Id: 5417
+    Name: SOA_SOUL_MASTERY
+    Description: Soul Mastery
+    MaxLevel: 10
+  - Id: 5418
+    Name: SOA_TALISMAN_OF_PROTECTION
+    Description: Talisman Of Protection
+    MaxLevel: 5
+    TargetType: Support
+    DamageFlags:
+      NoDamage: true
+    Flags:
+      PartyOnly: true
+    Range: 9
+    Hit: Single
+    HitCount: 1
+    CastCancel: true
+    CastTime: 1500
+    AfterCastActDelay: 500
+    Duration1:
+      - Level: 1
+        Time: 180000
+      - Level: 2
+        Time: 210000
+      - Level: 3
+        Time: 240000
+      - Level: 4
+        Time: 270000
+      - Level: 5
+        Time: 300000
+    Duration2:
+      - Level: 1
+        Time: 180000
+      - Level: 2
+        Time: 210000
+      - Level: 3
+        Time: 240000
+      - Level: 4
+        Time: 270000
+      - Level: 5
+        Time: 300000
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 50
+        - Level: 2
+          Amount: 55
+        - Level: 3
+          Amount: 60
+        - Level: 4
+          Amount: 65
+        - Level: 5
+          Amount: 70
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 1
+    Status: Talisman_of_Protection
+  - Id: 5419
+    Name: SOA_TALISMAN_OF_WARRIOR
+    Description: Talisman Of Warrior
+    MaxLevel: 5
+    TargetType: Support
+    DamageFlags:
+      NoDamage: true
+    Flags:
+      PartyOnly: true
+    Range: 9
+    Hit: Single
+    HitCount: 1
+    GiveAp: 2
+    CastCancel: true
+    CastTime: 1500
+    AfterCastActDelay: 500
+    Duration1:
+      - Level: 1
+        Time: 180000
+      - Level: 2
+        Time: 210000
+      - Level: 3
+        Time: 240000
+      - Level: 4
+        Time: 270000
+      - Level: 5
+        Time: 300000
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 50
+        - Level: 2
+          Amount: 55
+        - Level: 3
+          Amount: 60
+        - Level: 4
+          Amount: 65
+        - Level: 5
+          Amount: 70
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 1
+    Status: Talisman_of_Warrior
+  - Id: 5420
+    Name: SOA_TALISMAN_OF_MAGICIAN
+    Description: Talisman Of Magician
+    MaxLevel: 5
+    TargetType: Support
+    DamageFlags:
+      NoDamage: true
+    Flags:
+      PartyOnly: true
+    Range: 9
+    Hit: Single
+    HitCount: 1
+    GiveAp: 2
+    CastCancel: true
+    CastTime: 1500
+    AfterCastActDelay: 500
+    Duration1:
+      - Level: 1
+        Time: 180000
+      - Level: 2
+        Time: 210000
+      - Level: 3
+        Time: 240000
+      - Level: 4
+        Time: 270000
+      - Level: 5
+        Time: 300000
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 50
+        - Level: 2
+          Amount: 55
+        - Level: 3
+          Amount: 60
+        - Level: 4
+          Amount: 65
+        - Level: 5
+          Amount: 70
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 1
+    Status: Talisman_of_Magician
+  - Id: 5421
+    Name: SOA_SOUL_GATHERING
+    Description: Soul Gathering
+    MaxLevel: 5
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+    Hit: Single
+    HitCount: 1
+    CastCancel: true
+    FixedCastTime: 1000
+    CastTime: 1500
+    Cooldown:
+      - Level: 1
+        Time: 5000
+      - Level: 2
+        Time: 4000
+      - Level: 3
+        Time: 3000
+      - Level: 4
+        Time: 2000
+      - Level: 5
+        Time: 1000
+    Requires:
+      SpCost: 
+        - Level: 1
+          Amount: 70
+        - Level: 2
+          Amount: 75
+        - Level: 3
+          Amount: 80
+        - Level: 4
+          Amount: 85
+        - Level: 5
+          Amount: 90
+  - Id: 5422
+    Name: SOA_TOTEM_OF_TUTELARY
+    Description: Totem Of Tutelary
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Ground
+    DamageFlags:
+      NoDamage: true
+    Range: 11
+    Hit: Single
+    HitCount: 1
+    SplashArea: 2
+    ActiveInstance: 1
+    CastCancel: true
+    CastTime: 3500
+    Duration1:
+      - Level: 1
+        Time: 18000
+      - Level: 2
+        Time: 21000
+      - Level: 3
+        Time: 24000
+      - Level: 4
+        Time: 27000
+      - Level: 5
+        Time: 30000
+    Cooldown: 15000
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 76
+        - Level: 2
+          Amount: 92
+        - Level: 3
+          Amount: 108
+        - Level: 4
+          Amount: 124
+        - Level: 5
+          Amount: 140
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 10
+    Unit:
+      Id: Totem_Of_Tutelary
+      Range:
+        - Level: 1
+          Size: 2
+        - Level: 2
+          Size: 2
+        - Level: 3
+          Size: 3
+        - Level: 4
+          Size: 3
+        - Level: 5
+          Size: 4
+      Interval: 2000
+      Flag:
+        NoOverlap: true
+        PathCheck: true
+    Status: Totem_of_Tutelary
+  - Id: 5423
+    Name: SOA_TALISMAN_OF_FIVE_ELEMENTS
+    Description: Talisman Of Five Elements
+    MaxLevel: 5
+    TargetType: Support
+    DamageFlags:
+      NoDamage: true
+    Flags:
+      PartyOnly: true
+    Range: 9
+    Hit: Single
+    HitCount: 1
+    CastCancel: true
+    CastTime: 1500
+    AfterCastActDelay: 500
+    Duration1:
+      - Level: 1
+        Time: 180000
+      - Level: 2
+        Time: 210000
+      - Level: 3
+        Time: 240000
+      - Level: 4
+        Time: 270000
+      - Level: 5
+        Time: 300000
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 50
+        - Level: 2
+          Amount: 55
+        - Level: 3
+          Amount: 60
+        - Level: 4
+          Amount: 65
+        - Level: 5
+          Amount: 70
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 5
+    Status: Talisman_of_five_Elements
+  - Id: 5424
+    Name: SOA_TALISMAN_OF_SOUL_STEALING
+    Description: Talisman Of Soul Stealing
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Attack
+    Range: 9
+    Hit: Single
+    HitCount: 1
+    Element: Endowed
+    CastCancel: true
+    CastTime: 2200
+    Cooldown: 1000
+    FixedCastTime: 1500
+    Requires:
+      SpCost: 84
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 1
+  - Id: 5425
+    Name: SOA_EXORCISM_OF_MALICIOUS_SOUL
+    Description: Exorcism Of Malicious Soul
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      Splash: true
+    Hit: Multi_Hit
+    GiveAp: 2
+    HitCount: -5
+    Element: Endowed
+    SplashArea:
+      - Level: 1
+        Area: 5
+      - Level: 2
+        Area: 5
+      - Level: 3
+        Area: 5
+      - Level: 4
+        Area: 6
+      - Level: 5
+        Area: 6
+    CastCancel: true
+    CastTime: 2200
+    AfterCastActDelay: 500
+    FixedCastTime: 1500
+    Cooldown: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 70
+        - Level: 2
+          Amount: 80
+        - Level: 3
+          Amount: 90
+        - Level: 4
+          Amount: 100
+        - Level: 5
+          Amount: 110
+      SpiritSphereCost: 1
+  - Id: 5426
+    Name: SOA_TALISMAN_OF_BLUE_DRAGON
+    Description: Talisman Of Blue Dragon
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Attack
+    Range: 11
+    Hit: Single
+    HitCount: 1
+    Element: Endowed
+    GiveAp: 2
+    CastCancel: true
+    CastTime: 1000
+    FixedCastTime: 1500
+    Cooldown: 300
+    Duration1:
+      - Level: 1
+        Time: 30000
+      - Level: 2
+        Time: 60000
+      - Level: 3
+        Time: 90000
+      - Level: 4
+        Time: 120000
+      - Level: 5
+        Time: 150000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 54
+        - Level: 2
+          Amount: 58
+        - Level: 3
+          Amount: 62
+        - Level: 4
+          Amount: 66
+        - Level: 5
+          Amount: 70
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 1
+    Status: T_First_God
+  - Id: 5427
+    Name: SOA_TALISMAN_OF_WHITE_TIGER
+    Description: Talisman Of White Tiger
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      Splash: true
+    Hit: Multi_Hit
+    HitCount: -2
+    Element: Endowed
+    GiveAp: 2
+    SplashArea:
+      - Level: 1
+        Area: 5
+      - Level: 2
+        Area: 5
+      - Level: 3
+        Area: 6
+      - Level: 4
+        Area: 6
+      - Level: 5
+        Area: 7
+    CastCancel: true
+    CastTime: 1000
+    FixedCastTime: 1500
+    Cooldown: 400
+    Duration1:
+      - Level: 1
+        Time: 30000
+      - Level: 2
+        Time: 60000
+      - Level: 3
+        Time: 90000
+      - Level: 4
+        Time: 120000
+      - Level: 5
+        Time: 150000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 110
+        - Level: 2
+          Amount: 112
+        - Level: 3
+          Amount: 114
+        - Level: 4
+          Amount: 116
+        - Level: 5
+          Amount: 118
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 1
+    Status: T_Second_God
+  - Id: 5428
+    Name: SOA_TALISMAN_OF_RED_PHOENIX
+    Description: Talisman Of Red Phoenix
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Attack
+    DamageFlags:
+      Splash: true
+    Range: 9
+    Hit: Multi_Hit
+    HitCount: -3
+    Element: Endowed
+    GiveAp: 3
+    SplashArea:
+      - Level: 1
+        Area: 1
+      - Level: 2
+        Area: 1
+      - Level: 3
+        Area: 2
+      - Level: 4
+        Area: 2
+      - Level: 5
+        Area: 3
+    Duration1:
+      - Level: 1
+        Time: 30000
+      - Level: 2
+        Time: 60000
+      - Level: 3
+        Time: 90000
+      - Level: 4
+        Time: 120000
+      - Level: 5
+        Time: 150000
+    CastCancel: true
+    CastTime: 1000
+    FixedCastTime: 1500
+    Cooldown: 450
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 72
+        - Level: 2
+          Amount: 76
+        - Level: 3
+          Amount: 80
+        - Level: 4
+          Amount: 84
+        - Level: 5
+          Amount: 88
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 1
+    Status: T_Third_God
+  - Id: 5429
+    Name: SOA_TALISMAN_OF_BLACK_TORTOISE
+    Description: Talisman Of Black Tortoise
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Ground
+    DamageFlags:
+      Splash: true
+    Range: 9
+    Hit: Multi_Hit
+    HitCount: -3
+    Element: Endowed
+    GiveAp: 3
+    Duration1: 100
+    Duration2:
+      - Level: 1
+        Time: 30000
+      - Level: 2
+        Time: 60000
+      - Level: 3
+        Time: 90000
+      - Level: 4
+        Time: 120000
+      - Level: 5
+        Time: 150000
+    CastCancel: true
+    CastTime: 1000
+    FixedCastTime: 1500
+    Cooldown: 700
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 72
+        - Level: 2
+          Amount: 77
+        - Level: 3
+          Amount: 82
+        - Level: 4
+          Amount: 87
+        - Level: 5
+          Amount: 92
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 1
+    Unit:
+      Id: Dummyskill
+      Range:
+        - Level: 1
+          Size: 3
+        - Level: 2
+          Size: 3
+        - Level: 3
+          Size: 4
+        - Level: 4
+          Size: 4
+        - Level: 5
+          Size: 5
+      Interval: 1000
+      Target: Enemy
+      Flag:
+        PathCheck: true
+    Status: T_Fourth_God
+  - Id: 5430
+    Name: SOA_TALISMAN_OF_FOUR_BEARING_GOD
+    Description: Talisman Of Four Bearing God
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Attack
+    DamageFlags:
+      Splash: true
+    Range: 9
+    Hit: Single
+    HitCount: 1
+    Element: Endowed
+    GiveAp: 3
+    SplashArea:
+      - Level: 1
+        Area: 3
+      - Level: 2
+        Area: 3
+      - Level: 3
+        Area: 4
+      - Level: 4
+        Area: 4
+      - Level: 5
+        Area: 5
+    CastCancel: true
+    CastTime: 1500
+    FixedCastTime: 1500
+    Cooldown: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 86
+        - Level: 2
+          Amount: 88
+        - Level: 3
+          Amount: 90
+        - Level: 4
+          Amount: 92
+        - Level: 5
+          Amount: 94
+      ItemCost:
+        - Item: Soa_Charm
+          Amount: 3
+  - Id: 5431
+    Name: SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS
+    Description: Circle Of Directions And Elementals
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Attack
+    DamageFlags:
+      Splash: true
+    Range: 9
+    Hit: Multi_Hit
+    HitCount: 5
+    Element: Endowed
+    SplashArea:
+      - Level: 1
+        Area: 3
+      - Level: 2
+        Area: 3
+      - Level: 3
+        Area: 4
+      - Level: 4
+        Area: 4
+      - Level: 5
+        Area: 5
+    Duration1:
+      - Level: 1
+        Time: 30000
+      - Level: 2
+        Time: 60000
+      - Level: 3
+        Time: 90000
+      - Level: 4
+        Time: 120000
+      - Level: 5
+        Time: 150000
+    CastCancel: true
+    Cooldown: 5000
+    AfterCastActDelay: 500
+    CastTime: 1500
+    FixedCastTime: 1500
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 120
+        - Level: 2
+          Amount: 140
+        - Level: 3
+          Amount: 160
+        - Level: 4
+          Amount: 180
+        - Level: 5
+          Amount: 200
+      ApCost: 35
+    Status: T_Fifth_God
+  - Id: 5432
+    Name: SOA_SOUL_OF_HEAVEN_AND_EARTH
+    Description: Soul Of Heaven And Earth
+    MaxLevel: 10
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+      Splash: true
+    Range: 11
+    Hit: Single
+    HitCount: 1
+    SplashArea: 11
+    CastCancel: true
+    AfterCastActDelay: 1000
+    Duration1: 300000
+    Cooldown:
+      - Level: 2
+        Time: 30000
+      - Level: 3
+        Time: 60000
+      - Level: 4
+        Time: 90000
+      - Level: 5
+        Time: 120000
+      - Level: 6
+        Time: 150000
+      - Level: 7
+        Time: 180000
+      - Level: 8
+        Time: 210000
+      - Level: 9
+        Time: 270000
+      - Level: 10
+        Time: 300000
+    CastTime: 3000
+    FixedCastTime: 2000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 90
+        - Level: 2
+          Amount: 100
+        - Level: 3
+          Amount: 110
+        - Level: 4
+          Amount: 120
+        - Level: 5
+          Amount: 130
+        - Level: 6
+          Amount: 140
+        - Level: 7
+          Amount: 150
+        - Level: 8
+          Amount: 160
+        - Level: 9
+          Amount: 170
+        - Level: 10
+          Amount: 180
+      ApCost: 180
+    Status: Heaven_and_Earth
   - Id: 5449
     Name: HN_SELFSTUDY_TATICS
     Description: Self Study Tactics

+ 110 - 0
db/re/skill_tree.yml

@@ -7908,6 +7908,116 @@ Body:
       Royal_Guard: true
       Royal_Guard_T: true
       Imperial_Guard: true
+  - Job: Soul_Ascetic
+    Inherit:
+      Novice: true
+      Taekwon: true
+      Soul_Linker: true
+      Soul_Reaper: true
+    Tree:
+      - Name: SOA_SOUL_MASTERY
+        MaxLevel: 10
+      - Name: SOA_TALISMAN_MASTERY
+        MaxLevel: 10
+      - Name: SOA_SOUL_GATHERING
+        MaxLevel: 5
+        Requires:
+          - Name: SP_SOULENERGY
+            Level: 5
+          - Name: SOA_SOUL_MASTERY
+            Level: 3
+      - Name: SOA_TALISMAN_OF_PROTECTION
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_MASTERY
+            Level: 1
+      - Name: SOA_TALISMAN_OF_WARRIOR
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_MASTERY
+            Level: 1
+      - Name: SOA_TALISMAN_OF_MAGICIAN
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_MASTERY
+            Level: 1
+      - Name: SOA_EXORCISM_OF_MALICIOUS_SOUL
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_SOUL_GATHERING
+            Level: 1
+          - Name: SP_SOULCURSE
+            Level: 5
+      - Name: SOA_TALISMAN_OF_SOUL_STEALING
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_MASTERY
+            Level: 1
+          - Name: SOA_SOUL_MASTERY
+            Level: 1
+      - Name: SOA_TOTEM_OF_TUTELARY
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_MASTERY
+            Level: 3
+          - Name: SOA_SOUL_MASTERY
+            Level: 3
+      - Name: SOA_TALISMAN_OF_FIVE_ELEMENTS
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_MASTERY
+            Level: 1
+      - Name: SOA_TALISMAN_OF_BLUE_DRAGON
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_OF_SOUL_STEALING
+            Level: 1
+      - Name: SOA_TALISMAN_OF_WHITE_TIGER
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_OF_BLUE_DRAGON
+            Level: 1
+      - Name: SOA_TALISMAN_OF_RED_PHOENIX
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_OF_WHITE_TIGER
+            Level: 1
+      - Name: SOA_TALISMAN_OF_BLACK_TORTOISE
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_OF_RED_PHOENIX
+            Level: 1
+      - Name: SOA_TALISMAN_OF_FOUR_BEARING_GOD
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_TALISMAN_OF_BLUE_DRAGON
+            Level: 1
+          - Name: SOA_TALISMAN_OF_WHITE_TIGER
+            Level: 1
+          - Name: SOA_TALISMAN_OF_RED_PHOENIX
+            Level: 1
+          - Name: SOA_TALISMAN_OF_BLACK_TORTOISE
+            Level: 1
+      - Name: SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS
+        MaxLevel: 5
+        Requires:
+          - Name: SOA_SOUL_MASTERY
+            Level: 3
+          - Name: SOA_TALISMAN_OF_FIVE_ELEMENTS
+            Level: 1
+          - Name: SOA_TALISMAN_OF_FOUR_BEARING_GOD
+            Level: 1
+      - Name: SOA_SOUL_OF_HEAVEN_AND_EARTH
+        MaxLevel: 10
+        Requires:
+          - Name: SOA_TALISMAN_OF_PROTECTION
+            Level: 5
+          - Name: SOA_TALISMAN_OF_WARRIOR
+            Level: 5
+          - Name: SOA_TALISMAN_OF_MAGICIAN
+            Level: 5
+          - Name: SOA_TALISMAN_OF_FIVE_ELEMENTS
+            Level: 5
   - Job: Night_Watch
     Inherit:
       Novice: true

+ 83 - 0
db/re/status.yml

@@ -9429,3 +9429,86 @@ Body:
       bonus bVariableCastrate, -.@val1;
       bonus bMaxHPrate, .@val1;
       bonus bMaxSPrate, .@val1;
+  - Status: Talisman_of_Protection
+    Icon: EFST_TALISMAN_OF_PROTECTION
+    DurationLookup: SOA_TALISMAN_OF_PROTECTION
+    Flags:
+      BlEffect: true
+      DisplayPc: true
+  - Status: Talisman_of_Warrior
+    Icon: EFST_TALISMAN_OF_WARRIOR
+    DurationLookup: SOA_TALISMAN_OF_WARRIOR
+    CalcFlags:
+      Patk: true
+    Flags:
+      BlEffect: true
+      DisplayPc: true
+      RequireWeapon: true
+  - Status: Talisman_of_Magician
+    Icon: EFST_TALISMAN_OF_MAGICIAN
+    DurationLookup: SOA_TALISMAN_OF_MAGICIAN
+    CalcFlags:
+      Smatk: true
+    Flags:
+      BlEffect: true
+      DisplayPc: true
+      RequireWeapon: true
+  - Status: Talisman_of_five_Elements
+    Icon: EFST_TALISMAN_OF_FIVE_ELEMENTS
+    DurationLookup: SOA_TALISMAN_OF_FIVE_ELEMENTS
+    CalcFlags:
+      All: true
+    Flags:
+      BlEffect: true
+      DisplayPc: true
+      RequireWeapon: true
+  - Status: Totem_of_Tutelary
+    Icon: EFST_BLANK
+    DurationLookup: SOA_TOTEM_OF_TUTELARY
+    CalcFlags:
+      Regen: true
+  - Status: T_First_God
+    Icon: EFST_T_FIRST_GOD
+    DurationLookup: SOA_TALISMAN_OF_BLUE_DRAGON
+    Fail:
+      T_Second_God: true
+      T_Third_God: true
+      T_Fourth_God: true
+      T_Fifth_God: true
+  - Status: T_Second_God
+    Icon: EFST_T_SECOND_GOD
+    DurationLookup: SOA_TALISMAN_OF_WHITE_TIGER
+    Fail:
+      T_Second_God: true
+    EndOnStart:
+      T_First_God: true
+  - Status: T_Third_God
+    Icon: EFST_T_THIRD_GOD
+    DurationLookup: SOA_TALISMAN_OF_RED_PHOENIX
+    Fail:
+      T_Third_God: true
+    EndOnStart:
+      T_Second_God: true
+  - Status: T_Fourth_God
+    Icon: EFST_T_FOURTH_GOD
+    DurationLookup: SOA_TALISMAN_OF_BLACK_TORTOISE
+    Fail:
+      T_Fourth_God: true
+    EndOnStart:
+      T_Third_God: true
+  - Status: T_Fifth_God
+    Icon: EFST_T_FIVETH_GOD
+    DurationLookup: SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS
+    CalcFlags:
+      Smatk: true
+    Flags:
+      NoBanishingBuster: true
+      NoClearance: true
+      NoDispell: true
+    EndOnStart:
+      T_Fourth_God: true
+  - Status: Heaven_and_Earth
+    Icon: EFST_HEAVEN_AND_EARTH
+    DurationLookup: SOA_SOUL_OF_HEAVEN_AND_EARTH
+    CalcFlags:
+      All: true

+ 78 - 0
src/map/battle.cpp

@@ -7832,6 +7832,20 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 				ad.div_ = 2;
 			}
 			break;
+		case SOA_TALISMAN_OF_FOUR_BEARING_GOD:
+			if (sc != nullptr){
+				if (sc->getSCE(SC_T_FIRST_GOD) != nullptr)
+					ad.div_ = 2;
+				else if (sc->getSCE(SC_T_SECOND_GOD) != nullptr)
+					ad.div_ = 3;
+				else if (sc->getSCE(SC_T_THIRD_GOD) != nullptr)
+					ad.div_ = 4;
+				else if (sc->getSCE(SC_T_FOURTH_GOD) != nullptr)
+					ad.div_ = 5;
+				else if (sc->getSCE(SC_T_FIFTH_GOD) != nullptr)
+					ad.div_ = 7;
+			}
+			break;
 	}
 
 	//Set miscellaneous data that needs be filled
@@ -8788,6 +8802,70 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						if (sc && sc->getSCE(SC_RULEBREAK))
 							skillratio += skillratio * 50 / 100;
 						break;
+					case SOA_EXORCISM_OF_MALICIOUS_SOUL:
+						skillratio += -100 + 150 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_SOUL_MASTERY) * 2;
+						skillratio += 1 * sstatus->spl;
+
+						if ((tsc != nullptr && tsc->getSCE(SC_SOULCURSE) != nullptr) || (sc != nullptr && sc->getSCE(SC_TOTEM_OF_TUTELARY) != nullptr))
+							skillratio += 100 * skill_lv;
+
+						if (sd != nullptr)
+							skillratio *= sd->soulball_old;
+						RE_LVL_DMOD(100);
+						break;
+					case SOA_TALISMAN_OF_BLUE_DRAGON:
+						skillratio += -100 + 850 + 2250 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_TALISMAN_MASTERY) * 15 * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						if (sc != nullptr && sc->getSCE(SC_T_FIFTH_GOD) != nullptr)
+							skillratio += 100 + 700 * skill_lv;
+						RE_LVL_DMOD(100);
+						break;
+					case SOA_TALISMAN_OF_WHITE_TIGER:
+						skillratio += -100 + 400 + 1000 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_TALISMAN_MASTERY) * 15 * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						if (sc != nullptr && sc->getSCE(SC_T_FIFTH_GOD) != nullptr)
+							skillratio += 400 * skill_lv;
+						RE_LVL_DMOD(100);
+						break;
+					case SOA_TALISMAN_OF_RED_PHOENIX:
+						skillratio += -100 + 1400 + 1450 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_TALISMAN_MASTERY) * 15 * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						if (sc != nullptr && sc->getSCE(SC_T_FIFTH_GOD) != nullptr)
+							skillratio += 200 + 400 * skill_lv;
+						RE_LVL_DMOD(100);
+						break;
+					case SOA_TALISMAN_OF_BLACK_TORTOISE:
+						skillratio += -100 + 2150 + 1600 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_TALISMAN_MASTERY) * 15 * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						if (sc != nullptr && sc->getSCE(SC_T_FIFTH_GOD) != nullptr)
+							skillratio += 150 + 500 * skill_lv;
+						RE_LVL_DMOD(100);
+						break;
+					case SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS:
+						skillratio += -100 + 500 + 2000 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_TALISMAN_MASTERY) * 15 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_SOUL_MASTERY) * 15 * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						break;
+					case SOA_TALISMAN_OF_FOUR_BEARING_GOD:
+						skillratio += -100 + 50 + 250 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_TALISMAN_MASTERY) * 15 * skill_lv;
+						skillratio += 5 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						break;
+					case SOA_TALISMAN_OF_SOUL_STEALING:
+						skillratio += -100 + 500 + 1250 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_TALISMAN_MASTERY) * 7 * skill_lv;
+						skillratio += pc_checkskill(sd, SOA_SOUL_MASTERY) * 7 * skill_lv;
+						skillratio += 3 * sstatus->spl;
+						RE_LVL_DMOD(100);
+						break;
 				}
 
 				if (sc) {// Insignia's increases the damage of offensive magic by a fixed percentage depending on the element.

+ 26 - 2
src/map/clif.hpp

@@ -488,8 +488,32 @@ enum useskill_fail_cause : uint8_t
 	USESKILL_FAIL_THERE_ARE_NPC_AROUND = 83,
 	USESKILL_FAIL_NEED_MORE_BULLET = 84,
 	USESKILL_FAIL_COINS = 85,
-	// 86-99 unknown
-	USESKILL_FAIL_AP_INSUFFICIENT = 100,
+	// 86 unknown
+	USESKILL_FAIL_MAP = 87,
+	USESKILL_FAIL_NEED_SUMMON_SP,
+	USESKILL_FAIL_SAME_VEND,
+	USESKILL_FAIL_NEED_BULLETS,
+	USESKILL_FAIL_NEED_ARROWS,
+	USESKILL_FAIL_NEED_PARTY,
+	USESKILL_FAIL_NEED_PARTY_LEADER,
+	USESKILL_FAIL_NEED_PARTNER_SP,
+	USESKILL_FAIL_NEED_WEAPON,
+	USESKILL_FAIL_NEED_ENERGY_SPHERE,
+	USESKILL_FAIL_NEED_WEAPON_BLOCKING,
+	USESKILL_FAIL_MAX_TRAPS,
+	USESKILL_FAIL_NEED_MAGIC_SPELLBOOK,
+	USESKILL_FAIL_AP_INSUFFICIENT,
+	USESKILL_FAIL_NEED_SERVANT_WEAPON,
+	USESKILL_FAIL_NEED_TWINKLING_GALAXY,
+	USESKILL_FAIL_NEED_SOUL_ENGERY,
+	USESKILL_FAIL_NEED_AMULET,
+	USESKILL_FAIL_NEED_GATLING_SHOTGUT,
+	USESKILL_FAIL_NEED_RIFLE_REVOLVER,
+	USESKILL_FAIL_NEED_GLAUNCHER_RIFLE,
+	USESKILL_FAIL_NEED_GATLING_REVOLVER,
+	USESKILL_FAIL_NEED_SHOTGUN_GLAUNCHER,
+	USESKILL_FAIL_NEED_SHIELD,
+	USESKILL_FAIL_TARGET_SHADOW_SPACE,
 	USESKILL_FAIL_MAX
 };
 

+ 11 - 0
src/map/script_constants.hpp

@@ -1921,6 +1921,17 @@
 	export_constant(SC_CONTENTS_31);
 	export_constant(SC_CONTENTS_32);
 	export_constant(SC_CONTENTS_33);
+	export_constant(SC_TALISMAN_OF_PROTECTION);
+	export_constant(SC_TALISMAN_OF_WARRIOR);
+	export_constant(SC_TALISMAN_OF_MAGICIAN);
+	export_constant(SC_TALISMAN_OF_FIVE_ELEMENTS);
+	export_constant(SC_TOTEM_OF_TUTELARY);
+	export_constant(SC_T_FIRST_GOD);
+	export_constant(SC_T_SECOND_GOD);
+	export_constant(SC_T_THIRD_GOD);
+	export_constant(SC_T_FOURTH_GOD);
+	export_constant(SC_T_FIFTH_GOD);
+	export_constant(SC_HEAVEN_AND_EARTH);
 
 /// Do not modify code below this, until the end of the API hook, since it will be automatically generated again
 /// @APIHOOK_START(EFST_CONST)

+ 166 - 6
src/map/skill.cpp

@@ -570,6 +570,12 @@ int32 skill_calc_heal(struct block_list *src, struct block_list *target, uint16
 				hp_bonus += skill * 2;
 #endif
 			break;
+
+		case SOA_TALISMAN_OF_PROTECTION:
+			hp = (500 + pc_checkskill(sd,SOA_TALISMAN_MASTERY) * 50) * skill_lv * status_get_lv(src) / 100;
+			hp += (status_get_lv(src) + status_get_int(src)) / 5 * 30 * status_get_crt(src) / 100;
+			break;
+
 		default:
 			if (skill_lv >= battle_config.max_heal_lv)
 				return battle_config.max_heal;
@@ -686,7 +692,7 @@ int32 skill_calc_heal(struct block_list *src, struct block_list *target, uint16
 	}
 
 #ifdef RENEWAL
-	if (hp_bonus)
+	if (hp_bonus && skill_id != SOA_TALISMAN_OF_PROTECTION)
 		hp += hp * hp_bonus / 100;
 
 	// MATK part of the RE heal formula [malufett]
@@ -764,7 +770,7 @@ int32 skill_calc_heal(struct block_list *src, struct block_list *target, uint16
 
 	// Final heal increased by HPlus.
 	// Is this the right place for this??? [Rytech]
-	if ( sd && status_get_hplus(src) > 0 )
+	if ( sd && status_get_hplus(src) > 0 && skill_id != SOA_TALISMAN_OF_PROTECTION)
 		hp += hp * status_get_hplus(src) / 100;
 
 	return (heal) ? max(1, hp) : hp;
@@ -5726,6 +5732,11 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 	case TR_METALIC_FURY:
 	case IG_GRAND_JUDGEMENT:
 	case HN_JUPITEL_THUNDER_STORM:
+	case SOA_EXORCISM_OF_MALICIOUS_SOUL:
+	case SOA_TALISMAN_OF_WHITE_TIGER:
+	case SOA_TALISMAN_OF_RED_PHOENIX:
+	case SOA_TALISMAN_OF_FOUR_BEARING_GOD:
+	case SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS:
 		if( flag&1 ) {//Recursive invocation
 			int32 sflag = skill_area_temp[0] & 0xFFF;
 			int32 heal = 0;
@@ -5797,6 +5808,7 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 				case DK_HACKANDSLASHER:
 				case MT_SPARK_BLASTER:
 				case HN_JUPITEL_THUNDER_STORM:
+				case SOA_TALISMAN_OF_FOUR_BEARING_GOD:
 					clif_skill_nodamage(src,*bl,skill_id,skill_lv);
 					break;
 #ifdef RENEWAL
@@ -5938,6 +5950,18 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 					clif_skill_nodamage(src, *bl, skill_id, skill_lv);
 					sc_start(src, src, skill_get_sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
 					break;
+				case SOA_TALISMAN_OF_RED_PHOENIX:
+					clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+					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);
+					if (sc != nullptr && sc->getSCE(SC_T_SECOND_GOD) != nullptr){
+						sc_start(src, src, skill_get_sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
+					}
+					break;
+				case SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS:
+					clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+					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;
 			}
 
 			// if skill damage should be split among targets, count them
@@ -7134,6 +7158,22 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 			status_change_end(src, SC_INTENSIVE_AIM_COUNT);
  		break;
 
+	case SOA_TALISMAN_OF_BLUE_DRAGON:
+		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+		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, 1, skill_get_time(skill_id, skill_lv));
+		break;
+
+	case SOA_TALISMAN_OF_SOUL_STEALING:
+		skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+		if( bl->type != BL_SKILL ){
+			int32 sp = (100 + status_get_lv(src) / 50) * skill_lv;
+
+			status_heal(src, 0, sp, 0, 0);
+			clif_skill_nodamage( src, *src, skill_id, sp );
+		}
+		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,
@@ -8056,6 +8096,7 @@ int32 skill_castend_nodamage_id (struct block_list *src, struct block_list *bl,
 
 	case DK_SERVANTWEAPON:
 	case ABC_FROM_THE_ABYSS:
+	case SOA_TALISMAN_OF_PROTECTION:
 		clif_skill_nodamage(src, *bl, skill_id, skill_lv, sc_start2(src, bl, type, 100, skill_lv, src->id, skill_get_time(skill_id, skill_lv)));
 		break;
 
@@ -8619,6 +8660,8 @@ int32 skill_castend_nodamage_id (struct block_list *src, struct block_list *bl,
 	case MT_MIGHTY_SMASH:
 	case ABC_ABYSS_DAGGER:
 	case BO_EXPLOSIVE_POWDER:
+	case SOA_EXORCISM_OF_MALICIOUS_SOUL:
+	case SOA_TALISMAN_OF_WHITE_TIGER:
 	{
 		int32 starget = BL_CHAR|BL_SKILL;
 
@@ -8647,6 +8690,24 @@ int32 skill_castend_nodamage_id (struct block_list *src, struct block_list *bl,
 			hom_addspiritball(hd, MAX_SPIRITBALL);
 		}
 
+		// TODO: refactor the ifs above into the switch below
+
+		switch( skill_id ){
+			case SOA_EXORCISM_OF_MALICIOUS_SOUL:
+				if( sd != nullptr ){
+					// Remove old souls if any exist.
+					sd->soulball_old = sd->soulball;
+					pc_delsoulball( *sd, sd->soulball, 0 );
+				}
+				break;
+
+			case SOA_TALISMAN_OF_WHITE_TIGER:
+				if (sc != nullptr && sc->getSCE(SC_T_FIRST_GOD) != nullptr) {
+					sc_start(src, src, skill_get_sc(skill_id), 100, skill_lv, skill_get_time(skill_id, skill_lv));
+				}
+				break;
+		}
+
 		skill_area_temp[1] = 0;
 		clif_skill_nodamage(src,*bl,skill_id,skill_lv);
 		i = map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), starget,
@@ -8833,12 +8894,21 @@ int32 skill_castend_nodamage_id (struct block_list *src, struct block_list *bl,
 #endif
 	case PR_MAGNIFICAT:
 	case PR_GLORIA:
+	case SOA_SOUL_OF_HEAVEN_AND_EARTH:
 		if (sd == nullptr || sd->status.party_id == 0 || (flag & 1)) {
 
 			// Animations don't play when outside visible range
 			if (check_distance_bl(src, bl, AREA_SIZE))
 				clif_skill_nodamage(bl, *bl, skill_id, skill_lv);
 
+			if( skill_id == SOA_SOUL_OF_HEAVEN_AND_EARTH ){
+				status_percent_heal(bl, 0, 100);
+
+				if( src != bl && sc != nullptr && sc->getSCE(SC_TOTEM_OF_TUTELARY) != nullptr ){
+					status_heal(bl, 0, 0, 3 * skill_lv, 0);
+				}
+			}
+
 			sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
 		}
 		else if (sd)
@@ -12997,6 +13067,34 @@ int32 skill_castend_nodamage_id (struct block_list *src, struct block_list *bl,
 		clif_skill_nodamage(src, *src, skill_id, skill_lv);
 		break;
 
+	case SOA_SOUL_GATHERING:
+		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+
+		if( sd != nullptr ){
+			int32 limit = 5 + pc_checkskill(sd, SP_SOULENERGY) * 3;
+			
+			for (i = 0; i < limit; i++)
+				pc_addsoulball(*sd,limit);
+		}
+		break;
+
+	case SOA_TALISMAN_OF_WARRIOR:
+	case SOA_TALISMAN_OF_MAGICIAN:
+	case SOA_TALISMAN_OF_FIVE_ELEMENTS:
+		if( dstsd != nullptr ){
+			int16 index = dstsd->equip_index[EQI_HAND_R];
+
+			if (index >= 0 && dstsd->inventory_data[index] != nullptr && dstsd->inventory_data[index]->type == IT_WEAPON) {
+				clif_skill_nodamage(src, *bl, skill_id, skill_lv, sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv)));
+				break;
+			}
+		}
+
+		if( sd != nullptr ){
+			clif_skill_fail( *sd, skill_id, USESKILL_FAIL_NEED_WEAPON );
+		}
+		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);
@@ -13982,6 +14080,7 @@ int32 skill_castend_pos2(struct block_list* src, int32 x, int32 y, uint16 skill_
 	case EM_VENOM_SWAMP:
 	case EM_CONFLAGRATION:
 	case EM_TERRA_DRIVE:
+	case SOA_TOTEM_OF_TUTELARY:
 		flag|=1;//Set flag to 1 to prevent deleting ammo (it will be deleted on group-delete).
 		[[fallthrough]];
 	case GS_GROUNDDRIFT: //Ammo should be deleted right away.
@@ -14778,6 +14877,13 @@ int32 skill_castend_pos2(struct block_list* src, int32 x, int32 y, uint16 skill_
 		}
 		break;
 
+	case SOA_TALISMAN_OF_BLACK_TORTOISE:
+		if (sc != nullptr && sc->getSCE(SC_T_THIRD_GOD) != nullptr){
+			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,0);
+		break;
+
 	default:
 		ShowWarning("skill_castend_pos2: Unknown skill used:%d\n",skill_id);
 		return 1;
@@ -15176,6 +15282,7 @@ std::shared_ptr<s_skill_unit_group> skill_unitsetting(struct block_list *src, ui
 	case SA_DELUGE:
 	case SA_VIOLENTGALE:
 	case SC_CHAOSPANIC:
+	case SOA_TOTEM_OF_TUTELARY:
 	{
 		std::shared_ptr<s_skill_unit_group> old_sg = skill_locate_element_field(src);
 
@@ -16161,6 +16268,7 @@ int32 skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t
 					skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
 					break;
 				case HN_METEOR_STORM_BUSTER:
+				case SOA_TALISMAN_OF_BLACK_TORTOISE:
 					skill_attack( skill_get_type(sg->skill_id), ss, ss, bl, sg->skill_id, sg->skill_lv, tick, 0 );
 					break;
 				default:
@@ -16795,6 +16903,31 @@ int32 skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t
 				skill_attack(skill_get_type(sg->skill_id), ss, &unit->bl, bl, sg->skill_id, sg->skill_lv, tick, flag);
 			}
 			break;
+
+		case UNT_TOTEM_OF_TUTELARY:
+			if( bl->type == BL_PC ) {
+				if (tsc != nullptr && tsc->option&OPTION_MADOGEAR)
+					break;
+
+				int32 hp = 500;
+
+				hp += 500 * sg->skill_lv;
+				hp += 50 * pc_checkskill( BL_CAST( BL_PC, ss ), SOA_TALISMAN_MASTERY ) * sg->skill_lv;
+				hp += 5 * status_get_crt( ss ) * sg->skill_lv;
+				hp *= status_get_lv( ss ) / 100;
+
+				int32 sp = 0;
+
+				sp += 50 * sg->skill_lv;
+				sp += 5 * pc_checkskill( BL_CAST( BL_PC, ss ), SOA_TALISMAN_MASTERY ) * sg->skill_lv;
+				sp += 5 * status_get_crt( ss ) * sg->skill_lv;
+				sp *= status_get_lv( ss ) / 100;
+
+				status_heal( bl, hp, sp, 0, 2 );
+
+				sc_start( ss, bl, skill_get_sc( sg->skill_id ), 100, sg->skill_lv, sg->interval + 100 );
+			} 
+			break;
 	}
 
 	if (bl->type == BL_MOB && ss != bl)
@@ -16834,6 +16967,7 @@ int32 skill_unit_onout(struct skill_unit *src, struct block_list *bl, t_tick tic
 		case UNT_SAFETYWALL:
 		case UNT_PNEUMA:
 		case UNT_EPICLESIS://Arch Bishop
+		case UNT_TOTEM_OF_TUTELARY:
 			if (sce)
 				status_change_end(bl, type);
 			break;
@@ -18178,6 +18312,19 @@ bool skill_check_condition_castbegin( map_session_data& sd, uint16 skill_id, uin
 			if (!(sc && sc->getSCE(SC_THIRD_EXOR_FLAME)))
 				return false;
 			break;
+
+		case SOA_SOUL_GATHERING:
+			if (!(sc != nullptr && sc->getSCE(SC_SOULCOLLECT) != nullptr)){
+				clif_skill_fail(sd,skill_id,USESKILL_FAIL_CONDITION,0);
+				return false;
+			}
+			break;
+		case SOA_CIRCLE_OF_DIRECTIONS_AND_ELEMENTALS:
+			if (!(sc != nullptr && (sc->getSCE(SC_T_FOURTH_GOD) != nullptr || sc->getSCE(SC_T_FIFTH_GOD) != nullptr))) {
+				clif_skill_fail(sd,skill_id,USESKILL_FAIL_CONDITION,0);
+				return false;
+			}
+			break;
 	}
 
 	/* check state required */
@@ -18431,6 +18578,7 @@ bool skill_check_condition_castbegin( map_session_data& sd, uint16 skill_id, uin
 			case SP_SOULREAPER:
 			case SP_SOULEXPLOSION:
 			case SP_KAUTE:
+			case SOA_EXORCISM_OF_MALICIOUS_SOUL:
 				if (sd.soulball < require.spiritball) {
 					clif_skill_fail( sd, skill_id, USESKILL_FAIL_SPIRITS );
 					return false;
@@ -20120,6 +20268,7 @@ int32 skill_clear_group(block_list *bl, uint8 flag)
 			case SC_CHAOSPANIC:
 			case MH_POISON_MIST:
 			case MH_LAVA_SLIDE:
+			case SOA_TOTEM_OF_TUTELARY:
 				if (flag & 1) {
 					skill_delunitgroup(*it);
 					count++;
@@ -20181,6 +20330,7 @@ std::shared_ptr<s_skill_unit_group> skill_locate_element_field(struct block_list
 			case SC_CHAOSPANIC:
 			case MH_POISON_MIST:
 			case MH_LAVA_SLIDE:
+			case SOA_TOTEM_OF_TUTELARY:
 				return su;
 		}
 	}
@@ -23922,18 +24072,28 @@ uint64 SkillDatabase::parseBodyNode(const ryml::NodeRef& node) {
 		if (!this->asString(node, "Name", name))
 			return 0;
 
+		if( name.length() > SKILL_NAME_LENGTH ){
+			this->invalidWarning( node["Name"], "Name \"%s\" exceeds maximum length of %d.\n", name.c_str(), SKILL_NAME_LENGTH );
+			return 0;
+		}
+
 		name.resize(SKILL_NAME_LENGTH);
 		memcpy(skill->name, name.c_str(), sizeof(skill->name));
 	}
 
 	if (this->nodeExists(node, "Description")) {
-		std::string name;
+		std::string desc;
+
+		if (!this->asString(node, "Description", desc))
+			return 0;
 
-		if (!this->asString(node, "Description", name))
+		if( desc.length() > SKILL_DESC_LENGTH ){
+			this->invalidWarning( node["Description"], "Description \"%s\" exceeds maximum length of %d.\n", desc.c_str(), SKILL_DESC_LENGTH );
 			return 0;
+		}
 
-		name.resize(SKILL_DESC_LENGTH);
-		memcpy(skill->desc, name.c_str(), sizeof(skill->desc));
+		desc.resize(SKILL_DESC_LENGTH);
+		memcpy(skill->desc, desc.c_str(), sizeof(skill->desc));
 	}
 
 	if (this->nodeExists(node, "MaxLevel")) {

+ 2 - 2
src/map/skill.hpp

@@ -33,8 +33,8 @@ class status_change;
 #define MAX_SKILL_LEVEL 13 /// Max Skill Level (for skill_db storage)
 #define MAX_MOBSKILL_LEVEL 100	/// Max monster skill level (on skill usage)
 #define MAX_SKILL_CRIMSON_MARKER 3 /// Max Crimson Marker targets (RL_C_MARKER)
-#define SKILL_NAME_LENGTH 31 /// Max Skill Name length
-#define SKILL_DESC_LENGTH 31 /// Max Skill Desc length
+#define SKILL_NAME_LENGTH 40 /// Max Skill Name length
+#define SKILL_DESC_LENGTH 40 /// Max Skill Desc length
 
 /// Used with tracking the hitcount of Earthquake for skills that can avoid the first attack
 #define NPC_EARTHQUAKE_FLAG 0x800

+ 71 - 0
src/map/status.cpp

@@ -4207,6 +4207,10 @@ int32 status_calc_pc_sub(map_session_data* sd, uint8 opt)
 	if ((skill = pc_checkskill(sd, NW_GRENADE_MASTERY)) > 0)
 		base_status->con += skill;
 
+// ----- SPELL CALCULATION -----
+	if ((skill = pc_checkskill(sd, SOA_SOUL_MASTERY)) > 0)
+		base_status->spl += skill;
+
 // ------ ATTACK CALCULATION ------
 
 	// Base batk value is set in status_calc_misc
@@ -4423,6 +4427,8 @@ int32 status_calc_pc_sub(map_session_data* sd, uint8 opt)
 		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;
+	if ((skill = pc_checkskill(sd, SOA_TALISMAN_MASTERY)) > 0)
+		base_status->smatk += skill;
 
 	// 2-Handed Staff Mastery
 	if( sd->status.weapon == W_2HSTAFF && ( skill = pc_checkskill( sd, AG_TWOHANDSTAFF ) ) > 0 ){
@@ -4803,6 +4809,24 @@ int32 status_calc_pc_sub(map_session_data* sd, uint8 opt)
 			pc_bonus(sd, SP_MATK_RATE, sc->getSCE(SC_CATNIPPOWDER)->val2);
 		if (sc->getSCE(SC_NIBELUNGEN) && sc->getSCE(SC_NIBELUNGEN)->val2 == RINGNBL_MATKRATE)
 			pc_bonus(sd, SP_MATK_RATE, 20);
+		if( sc->getSCE(SC_TALISMAN_OF_FIVE_ELEMENTS) != nullptr ) {
+			const std::vector<e_element> elements = { ELE_FIRE, ELE_WATER, ELE_WIND, ELE_EARTH, ELE_NEUTRAL };
+			int32 bonus = sc->getSCE(SC_TALISMAN_OF_FIVE_ELEMENTS)->val2;
+
+			for( const auto &element : elements ){
+				sd->indexed_bonus.magic_addele[element] += bonus;
+				sd->right_weapon.addele[element] += bonus;
+				if( !battle_config.left_cardfix_to_right ){
+					sd->left_weapon.addele[element] += bonus;
+				}
+			}
+		}
+		if( sc->getSCE(SC_HEAVEN_AND_EARTH) != nullptr ) {
+			i = sc->getSCE(SC_HEAVEN_AND_EARTH)->val2;
+			sd->indexed_bonus.magic_atk_ele[ELE_ALL] += i;
+			sd->bonus.short_attack_atk_rate += i;
+			sd->bonus.long_attack_atk_rate += i;
+		}
 	}
 	status_cpy(&sd->battle_status, base_status);
 
@@ -8233,6 +8257,8 @@ static signed short status_calc_patk(struct block_list *bl, status_change *sc, i
 	}
 	if (sc->getSCE(SC_HIDDEN_CARD))
 		patk += sc->getSCE(SC_HIDDEN_CARD)->val2;
+	if (sc->getSCE(SC_TALISMAN_OF_WARRIOR) != nullptr)
+		patk += sc->getSCE(SC_TALISMAN_OF_WARRIOR)->val2;
 
 	return (short)cap_value(patk, 0, SHRT_MAX);
 }
@@ -8260,6 +8286,10 @@ static signed short status_calc_smatk(struct block_list *bl, status_change *sc,
 	if( sc->getSCE( SC_ATTACK_STANCE ) ){
 		smatk += sc->getSCE( SC_ATTACK_STANCE )->val3;
 	}
+	if (sc->getSCE(SC_TALISMAN_OF_MAGICIAN) != nullptr)
+		smatk += sc->getSCE(SC_TALISMAN_OF_MAGICIAN)->val2;
+	if (sc->getSCE(SC_T_FIFTH_GOD) != nullptr)
+		smatk += sc->getSCE(SC_T_FIFTH_GOD)->val2;
 
 	return (short)cap_value(smatk, 0, SHRT_MAX);
 }
@@ -12446,6 +12476,26 @@ int32 status_change_start(struct block_list* src, struct block_list* bl,enum sc_
 			val2 = 3 * val1;
 			val3 = 10 * val1;
 			break;
+		case SC_TALISMAN_OF_PROTECTION:
+			// Heal value is static per cast of skill
+			val3 = skill_calc_heal(src, bl, SOA_TALISMAN_OF_PROTECTION, val1, true);
+			val4 = tick / 3000;
+			// First heal tick applies on cast
+			tick_time = 100;
+			break;
+		case SC_TALISMAN_OF_WARRIOR:
+		case SC_TALISMAN_OF_MAGICIAN:
+			val2 = 2 * val1;
+			break;
+		case SC_T_FIFTH_GOD:
+			val2 = 5 * val1;
+			break;
+		case SC_TALISMAN_OF_FIVE_ELEMENTS:
+			val2 = 4 * val1;
+			break;
+		case SC_HEAVEN_AND_EARTH:
+			val2 = 5 + 2 * 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()) {
@@ -14558,6 +14608,27 @@ TIMER_FUNC(status_change_timer){
 		}
 		sc_timer_next(500 + tick);
 		return 0;
+	case SC_TALISMAN_OF_PROTECTION:
+		if(--(sce->val4) >= 0){
+			// Get the original caster
+			map_session_data* ssd = map_id2sd( sce->val2 );
+
+			// If the caster is offline, dead, on another map or
+			// if the target is not a player or is in another party
+			if( ssd == nullptr || status_isdead( ssd->bl ) || ssd->bl.m != bl->m || sd == nullptr || ssd->status.party_id != sd->status.party_id ){
+				// End the status change
+				sce->val4 = 0;
+				break;
+			}
+
+			int32 hp = sc->getSCE(SC_TALISMAN_OF_PROTECTION)->val3;
+
+			status_heal( bl, hp, 0, 0, 0 );
+			clif_skill_nodamage( nullptr, *bl, AL_HEAL, hp );
+			sc_timer_next(3000 + tick);
+			return 0;
+		}
+		break;
 	}
 
 	// If status has an interval and there is at least 100ms remaining time, wait for next interval

+ 13 - 0
src/map/status.hpp

@@ -1337,6 +1337,19 @@ enum sc_type : int16 {
 	SC_CONTENTS_32,
 	SC_CONTENTS_33,
 
+	// Soul Ascetic
+	SC_TALISMAN_OF_PROTECTION,
+	SC_TALISMAN_OF_WARRIOR,
+	SC_TALISMAN_OF_MAGICIAN,
+	SC_TALISMAN_OF_FIVE_ELEMENTS,
+	SC_T_FIRST_GOD,
+	SC_T_SECOND_GOD,
+	SC_T_THIRD_GOD,
+	SC_T_FOURTH_GOD,
+	SC_T_FIFTH_GOD,
+	SC_HEAVEN_AND_EARTH,
+	SC_TOTEM_OF_TUTELARY,
+
 	SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
 };