Parcourir la source

Initial implementation of Spirit handler (#7998)

Taken from https://github.com/rathena/rathena/pull/7024

Co-authored-by: munkrej <schmunk@posteo.de>
Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
Atemo il y a 4 mois
Parent
commit
d1af743eaa
9 fichiers modifiés avec 1060 ajouts et 3 suppressions
  1. 483 0
      db/re/skill_db.yml
  2. 105 0
      db/re/skill_tree.yml
  3. 107 0
      db/re/status.yml
  4. 84 0
      src/map/battle.cpp
  5. 1 0
      src/map/clif.cpp
  6. 14 0
      src/map/script_constants.hpp
  7. 196 3
      src/map/skill.cpp
  8. 54 0
      src/map/status.cpp
  9. 16 0
      src/map/status.hpp

+ 483 - 0
db/re/skill_db.yml

@@ -41469,6 +41469,489 @@ Body:
     SplashArea: 6
     Requires:
       SpCost: 1
+  - Id: 5433
+    Name: SH_MYSTICAL_CREATURE_MASTERY
+    Description: Mystical Creature Mastery
+    MaxLevel: 10
+  - Id: 5434
+    Name: SH_COMMUNE_WITH_CHUL_HO
+    Description: Commune with Chulho
+    MaxLevel: 1
+  - Id: 5435
+    Name: SH_CHUL_HO_SONIC_CLAW
+    Description: Chulho Sonic Claw
+    MaxLevel: 7
+    Type: Weapon
+    TargetType: Attack
+    DamageFlags:
+      Critical: true
+    Range: -11
+    Hit: Multi_Hit
+    HitCount: -2
+    GiveAp: 1
+    Element: Weapon
+    AfterCastActDelay: 500
+    Cooldown:
+      - Level: 1
+        Time: 1150
+      - Level: 2
+        Time: 1000
+      - Level: 3
+        Time: 850
+      - Level: 4
+        Time: 700
+      - Level: 5
+        Time: 550
+      - Level: 6
+        Time: 400
+      - Level: 7
+        Time: 250
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 42
+        - Level: 2
+          Amount: 44
+        - Level: 3
+          Amount: 46
+        - Level: 4
+          Amount: 48
+        - Level: 5
+          Amount: 50
+        - Level: 6
+          Amount: 52
+        - Level: 7
+          Amount: 54
+  - Id: 5436
+    Name: SH_HOWLING_OF_CHUL_HO
+    Description: Howling of Chulho
+    MaxLevel: 7
+    Type: Weapon
+    TargetType: Self
+    Range: -9
+    Hit: Multi_Hit
+    HitCount: -3
+    GiveAp: 2
+    Element: Weapon
+    DamageFlags:
+      Splash: true
+    SplashArea:
+      - Level: 1
+        Area: 2
+      - Level: 2
+        Area: 2
+      - Level: 3
+        Area: 2
+      - Level: 4
+        Area: 3
+      - Level: 5
+        Area: 3
+      - Level: 6
+        Area: 3
+      - Level: 7
+        Area: 4
+    Duration1: 12000
+    Cooldown: 1000
+    CastCancel: true
+    FixedCastTime: 1000
+    Requires:
+      SpCost: 72
+    Status: Hogogong
+  - Id: 5437
+    Name: SH_HOGOGONG_STRIKE
+    Description: Hogogong Strike
+    MaxLevel: 7
+    Type: Weapon
+    TargetType: Self
+    Range: -9
+    Hit: Multi_Hit
+    HitCount: 3
+    GiveAp: 1
+    Element: Weapon
+    DamageFlags:
+      Splash: true
+      Critical: true
+    SplashArea:
+      - Level: 1
+        Area: 3
+      - Level: 2
+        Area: 3
+      - Level: 3
+        Area: 3
+      - Level: 4
+        Area: 4
+      - Level: 5
+        Area: 4
+      - Level: 6
+        Area: 4
+      - Level: 7
+        Area: 5
+    Cooldown: 350
+    CastCancel: true
+    FixedCastTime: 1000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 67
+        - Level: 2
+          Amount: 70
+        - Level: 3
+          Amount: 73
+        - Level: 4
+          Amount: 76
+        - Level: 5
+          Amount: 79
+        - Level: 6
+          Amount: 82
+        - Level: 7
+          Amount: 85
+  - Id: 5438
+    Name: SH_COMMUNE_WITH_KI_SUL
+    Description: Commune with Kisul
+    MaxLevel: 1
+  - Id: 5439
+    Name: SH_KI_SUL_WATER_SPRAYING
+    Description: Kisul Water Spraying
+    MaxLevel: 7
+    Type: Magic
+    TargetType: Self
+    GiveAp: 1
+    DamageFlags:
+      NoDamage: true
+      Splash: true
+    SplashArea:
+      - Level: 1
+        Area: 3
+      - Level: 2
+        Area: 3
+      - Level: 3
+        Area: 4
+      - Level: 4
+        Area: 4
+      - Level: 5
+        Area: 5
+      - Level: 6
+        Area: 5
+      - Level: 7
+        Area: 6
+    CastCancel: true
+    CastTime: 1700
+    AfterCastActDelay: 1000
+    FixedCastTime: 1000
+    Cooldown: 300
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 61
+        - Level: 2
+          Amount: 65
+        - Level: 3
+          Amount: 69
+        - Level: 4
+          Amount: 73
+        - Level: 5
+          Amount: 77
+        - Level: 6
+          Amount: 81
+        - Level: 7
+          Amount: 85
+  - Id: 5440
+    Name: SH_MARINE_FESTIVAL_OF_KI_SUL
+    Description: Marine Festival of Kisul
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+      Splash: true
+    GiveAp: 4
+    SplashArea:
+      - Level: 1
+        Area: 2
+      - Level: 2
+        Area: 3
+      - Level: 3
+        Area: 4
+      - Level: 4
+        Area: 5
+      - Level: 5
+        Area: 6
+    Duration1: 
+     - Level: 1
+       Time: 60000
+     - Level: 2
+       Time: 75000
+     - Level: 3
+       Time: 90000
+     - Level: 4
+       Time: 105000
+     - Level: 5
+       Time: 120000
+    CastCancel: true
+    CastTime: 1700
+    AfterCastActDelay: 1000
+    FixedCastTime: 1000
+    Cooldown: 2000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 80
+        - Level: 2
+          Amount: 90
+        - Level: 3
+          Amount: 100
+        - Level: 4
+          Amount: 110
+        - Level: 5
+          Amount: 120
+    Status: Marine_Festival
+  - Id: 5441
+    Name: SH_SANDY_FESTIVAL_OF_KI_SUL
+    Description: Sandy Festival of Kisul
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+      Splash: true
+    GiveAp: 4
+    SplashArea:
+      - Level: 1
+        Area: 2
+      - Level: 2
+        Area: 3
+      - Level: 3
+        Area: 4
+      - Level: 4
+        Area: 5
+      - Level: 5
+        Area: 6
+    Duration1: 
+     - Level: 1
+       Time: 60000
+     - Level: 2
+       Time: 75000
+     - Level: 3
+       Time: 90000
+     - Level: 4
+       Time: 105000
+     - Level: 5
+       Time: 120000
+    CastCancel: true
+    CastTime: 1700
+    AfterCastActDelay: 1000
+    FixedCastTime: 1000
+    Cooldown: 2000
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 80
+        - Level: 2
+          Amount: 90
+        - Level: 3
+          Amount: 100
+        - Level: 4
+          Amount: 110
+        - Level: 5
+          Amount: 120
+    Status: Sandy_Festival
+  - Id: 5442
+    Name: SH_KI_SUL_RAMPAGE
+    Description: Kisul Rampage
+    MaxLevel: 7
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+      Splash: true
+    SplashArea: 3
+    Duration1: 
+     - Level: 1
+       Time: 4000
+     - Level: 2
+       Time: 5000
+     - Level: 3
+       Time: 6000
+     - Level: 4
+       Time: 7000
+     - Level: 5
+       Time: 8000
+     - Level: 6
+       Time: 9000
+     - Level: 7
+       Time: 10000
+    CastCancel: true
+    CastTime: 3000
+    AfterCastActDelay: 1000
+    Cooldown: 60000
+    FixedCastTime: 1500
+    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
+    Status: Ki_Sul_Rampage
+  - Id: 5443
+    Name: SH_COMMUNE_WITH_HYUN_ROK
+    Description: Commune with Hyunrok
+    MaxLevel: 1
+  - Id: 5444
+    Name: SH_COLORS_OF_HYUN_ROK
+    Description: Colors of Hyunrok
+    MaxLevel: 7
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+    Duration1: 300000
+    CastCancel: true
+    CastTime: 1700
+    FixedCastTime: 1000
+    Requires:
+      SpCost: 90
+  - Id: 5445
+    Name: SH_HYUN_ROKS_BREEZE
+    Description: Hyunrok Breeze
+    MaxLevel: 7
+    Type: Magic
+    TargetType: Ground
+    Hit: Single
+    HitCount: 1
+    Range: 9
+    GiveAp: 4
+    CastCancel: true
+    CastTime: 3000
+    AfterCastActDelay: 500
+    Cooldown: 4500
+    FixedCastTime: 1500
+    Duration1: 4500
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 58
+        - Level: 2
+          Amount: 64
+        - Level: 3
+          Amount: 70
+        - Level: 4
+          Amount: 76
+        - Level: 5
+          Amount: 82
+        - Level: 6
+          Amount: 88
+        - Level: 7
+          Amount: 94
+    Unit:
+      Id: HYUN_ROKS_BREEZE
+      Range:
+        - Level: 1
+          Size: 2
+        - Level: 2
+          Size: 2
+        - Level: 3
+          Size: 3
+        - Level: 4
+          Size: 3
+        - Level: 5
+          Size: 4
+        - Level: 6
+          Size: 4
+        - Level: 7
+          Size: 5
+      Interval: 300
+      Target: Enemy
+      Flag:
+        NoOverlap: true
+        PathCheck: true
+  - Id: 5446
+    Name: SH_HYUN_ROK_CANNON
+    Description: Hyunrok Cannon
+    MaxLevel: 7
+    Type: Magic
+    TargetType: Attack
+    Range: -11
+    GiveAp: 1
+    Hit: Single
+    HitCount: 1
+    CastCancel: true
+    CastTime: 2000
+    Cooldown: 300
+    FixedCastTime: 1500
+    Requires:
+      SpCost:
+        - Level: 1
+          Amount: 47
+        - Level: 2
+          Amount: 50
+        - Level: 3
+          Amount: 53
+        - Level: 4
+          Amount: 56
+        - Level: 5
+          Amount: 59
+        - Level: 6
+          Amount: 62
+        - Level: 7
+          Amount: 65
+  - Id: 5447
+    Name: SH_TEMPORARY_COMMUNION
+    Description: Temporary Communion
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+    CastCancel: true
+    CastTime: 2000
+    AfterCastActDelay: 500
+    Cooldown: 60000
+    FixedCastTime: 1500
+    Duration1: 
+     - Level: 1
+       Time: 30000
+     - Level: 2
+       Time: 60000
+     - Level: 3
+       Time: 90000
+     - Level: 4
+       Time: 12000
+     - Level: 5
+       Time: 150000
+    Requires:
+      SpCost: 100
+      ApCost: 150
+    Status: Temporary_Communion
+  - Id: 5448
+    Name: SH_BLESSING_OF_MYSTICAL_CREATURES
+    Description: Blessing of Mystical Creatures
+    MaxLevel: 5
+    Type: Magic
+    TargetType: Support
+    Range: -9
+    DamageFlags:
+      NoDamage: true
+    CastCancel: true
+    CastTime: 2000
+    AfterCastActDelay: 500
+    Cooldown: 60000
+    FixedCastTime: 1500
+    Duration1: 10000
+    Duration2: 60000
+    Requires:
+      SpCost: 100
+      ApCost: 100
+    Status: Blessing_of_M_Creatures
   - Id: 5401
     Name: NW_P_F_I
     Description: P.F.I

+ 105 - 0
db/re/skill_tree.yml

@@ -8193,3 +8193,108 @@ Body:
             Level: 5
           - Name: HN_NAPALM_VULCAN_STRIKE
             Level: 5
+  - Job: Spirit_Handler
+    Inherit:
+      Summoner: true
+    Tree:
+      - Name: SH_MYSTICAL_CREATURE_MASTERY
+        MaxLevel: 10
+      - Name: SH_CHUL_HO_SONIC_CLAW
+        MaxLevel: 7
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 1
+      - Name: SH_KI_SUL_WATER_SPRAYING
+        MaxLevel: 7
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 1
+      - Name: SH_COLORS_OF_HYUN_ROK
+        MaxLevel: 7
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 1
+      - Name: SH_HOWLING_OF_CHUL_HO
+        MaxLevel: 7
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 3
+          - Name: SH_CHUL_HO_SONIC_CLAW
+            Level: 3
+      - Name: SH_MARINE_FESTIVAL_OF_KI_SUL
+        MaxLevel: 5
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 3
+          - Name: SH_KI_SUL_WATER_SPRAYING
+            Level: 3
+      - Name: SH_SANDY_FESTIVAL_OF_KI_SUL
+        MaxLevel: 5
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 3
+          - Name: SH_KI_SUL_WATER_SPRAYING
+            Level: 3
+      - Name: SH_HYUN_ROKS_BREEZE
+        MaxLevel: 7
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 3
+          - Name: SH_COLORS_OF_HYUN_ROK
+            Level: 3
+      - Name: SH_HOGOGONG_STRIKE
+        MaxLevel: 7
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 5
+          - Name: SH_CHUL_HO_SONIC_CLAW
+            Level: 3
+      - Name: SH_KI_SUL_RAMPAGE
+        MaxLevel: 7
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 5
+          - Name: SH_MARINE_FESTIVAL_OF_KI_SUL
+            Level: 2
+          - Name: SH_SANDY_FESTIVAL_OF_KI_SUL
+            Level: 2
+      - Name: SH_HYUN_ROK_CANNON
+        MaxLevel: 7
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 5
+          - Name: SH_HYUN_ROKS_BREEZE
+            Level: 3
+      - Name: SH_COMMUNE_WITH_CHUL_HO
+        MaxLevel: 1
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 7
+          - Name: SH_HOGOGONG_STRIKE
+            Level: 3
+      - Name: SH_COMMUNE_WITH_KI_SUL
+        MaxLevel: 1
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 7
+          - Name: SH_KI_SUL_RAMPAGE
+            Level: 3
+      - Name: SH_COMMUNE_WITH_HYUN_ROK
+        MaxLevel: 1
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 7
+          - Name: SH_HYUN_ROK_CANNON
+            Level: 3
+      - Name: SH_TEMPORARY_COMMUNION
+        MaxLevel: 5
+        Requires:
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 10
+      - Name: SH_BLESSING_OF_MYSTICAL_CREATURES
+        MaxLevel: 5
+        Requires:
+          - Name: SH_COMMUNE_WITH_KI_SUL
+            Level: 1
+          - Name: SH_MYSTICAL_CREATURE_MASTERY
+            Level: 10

+ 107 - 0
db/re/status.yml

@@ -7946,6 +7946,8 @@ Body:
     Flags:
       BlEffect: true
       DisplayPc: true
+    EndOnStart:
+      Sandy_Festival: true
   - Status: Benedictum
     Icon: EFST_BENEDICTUM
     DurationLookup: CD_BENEDICTUM
@@ -7956,6 +7958,8 @@ Body:
     Flags:
       BlEffect: true
       DisplayPc: true
+    EndOnStart:
+      Marine_Festival: true
   - Status: Axe_Stomp
     Icon: EFST_AXE_STOMP
     DurationLookup: MT_AXE_STOMP
@@ -9568,3 +9572,106 @@ Body:
       NoDispell: true
       NoBanishingBuster: true
       NoClearance: true
+  - Status: Hogogong
+    Icon: EFST_HOGOGONG
+    DurationLookup: SH_HOWLING_OF_CHUL_HO
+    Flags:
+      Debuff: true
+      BlEffect: true
+      DisplayPc: true
+  - Status: Temporary_Communion
+    Icon: EFST_TEMPORARY_COMMUNION
+    DurationLookup: SH_TEMPORARY_COMMUNION
+    CalcFlags:
+      Patk: true
+      Smatk: true
+      Hplus: true
+  - Status: Marine_Festival
+    Icon: EFST_MARINE_FESTIVAL
+    DurationLookup: SH_MARINE_FESTIVAL_OF_KI_SUL
+    CalcFlags:
+      Pow: true
+      Con: true
+      Crt: true
+    EndOnStart:
+      Benedictum: true
+  - Status: Sandy_Festival
+    Icon: EFST_SANDY_FESTIVAL
+    DurationLookup: SH_SANDY_FESTIVAL_OF_KI_SUL
+    CalcFlags:
+      Spl: true
+      Wis: true
+      Sta: true
+    EndOnStart:
+      Religio: true
+  - Status: Ki_Sul_Rampage
+    Icon: EFST_KI_SUL_RAMPAGE
+    DurationLookup: SH_KI_SUL_RAMPAGE
+    States:
+      NoCast: true
+  - Status: Colors_of_Hyun_Rok_Buff
+    Icon: EFST_COLORS_OF_HYUN_ROK_BUFF
+    DurationLookup: SH_COLORS_OF_HYUN_ROK
+  - Status: Colors_of_Hyun_Rok_1
+    Icon: EFST_COLORS_OF_HYUN_ROK_1
+    DurationLookup: SH_COLORS_OF_HYUN_ROK
+    EndOnStart:
+      Colors_of_Hyun_Rok_2: true
+      Colors_of_Hyun_Rok_3: true
+      Colors_of_Hyun_Rok_4: true
+      Colors_of_Hyun_Rok_5: true
+      Colors_of_Hyun_Rok_6: true
+  - Status: Colors_of_Hyun_Rok_2
+    Icon: EFST_COLORS_OF_HYUN_ROK_2
+    DurationLookup: SH_COLORS_OF_HYUN_ROK
+    EndOnStart:
+      Colors_of_Hyun_Rok_1: true
+      Colors_of_Hyun_Rok_3: true
+      Colors_of_Hyun_Rok_4: true
+      Colors_of_Hyun_Rok_5: true
+      Colors_of_Hyun_Rok_6: true
+  - Status: Colors_of_Hyun_Rok_3
+    Icon: EFST_COLORS_OF_HYUN_ROK_3
+    DurationLookup: SH_COLORS_OF_HYUN_ROK
+    EndOnStart:
+      Colors_of_Hyun_Rok_1: true
+      Colors_of_Hyun_Rok_2: true
+      Colors_of_Hyun_Rok_4: true
+      Colors_of_Hyun_Rok_5: true
+      Colors_of_Hyun_Rok_6: true
+  - Status: Colors_of_Hyun_Rok_4
+    Icon: EFST_COLORS_OF_HYUN_ROK_4
+    DurationLookup: SH_COLORS_OF_HYUN_ROK
+    EndOnStart:
+      Colors_of_Hyun_Rok_1: true
+      Colors_of_Hyun_Rok_2: true
+      Colors_of_Hyun_Rok_3: true
+      Colors_of_Hyun_Rok_5: true
+      Colors_of_Hyun_Rok_6: true
+  - Status: Colors_of_Hyun_Rok_5
+    Icon: EFST_COLORS_OF_HYUN_ROK_5
+    DurationLookup: SH_COLORS_OF_HYUN_ROK
+    EndOnStart:
+      Colors_of_Hyun_Rok_1: true
+      Colors_of_Hyun_Rok_2: true
+      Colors_of_Hyun_Rok_3: true
+      Colors_of_Hyun_Rok_4: true
+      Colors_of_Hyun_Rok_6: true
+  - Status: Colors_of_Hyun_Rok_6
+    Icon: EFST_COLORS_OF_HYUN_ROK_6
+    DurationLookup: SH_COLORS_OF_HYUN_ROK
+    EndOnStart:
+      Colors_of_Hyun_Rok_1: true
+      Colors_of_Hyun_Rok_2: true
+      Colors_of_Hyun_Rok_3: true
+      Colors_of_Hyun_Rok_4: true
+      Colors_of_Hyun_Rok_5: true
+  - Status: Blessing_of_M_Creatures
+    Icon: EFST_BLESSING_OF_M_CREATURES
+    DurationLookup: SH_BLESSING_OF_MYSTICAL_CREATURES
+    CalcFlags:
+      Patk: true
+      Smatk: true
+  - Status: Blessing_of_M_C_Debuff
+    Icon: EFST_BLESSING_OF_M_C_DEBUFF
+    DurationLookup: SH_BLESSING_OF_MYSTICAL_CREATURES

+ 84 - 0
src/map/battle.cpp

@@ -3019,6 +3019,12 @@ static bool is_attack_critical(struct Damage* wd, struct block_list *src, struct
 					return false;
 				}
 				break;
+			case SH_CHUL_HO_SONIC_CLAW:
+				if( pc_checkskill( sd, SH_COMMUNE_WITH_CHUL_HO ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+					break;
+				}
+
+				return false;
 		}
 		if(tsd && tsd->bonus.critical_def)
 			cri = cri * ( 100 - tsd->bonus.critical_def ) / 100;
@@ -3584,6 +3590,26 @@ int32 battle_get_magic_element(struct block_list* src, struct block_list* target
 			if (sd)
 				element = sd->bonus.arrow_ele;
 			break;
+		case SU_CN_METEOR:
+		case SU_CN_METEOR2:
+		case SH_HYUN_ROKS_BREEZE:
+		case SH_HYUN_ROK_CANNON:
+			if( sc != nullptr && sc->count > 0 ){
+				if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_1 ) != nullptr ){
+					element = ELE_WATER;
+				}else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_2 ) != nullptr ){
+					element = ELE_WIND;
+				}else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_3 ) != nullptr ){
+					element = ELE_EARTH;
+				}else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_4 ) != nullptr ){
+					element = ELE_FIRE;
+				}else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_5 ) != nullptr ){
+					element = ELE_DARK;
+				}else if( sc->getSCE( SC_COLORS_OF_HYUN_ROK_6 ) != nullptr ){
+					element = ELE_HOLY;
+				}
+			}
+			break;
 	}
 
 	return element;
@@ -6314,6 +6340,39 @@ static int32 battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list
 			skillratio += 5 * sstatus->con;
 			RE_LVL_DMOD(100);
 			break;
+		case SH_CHUL_HO_SONIC_CLAW:
+			skillratio += -100 + 850 + 1650 * skill_lv;
+			skillratio += 50 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+			skillratio += 5 * sstatus->pow;
+
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_CHUL_HO ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+				skillratio += 100 + 400 * skill_lv;
+				skillratio += 50 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+			}
+			RE_LVL_DMOD(100);
+			break;
+		case SH_HOWLING_OF_CHUL_HO:
+			skillratio += -100 + 600 + 1050 * skill_lv;
+			skillratio += 50 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+			skillratio += 5 * sstatus->pow;
+
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_CHUL_HO ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+				skillratio += 100 + 100 * skill_lv;
+				skillratio += 50 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+			}
+			RE_LVL_DMOD(100);
+			break;
+		case SH_HOGOGONG_STRIKE:
+			skillratio += -100 + 180 + 200 * skill_lv;
+			skillratio += 10 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+			skillratio += 5 * sstatus->pow;
+
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_CHUL_HO ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+				skillratio += 70 + 150 * skill_lv;
+				skillratio += 10 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+			}
+			RE_LVL_DMOD(100);
+			break;
 	}
 	return skillratio;
 }
@@ -8394,6 +8453,9 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						if (status_get_lv(src) > 99) {
 							skillratio += sstatus->int_ * 5;
 						}
+						// !TODO: the buff could be here or could be part of the skillatk bonus
+						if( sc != nullptr && sc->getSCE( SC_COLORS_OF_HYUN_ROK_BUFF ) != nullptr )
+							skillratio += skillratio * 50 / 100;
 						RE_LVL_DMOD(100);
 						break;
 					case NPC_VENOMFOG:
@@ -8869,6 +8931,28 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						skillratio += 3 * sstatus->spl;
 						RE_LVL_DMOD(100);
 						break;
+					case SH_HYUN_ROKS_BREEZE:
+						skillratio += -100 + 650 + 750 * skill_lv;
+						skillratio += 20 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+						skillratio += 5 * sstatus->spl;
+
+						if( pc_checkskill( sd, SH_COMMUNE_WITH_HYUN_ROK ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+							skillratio += 100 + 200 * skill_lv;
+							skillratio += 20 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+						}
+						RE_LVL_DMOD(100);
+						break;
+					case SH_HYUN_ROK_CANNON:
+						skillratio += -100 + 1050 + 1550 * skill_lv;
+						skillratio += 50 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+						skillratio += 5 * sstatus->spl;
+
+						if( pc_checkskill( sd, SH_COMMUNE_WITH_HYUN_ROK ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+							skillratio += 300 * skill_lv;
+							skillratio += 25 * pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY);
+						}
+						RE_LVL_DMOD(100);
+						break;
 				}
 
 				if (sc) {// Insignia's increases the damage of offensive magic by a fixed percentage depending on the element.

+ 1 - 0
src/map/clif.cpp

@@ -11356,6 +11356,7 @@ void clif_parse_WalkToXY(int32 fd, map_session_data *sd)
 		skill_check_cloaking(&sd->bl, sd->sc.getSCE(SC_CLOAKING));
 	status_change_end(&sd->bl, SC_ROLLINGCUTTER); // If you move, you lose your counters. [malufett]
 	status_change_end(&sd->bl, SC_CRESCIVEBOLT);
+	status_change_end(&sd->bl, SC_KI_SUL_RAMPAGE);
 
 	pc_delinvincibletimer(sd);
 

+ 14 - 0
src/map/script_constants.hpp

@@ -1940,6 +1940,20 @@
 	export_constant(SC_ALL_GLASTHEIM_RECALL);
 	export_constant(SC_ALL_THANATOS_RECALL);
 	export_constant(SC_ALL_LIGHTHALZEN_RECALL);
+	export_constant(SC_HOGOGONG);
+	export_constant(SC_MARINE_FESTIVAL);
+	export_constant(SC_SANDY_FESTIVAL);
+	export_constant(SC_KI_SUL_RAMPAGE);
+	export_constant(SC_COLORS_OF_HYUN_ROK_1);
+	export_constant(SC_COLORS_OF_HYUN_ROK_2);
+	export_constant(SC_COLORS_OF_HYUN_ROK_3);
+	export_constant(SC_COLORS_OF_HYUN_ROK_4);
+	export_constant(SC_COLORS_OF_HYUN_ROK_5);
+	export_constant(SC_COLORS_OF_HYUN_ROK_6);
+	export_constant(SC_COLORS_OF_HYUN_ROK_BUFF);
+	export_constant(SC_TEMPORARY_COMMUNION);
+	export_constant(SC_BLESSING_OF_M_CREATURES);
+	export_constant(SC_BLESSING_OF_M_C_DEBUFF);
 
 /// Do not modify code below this, until the end of the API hook, since it will be automatically generated again
 /// @APIHOOK_START(EFST_CONST)

+ 196 - 3
src/map/skill.cpp

@@ -2208,6 +2208,9 @@ int32 skill_additional_effect( struct block_list* src, struct block_list *bl, ui
 	case HN_GROUND_GRAVITATION:
 		sc_start(src, bl, skill_get_sc(skill_id), 100, 0, skill_get_time2(skill_id, skill_lv));
 		break;
+	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;
 	} //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)
@@ -3103,6 +3106,8 @@ short skill_blown(struct block_list* src, struct block_list* target, char count,
 			status_change_end(target, SC_ROLLINGCUTTER);
 		if (tsc->getSCE(SC_CRESCIVEBOLT))
 			status_change_end(target, SC_CRESCIVEBOLT);
+		if( tsc->getSCE( SC_KI_SUL_RAMPAGE ) != nullptr )
+			status_change_end(target, SC_KI_SUL_RAMPAGE);
 		if (tsc->getSCE(SC_SV_ROOTTWIST)) // Shouldn't move.
 			return 0;
 	}
@@ -5268,6 +5273,10 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 		skill_attack(BF_WEAPON,src,src,bl,skill_id,skill_lv,tick,flag);
 		break;
 	case DK_DRAGONIC_AURA:
+		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+		skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
+		sc_start(src, src, SC_DRAGONIC_AURA, 100, skill_lv, skill_get_time(skill_id,skill_lv));
+		break;
 	case DK_STORMSLASH:
 	case IG_IMPERIAL_CROSS:
 	case CD_EFFLIGO:
@@ -5278,10 +5287,9 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 	case TR_RHYTHMSHOOTING:
 	case HN_MEGA_SONIC_BLOW:
 	case HN_SPIRAL_PIERCE_MAX:
+	case SH_CHUL_HO_SONIC_CLAW:
 		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
 		skill_attack(BF_WEAPON, src, src, bl, skill_id, skill_lv, tick, flag);
-		if (skill_id == DK_DRAGONIC_AURA)
-			sc_start(src, src, SC_DRAGONIC_AURA, 100, skill_lv, skill_get_time(skill_id,skill_lv));
 		break;
 
 	case SHC_ETERNAL_SLASH:
@@ -6001,6 +6009,16 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 		}
 		break;
 
+	case SH_HOWLING_OF_CHUL_HO:
+		if (flag & 1)
+			skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+		break;
+	case SH_HOGOGONG_STRIKE:
+		if( flag&1 && tsc != nullptr && tsc->getSCE( SC_HOGOGONG ) != nullptr ){
+			skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
+		}
+		break;
+
 	//Place units around target
 	case NJ_BAKUENRYU:
 		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
@@ -6203,8 +6221,9 @@ int32 skill_castend_damage_id (struct block_list* src, struct block_list *bl, ui
 
 	case IG_JUDGEMENT_CROSS:
 	case TR_SOUNDBLEND:
+	case SH_HYUN_ROK_CANNON:
 		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
-		skill_attack(BF_MAGIC, src, src, bl, skill_id, skill_lv, tick, flag);
+		skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
 		break;
 
 	case AG_DEADLY_PROJECTION:
@@ -8056,6 +8075,7 @@ int32 skill_castend_nodamage_id (struct block_list *src, struct block_list *bl,
 	case NPC_RELIEVE_OFF:
 	case HN_BREAKINGLIMIT:
 	case HN_RULEBREAK:
+	case SH_TEMPORARY_COMMUNION:
 		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;
@@ -13106,6 +13126,150 @@ int32 skill_castend_nodamage_id (struct block_list *src, struct block_list *bl,
 		}
 		break;
 
+	case SH_HOWLING_OF_CHUL_HO: {
+		int32 range = skill_get_splash(skill_id, skill_lv);
+
+		if( pc_checkskill( sd, SH_COMMUNE_WITH_CHUL_HO ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+			range += 1;
+		}
+
+		skill_area_temp[0] = 0;
+		skill_area_temp[1] = bl->id;
+		skill_area_temp[2] = 0;
+		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 | 1, skill_castend_damage_id);
+		} break;
+
+	case SH_HOGOGONG_STRIKE:
+		if( pc_checkskill( sd, SH_COMMUNE_WITH_CHUL_HO ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) )
+			status_heal(src, 0, 0, 1, 0);
+		skill_area_temp[0] = 0;
+		skill_area_temp[1] = bl->id;
+		skill_area_temp[2] = 0;
+		clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+		map_foreachinrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag | BCT_ENEMY | 1, skill_castend_damage_id);
+		break;
+
+	case SH_KI_SUL_WATER_SPRAYING:
+		if (sd == nullptr || sd->status.party_id == 0 || (flag & 1)) {
+			// TODO: verify on official server, if this should be moved into skill_calc_heal
+			int32 heal = 500 * skill_lv + status_get_int(src) * 5;
+			heal += pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY) * 100;
+
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_KI_SUL ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+				heal += 250 * skill_lv;
+				heal += pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY) * 50;
+			}
+			heal = heal * (100 + status_get_crt(src)) * status_get_lv(src) / 10000;
+			status_heal(bl, heal, 0, 0, 0);
+			clif_skill_nodamage(src, *bl, skill_id, heal);
+		}
+		else {
+			int32 range = skill_get_splash(skill_id, skill_lv);
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_KI_SUL ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) )
+				range += 2;
+			party_foreachsamemap(skill_area_sub, sd, range, src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+		}
+		break;
+
+	case SH_MARINE_FESTIVAL_OF_KI_SUL:
+	case SH_SANDY_FESTIVAL_OF_KI_SUL:
+		if (sd == nullptr || sd->status.party_id == 0 || (flag & 1)) {
+			int32 time = skill_get_time(skill_id, skill_lv);
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_KI_SUL ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) )
+				time *= 2;
+			sc_start(src, bl, type, 100, skill_lv, time);
+			clif_skill_nodamage(src, *bl, skill_id, skill_lv);
+		}
+		else {
+			int32 range = skill_get_splash(skill_id, skill_lv);
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_KI_SUL ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) )
+				range += 2;
+			party_foreachsamemap(skill_area_sub, sd, range, src, skill_id, skill_lv, tick, flag|BCT_PARTY|1, skill_castend_nodamage_id);
+		}
+		break;
+
+	case SH_KI_SUL_RAMPAGE:
+		if( flag&2 ){
+			if( src == bl ){
+				break;
+			}
+
+			int64 ap = 2;
+
+			if( flag&4 ){
+				ap += 4;
+			}
+
+			status_heal( bl, 0, 0, ap, 0 );
+		}else if( flag&1 ){
+			int32 range = skill_get_splash( SH_KI_SUL_RAMPAGE, skill_lv );
+			uint16 skill_lv2 = skill_lv;
+
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_KI_SUL ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) ){
+				range += 2;
+				skill_lv2 = skill_get_max( SH_KI_SUL_RAMPAGE );
+				// Set a flag for AP increase
+				flag |= 4;
+			}
+
+			clif_skill_nodamage( bl, *bl, SH_KI_SUL_RAMPAGE, skill_lv2 );
+			map_foreachinrange( skill_area_sub, bl, range, BL_CHAR, bl, SH_KI_SUL_RAMPAGE, skill_lv2, tick, flag|BCT_PARTY|SD_SPLASH|2, skill_castend_nodamage_id );
+		}else{
+			// TODO: no party check ?
+			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;
+
+	case SH_COLORS_OF_HYUN_ROK:
+		if (skill_lv == 7) {
+			status_change_end(src, SC_COLORS_OF_HYUN_ROK_1);
+			status_change_end(src, SC_COLORS_OF_HYUN_ROK_2);
+			status_change_end(src, SC_COLORS_OF_HYUN_ROK_3);
+			status_change_end(src, SC_COLORS_OF_HYUN_ROK_4);
+			status_change_end(src, SC_COLORS_OF_HYUN_ROK_5);
+			status_change_end(src, SC_COLORS_OF_HYUN_ROK_6);
+
+			clif_skill_nodamage(src, *src, skill_id, skill_lv);
+		}
+		else {
+			// Buff to increase Catnip Meteor damage
+			if( pc_checkskill( sd, SH_COMMUNE_WITH_HYUN_ROK ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) )
+				sc_start(src, bl, SC_COLORS_OF_HYUN_ROK_BUFF, 100, 1, skill_get_time(skill_id, skill_lv));
+
+			// Endows elemental property to Catnip Meteor, Hyunrok Breeze and Hyunrok Cannon skills
+			switch (skill_lv) {
+				case 1:
+					type = SC_COLORS_OF_HYUN_ROK_1;
+					break;
+				case 2:
+					type = SC_COLORS_OF_HYUN_ROK_2;
+					break;
+				case 3:
+					type = SC_COLORS_OF_HYUN_ROK_3;
+					break;
+				case 4:
+					type = SC_COLORS_OF_HYUN_ROK_4;
+					break;
+				case 5:
+					type = SC_COLORS_OF_HYUN_ROK_5;
+					break;
+				case 6:
+					type = SC_COLORS_OF_HYUN_ROK_6;
+					break;
+			}
+			sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id,skill_lv));
+			clif_skill_nodamage(src, *src, skill_id, skill_lv);
+		}
+		break;
+
+	case SH_BLESSING_OF_MYSTICAL_CREATURES:
+		status_heal(bl, 0, 0, 200-status_get_ap(bl), 0);
+		sc_start(src, bl, type, 100, skill_lv, skill_get_time(skill_id, skill_lv));
+		clif_skill_nodamage(src, *src, skill_id, skill_lv);
+		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);
@@ -13232,6 +13396,23 @@ static int8 skill_castend_id_check(struct block_list *src, struct block_list *ta
 			if (!tsc || !tsc->getSCE(SC_SECOND_BRAND))
 				return USESKILL_FAIL_LEVEL;
 			break;
+		case SH_BLESSING_OF_MYSTICAL_CREATURES:
+			if( src == target ){
+				return USESKILL_FAIL_TOTARGET;
+			}
+
+			if( battle_check_target( src, target, BCT_PARTY ) <= 0 ){
+				return USESKILL_FAIL_TOTARGET;
+			}
+
+			if( ( status_get_class_( target )&MAPID_BASEMASK ) == MAPID_SUMMONER ){
+				return USESKILL_FAIL_TOTARGET;
+			}
+
+			if( tsc != nullptr && tsc->getSCE( SC_BLESSING_OF_M_C_DEBUFF ) != nullptr ){
+				return USESKILL_FAIL_TOTARGET;
+			}
+			break;
 	}
 
 	if (inf&INF_ATTACK_SKILL ||
@@ -13491,6 +13672,10 @@ TIMER_FUNC(skill_castend_id){
 								add_ap += 2;
 							}
 							break;
+						case SH_HYUN_ROK_CANNON:
+							if( pc_checkskill( sd, SH_COMMUNE_WITH_HYUN_ROK ) > 0 || ( sc != nullptr && sc->getSCE( SC_TEMPORARY_COMMUNION ) != nullptr ) )
+								add_ap += 1;
+							break;
 					}
 
 					status_heal(&sd->bl, 0, 0, add_ap, 0);
@@ -14092,6 +14277,7 @@ int32 skill_castend_pos2(struct block_list* src, int32 x, int32 y, uint16 skill_
 	case EM_CONFLAGRATION:
 	case EM_TERRA_DRIVE:
 	case SOA_TOTEM_OF_TUTELARY:
+	case SH_HYUN_ROKS_BREEZE:
 		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.
@@ -16207,6 +16393,7 @@ int32 skill_unit_onplace_timer(struct skill_unit *unit, struct block_list *bl, t
 		case UNT_SOLIDTRAP:
 		case UNT_SWIFTTRAP:
 		case UNT_FLAMETRAP:
+		case UNT_HYUN_ROKS_BREEZE:
 			skill_attack(skill_get_type(sg->skill_id),ss,&unit->bl,bl,sg->skill_id,sg->skill_lv,tick,0);
 			break;
 #ifdef RENEWAL
@@ -18336,6 +18523,12 @@ bool skill_check_condition_castbegin( map_session_data& sd, uint16 skill_id, uin
 				return false;
 			}
 			break;
+		case SH_TEMPORARY_COMMUNION:
+			if (pc_checkskill(&sd, SH_COMMUNE_WITH_CHUL_HO) == 0 && pc_checkskill(&sd, SH_COMMUNE_WITH_HYUN_ROK) == 0 && pc_checkskill(&sd, SH_COMMUNE_WITH_KI_SUL) == 0) {
+				clif_skill_fail( sd, skill_id, USESKILL_FAIL_CONDITION );
+				return false;
+			}
+			break;
 	}
 
 	/* check state required */

+ 54 - 0
src/map/status.cpp

@@ -4435,6 +4435,11 @@ int32 status_calc_pc_sub(map_session_data* sd, uint8 opt)
 		base_status->smatk += skill * 2;
 	}
 
+	if ((skill = pc_checkskill(sd, SH_MYSTICAL_CREATURE_MASTERY)) > 0) {
+		base_status->smatk += skill * 15 / 10;
+		base_status->patk += skill * 15 / 10;
+	}
+
 // ----- PHYSICAL RESISTANCE CALCULATION -----
 	if ((skill = pc_checkskill_imperial_guard(sd, 1)) > 0)// IG_SHIELD_MASTERY
 		base_status->res += skill * 3;
@@ -6852,6 +6857,8 @@ static unsigned short status_calc_pow(struct block_list *bl, status_change *sc,
 
 	if (sc->getSCE(SC_BENEDICTUM))
 		pow += sc->getSCE(SC_BENEDICTUM)->val2;
+	if (sc->getSCE(SC_MARINE_FESTIVAL) != nullptr)
+		pow += sc->getSCE(SC_MARINE_FESTIVAL)->val2;
 
 	return (unsigned short)cap_value(pow, 0, USHRT_MAX);
 }
@@ -6870,6 +6877,8 @@ static unsigned short status_calc_sta(struct block_list *bl, status_change *sc,
 
 	if (sc->getSCE(SC_RELIGIO))
 		sta += sc->getSCE(SC_RELIGIO)->val2;
+	if (sc->getSCE(SC_SANDY_FESTIVAL) != nullptr)
+		sta += sc->getSCE(SC_SANDY_FESTIVAL)->val2;
 
 	return (unsigned short)cap_value(sta, 0, USHRT_MAX);
 }
@@ -6888,6 +6897,8 @@ static unsigned short status_calc_wis(struct block_list *bl, status_change *sc,
 
 	if (sc->getSCE(SC_RELIGIO))
 		wis += sc->getSCE(SC_RELIGIO)->val2;
+	if (sc->getSCE(SC_SANDY_FESTIVAL) != nullptr)
+		wis += sc->getSCE(SC_SANDY_FESTIVAL)->val2;
 
 	return (unsigned short)cap_value(wis, 0, USHRT_MAX);
 }
@@ -6906,6 +6917,8 @@ static unsigned short status_calc_spl(struct block_list *bl, status_change *sc,
 
 	if (sc->getSCE(SC_RELIGIO))
 		spl += sc->getSCE(SC_RELIGIO)->val2;
+	if (sc->getSCE(SC_SANDY_FESTIVAL) != nullptr)
+		spl += sc->getSCE(SC_SANDY_FESTIVAL)->val2;
 
 	return (unsigned short)cap_value(spl, 0, USHRT_MAX);
 }
@@ -6924,6 +6937,8 @@ static unsigned short status_calc_con(struct block_list *bl, status_change *sc,
 
 	if (sc->getSCE(SC_BENEDICTUM))
 		con += sc->getSCE(SC_BENEDICTUM)->val2;
+	if (sc->getSCE(SC_MARINE_FESTIVAL) != nullptr)
+		con += sc->getSCE(SC_MARINE_FESTIVAL)->val2;
 
 	return (unsigned short)cap_value(con, 0, USHRT_MAX);
 }
@@ -6942,6 +6957,8 @@ static unsigned short status_calc_crt(struct block_list *bl, status_change *sc,
 
 	if (sc->getSCE(SC_BENEDICTUM))
 		crt += sc->getSCE(SC_BENEDICTUM)->val2;
+	if (sc->getSCE(SC_MARINE_FESTIVAL) != nullptr)
+		crt += sc->getSCE(SC_MARINE_FESTIVAL)->val2;
 
 	return (unsigned short)cap_value(crt, 0, USHRT_MAX);
 }
@@ -8259,6 +8276,10 @@ static signed short status_calc_patk(struct block_list *bl, status_change *sc, i
 		patk += sc->getSCE(SC_HIDDEN_CARD)->val2;
 	if (sc->getSCE(SC_TALISMAN_OF_WARRIOR) != nullptr)
 		patk += sc->getSCE(SC_TALISMAN_OF_WARRIOR)->val2;
+	if (sc->getSCE(SC_TEMPORARY_COMMUNION) != nullptr)
+		patk += sc->getSCE(SC_TEMPORARY_COMMUNION)->val2;
+	if (sc->getSCE(SC_BLESSING_OF_M_CREATURES) != nullptr)
+		patk += sc->getSCE(SC_BLESSING_OF_M_CREATURES)->val2;
 
 	return (short)cap_value(patk, 0, SHRT_MAX);
 }
@@ -8290,6 +8311,10 @@ static signed short status_calc_smatk(struct block_list *bl, status_change *sc,
 		smatk += sc->getSCE(SC_TALISMAN_OF_MAGICIAN)->val2;
 	if (sc->getSCE(SC_T_FIFTH_GOD) != nullptr)
 		smatk += sc->getSCE(SC_T_FIFTH_GOD)->val2;
+	if (sc->getSCE(SC_TEMPORARY_COMMUNION) != nullptr)
+		smatk += sc->getSCE(SC_TEMPORARY_COMMUNION)->val2;
+	if (sc->getSCE(SC_BLESSING_OF_M_CREATURES) != nullptr)
+		smatk += sc->getSCE(SC_BLESSING_OF_M_CREATURES)->val2;
 
 	return (short)cap_value(smatk, 0, SHRT_MAX);
 }
@@ -8358,6 +8383,9 @@ static signed short status_calc_hplus(struct block_list *bl, status_change *sc,
 	if (sc == nullptr || sc->empty())
 		return cap_value(hplus, 0, SHRT_MAX);
 
+	if (sc->getSCE(SC_TEMPORARY_COMMUNION) != nullptr)
+		hplus += sc->getSCE(SC_TEMPORARY_COMMUNION)->val2;
+
 	return (short)cap_value(hplus, 0, SHRT_MAX);
 }
 
@@ -12498,6 +12526,20 @@ int32 status_change_start(struct block_list* src, struct block_list* bl,enum sc_
 		case SC_HEAVEN_AND_EARTH:
 			val2 = 5 + 2 * val1;
 			break;
+		case SC_TEMPORARY_COMMUNION:
+			val2 = val1 * 3;
+			break;
+		case SC_MARINE_FESTIVAL:
+		case SC_SANDY_FESTIVAL:
+			val2 = 2 * val1;
+			break;
+		case SC_KI_SUL_RAMPAGE:
+			tick_time = 1000;
+			val4 = tick / tick_time;
+			break;
+		case SC_BLESSING_OF_M_CREATURES:
+			val2 = val1 * 10;
+			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()) {
@@ -13492,6 +13534,10 @@ int32 status_change_end(struct block_list* bl, enum sc_type type, int32 tid)
 				pc_delabyssball( *sd, sd->abyssball );
 			}
 			break;
+		case SC_BLESSING_OF_M_CREATURES:
+			sc_start(bl,bl, SC_BLESSING_OF_M_C_DEBUFF, 100, 1, skill_get_time2(SH_BLESSING_OF_MYSTICAL_CREATURES, 1));
+			status_percent_change(bl,bl,0, 0, -100,1);
+			break;
 	}
 
 	// End statuses found in the EndOnEnd list.
@@ -14608,6 +14654,7 @@ TIMER_FUNC(status_change_timer){
 			sce->val4++;
 			sc_start(bl, bl, SC_INTENSIVE_AIM_COUNT, 100, sce->val4, INFINITE_TICK);
 		}
+
 		sc_timer_next(500 + tick);
 		return 0;
 	case SC_TALISMAN_OF_PROTECTION:
@@ -14631,6 +14678,13 @@ TIMER_FUNC(status_change_timer){
 			return 0;
 		}
 		break;
+	case SC_KI_SUL_RAMPAGE:
+		if (--(sce->val4) >= 0) {
+			skill_castend_nodamage_id( bl, bl, SH_KI_SUL_RAMPAGE, sce->val1, tick, 1 );
+			sc_timer_next(1000 + tick);
+			return 0;
+		}
+		break;
 	}
 
 	// If status has an interval and there is at least 100ms remaining time, wait for next interval

+ 16 - 0
src/map/status.hpp

@@ -1359,6 +1359,22 @@ enum sc_type : int16 {
 	SC_ALL_THANATOS_RECALL,
 	SC_ALL_LIGHTHALZEN_RECALL,
 
+	// Spirit Handler
+	SC_HOGOGONG,
+	SC_MARINE_FESTIVAL,
+	SC_SANDY_FESTIVAL,
+	SC_KI_SUL_RAMPAGE,
+	SC_COLORS_OF_HYUN_ROK_1,
+	SC_COLORS_OF_HYUN_ROK_2,
+	SC_COLORS_OF_HYUN_ROK_3,
+	SC_COLORS_OF_HYUN_ROK_4,
+	SC_COLORS_OF_HYUN_ROK_5,
+	SC_COLORS_OF_HYUN_ROK_6,
+	SC_COLORS_OF_HYUN_ROK_BUFF,
+	SC_TEMPORARY_COMMUNION,
+	SC_BLESSING_OF_M_CREATURES,
+	SC_BLESSING_OF_M_C_DEBUFF,
+
 	SC_MAX, //Automatically updated max, used in for's to check we are within bounds.
 };