Explorar o código

Revert "SQL synchronization"

This reverts commit 53761b952af832455526401acfc8b388a60a5d84.
aleos %!s(int64=5) %!d(string=hai) anos
pai
achega
0021b6d577

+ 6 - 9
db/job_db2.txt

@@ -312,18 +312,15 @@
 // Baby Star Gladiator (Union)
 4238,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2
 //================================
-// Note: Star Emperor and Soul Reaper bonus stats are unknown. Using Star Gladiator and Soul Linker's
-// bonus stats for now until I know the official ones.
-//
 // Star Emperor
-4239,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2
+4239,1,5,0,0,2,0,4,1,6,0,5,1,2,0,4,6,3,0,1,5,2,0,1,3,4,0,5,0,2,5,1,0,0,5,2,6,3,5,1,0,2,3,1,0,5,0,2,1,0,5,0,0,0,0,0,1,0,0,2,0
 // Soul Reaper
-4240,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5
+4240,4,5,0,0,4,3,5,0,0,0,5,4,2,0,5,4,3,0,1,5,2,0,0,3,4,5,0,1,2,5,4,0,0,5,2,0,3,5,4,0,2,3,1,4,5,0,2,0,4,5,0,2,0,4,0,0,0,0,4,0
 // Baby Star Emperor
-4241,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2
+4241,1,5,0,0,2,0,4,1,6,0,5,1,2,0,4,6,3,0,1,5,2,0,1,3,4,0,5,0,2,5,1,0,0,5,2,6,3,5,1,0,2,3,1,0,5,0,2,1,0,5,0,0,0,0,0,1,0,0,2,0
 // Baby Soul Reaper
-4242,4,4,4,4,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,3,3,3,3,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,5,5,5,5,5,5,5,5,5,5,5,5
+4242,4,5,0,0,4,3,5,0,0,0,5,4,2,0,5,4,3,0,1,5,2,0,0,3,4,5,0,1,2,5,4,0,0,5,2,0,3,5,4,0,2,3,1,4,5,0,2,0,4,5,0,2,0,4,0,0,0,0,4,0
 // Star Emperor (Union)
-4243,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2
+4243,1,5,0,0,2,0,4,1,6,0,5,1,2,0,4,6,3,0,1,5,2,0,1,3,4,0,5,0,2,5,1,0,0,5,2,6,3,5,1,0,2,3,1,0,5,0,2,1,0,5,0,0,0,0,0,1,0,0,2,0
 // Baby Star Emperor (Union)
-4244,1,1,1,1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,5,5,5,5,5,5,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,2,2,2,2
+4244,1,5,0,0,2,0,4,1,6,0,5,1,2,0,4,6,3,0,1,5,2,0,1,3,4,0,5,0,2,5,1,0,0,5,2,6,3,5,1,0,2,3,1,0,5,0,2,1,0,5,0,0,0,0,0,1,0,0,2,0

+ 157 - 0
db/pre-re/skill_db.yml

@@ -28317,6 +28317,163 @@ Body:
     Element: Weapon
     Requires:
       SpCost: 1
+  - Id: 2574
+    Name: SJ_LIGHTOFMOON
+    Description: Light of Moon
+    MaxLevel: 1
+  - Id: 2575
+    Name: SJ_LUNARSTANCE
+    Description: Lunar Stance
+    MaxLevel: 1
+  - Id: 2576
+    Name: SJ_FULLMOONKICK
+    Description: Full Moon Kick
+    MaxLevel: 1
+  - Id: 2577
+    Name: SJ_LIGHTOFSTAR
+    Description: Light of Star
+    MaxLevel: 1
+  - Id: 2578
+    Name: SJ_STARSTANCE
+    Description: Star Stance
+    MaxLevel: 1
+  - Id: 2579
+    Name: SJ_NEWMOONKICK
+    Description: New Moon Kick
+    MaxLevel: 1
+  - Id: 2580
+    Name: SJ_FLASHKICK
+    Description: Flash Kick
+    MaxLevel: 1
+  - Id: 2581
+    Name: SJ_STAREMPEROR
+    Description: Star Emperor
+    MaxLevel: 1
+  - Id: 2582
+    Name: SJ_NOVAEXPLOSING
+    Description: Nova Explosion
+    MaxLevel: 1
+    Type: Misc
+  - Id: 2583
+    Name: SJ_UNIVERSESTANCE
+    Description: Universe Stance
+    MaxLevel: 1
+  - Id: 2584
+    Name: SJ_FALLINGSTAR
+    Description: Falling Star
+    MaxLevel: 1
+  - Id: 2585
+    Name: SJ_GRAVITYCONTROL
+    Description: Gravity Control
+    MaxLevel: 1
+  - Id: 2586
+    Name: SJ_BOOKOFDIMENSION
+    Description: Book of Dimension
+    MaxLevel: 1
+  - Id: 2587
+    Name: SJ_BOOKOFCREATINGSTAR
+    Description: Book of Creating Star
+    MaxLevel: 1
+  - Id: 2588
+    Name: SJ_DOCUMENT
+    Description: Document of Sun Moon and Star
+    MaxLevel: 1
+  - Id: 2589
+    Name: SJ_PURIFY
+    Description: Purification of Sun Moon and Star
+    MaxLevel: 1
+  - Id: 2590
+    Name: SJ_LIGHTOFSUN
+    Description: Light of Sun
+    MaxLevel: 1
+  - Id: 2591
+    Name: SJ_SUNSTANCE
+    Description: Sun Stance
+    MaxLevel: 1
+  - Id: 2592
+    Name: SJ_SOLARBURST
+    Description: Solar Burst
+    MaxLevel: 1
+  - Id: 2593
+    Name: SJ_PROMINENCEKICK
+    Description: Prominence Kick
+    MaxLevel: 1
+  - Id: 2594
+    Name: SJ_FALLINGSTAR_ATK
+    Description: Falling Star Attack
+    MaxLevel: 1
+  - Id: 2595
+    Name: SJ_FALLINGSTAR_ATK2
+    Description: Falling Star Attack 2
+    MaxLevel: 1
+  - Id: 2596
+    Name: SP_SOULGOLEM
+    Description: Golem's Soul
+    MaxLevel: 1
+  - Id: 2597
+    Name: SP_SOULSHADOW
+    Description: Shadow's Soul
+    MaxLevel: 1
+  - Id: 2598
+    Name: SP_SOULFALCON
+    Description: Falcon's Soul
+    MaxLevel: 1
+  - Id: 2599
+    Name: SP_SOULFAIRY
+    Description: Fairy's Soul
+    MaxLevel: 1
+  - Id: 2600
+    Name: SP_CURSEEXPLOSION
+    Description: Curse Explosion
+    MaxLevel: 1
+  - Id: 2601
+    Name: SP_SOULCURSE
+    Description: Soul Curse
+    MaxLevel: 1
+  - Id: 2602
+    Name: SP_SPA
+    Description: Espa
+    MaxLevel: 1
+  - Id: 2603
+    Name: SP_SHA
+    Description: Esha
+    MaxLevel: 1
+  - Id: 2604
+    Name: SP_SWHOO
+    Description: Eswhoo
+    MaxLevel: 1
+  - Id: 2605
+    Name: SP_SOULUNITY
+    Description: Soul Unity
+    MaxLevel: 1
+  - Id: 2606
+    Name: SP_SOULDIVISION
+    Description: Soul Division
+    MaxLevel: 1
+  - Id: 2607
+    Name: SP_SOULREAPER
+    Description: Soul Reaper
+    MaxLevel: 1
+  - Id: 2608
+    Name: SP_SOULREVOLVE
+    Description: Soul Revolution
+    MaxLevel: 1
+  - Id: 2609
+    Name: SP_SOULCOLLECT
+    Description: Soul Collect
+    MaxLevel: 1
+  - Id: 2610
+    Name: SP_SOULEXPLOSION
+    Description: Soul Explosion
+    MaxLevel: 1
+  - Id: 2611
+    Name: SP_SOULENERGY
+    Description: Soul Energy Research
+    MaxLevel: 1
+  - Id: 2612
+    Name: SP_KAUTE
+    Description: Kaute
+    MaxLevel: 1
   - Id: 3001
     Name: KO_YAMIKUMO
     Description: Shadow Hiding

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 605 - 28
db/re/skill_db.yml


+ 5 - 0
db/re/skill_nocast_db.txt

@@ -62,6 +62,7 @@
 2284,4	//SC_FATALMENACE
 2300,4	//SC_DIMENSIONDOOR
 5063,4	//WE_CALLALLFAMILY
+462,4	//SL_KAIZEL
 
 //----------------------------------------------------------------------------
 // Battlegrounds
@@ -100,6 +101,8 @@
 2284,8	//SC_FATALMENACE
 2300,8	//SC_DIMENSIONDOOR
 5063,8	//WE_CALLALLFAMILY
+5023,8	//SU_LOPE
+462,8	//SL_KAIZEL
 
 //----------------------------------------------------------------------------
 // Mixed
@@ -184,6 +187,8 @@
 //----------------------------------------------------------------------------
 426,256 //TK_HIGHJUMP
 290,256	//SA_ABRACADABRA
+5023,256	//SU_LOPE
+462,256	//SL_KAIZEL
 
 //----------------------------------------------------------------------------
 // Zone 5 - Sealed Shrine

+ 20 - 20
db/re/skill_tree.txt

@@ -6203,7 +6203,7 @@
 4239,444,1,443,9,0,0,0,0,0,0,0,0 //SG_FUSION#Union of the Sun, Moon and Stars#
 4239,2574,5,2576,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFMOON##
 4239,2575,3,2588,1,0,0,0,0,0,0,0,0 //SJ_LUNARSTANCE##
-4239,2576,7,2579,7,0,0,0,0,0,0,0,0 //SJ_FULLMOONKICK##
+4239,2576,10,2579,7,0,0,0,0,0,0,0,0 //SJ_FULLMOONKICK##
 4239,2577,5,2584,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFSTAR##
 4239,2578,3,2588,1,0,0,0,0,0,0,0,0 //SJ_STARSTANCE##
 4239,2579,7,2575,1,0,0,0,0,0,0,0,0 //SJ_NEWMOONKICK##
@@ -6211,7 +6211,7 @@
 4239,2581,5,2582,5,2583,3,0,0,0,0,0,0 //SJ_STAREMPEROR##
 4239,2582,5,2583,1,0,0,0,0,0,0,0,0 //SJ_NOVAEXPLOSING##
 4239,2583,3,2575,3,2578,3,2591,3,0,0,0,0 //SJ_UNIVERSESTANCE##
-4239,2584,7,2580,7,0,0,0,0,0,0,0,0 //SJ_FALLINGSTAR##
+4239,2584,10,2580,7,0,0,0,0,0,0,0,0 //SJ_FALLINGSTAR##
 4239,2585,1,2583,1,0,0,0,0,0,0,0,0 //SJ_GRAVITYCONTROL##
 4239,2586,5,2581,3,2588,3,0,0,0,0,0,0 //SJ_BOOKOFDIMENSION##
 4239,2587,5,2581,3,2588,3,0,0,0,0,0,0 //SJ_BOOKOFCREATINGSTAR##
@@ -6219,7 +6219,7 @@
 4239,2589,1,441,10,0,0,0,0,0,0,0,0 //SJ_PURIFY##
 4239,2590,5,2592,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFSUN##
 4239,2591,3,2588,1,0,0,0,0,0,0,0,0 //SJ_SUNSTANCE##
-4239,2592,7,2593,7,0,0,0,0,0,0,0,0 //SJ_SOLARBURST##
+4239,2592,10,2593,7,0,0,0,0,0,0,0,0 //SJ_SOLARBURST##
 4239,2593,7,2591,1,0,0,0,0,0,0,0,0 //SJ_PROMINENCEKICK##
 4239,410,1,0,0,0,0,0,0,0,0,0,0 //WE_CALLBABY#Call Baby#
 
@@ -6274,13 +6274,13 @@
 4240,2597,5,2605,5,0,0,0,0,0,0,0,0 //SP_SOULSHADOW##
 4240,2598,5,2608,2,0,0,0,0,0,0,0,0 //SP_SOULFALCON##
 4240,2599,5,2605,5,0,0,0,0,0,0,0,0 //SP_SOULFAIRY##
-4240,2600,5,2601,3,0,0,0,0,0,0,0,0 //SP_CURSEEXPLOSION##
+4240,2600,10,2601,3,0,0,0,0,0,0,0,0 //SP_CURSEEXPLOSION##
 4240,2601,5,2607,3,0,0,0,0,0,0,0,0 //SP_SOULCURSE##
-4240,2602,5,2603,1,0,0,0,0,0,0,0,0 //SP_SPA##
+4240,2602,10,2603,1,0,0,0,0,0,0,0,0 //SP_SPA##
 4240,2603,5,2607,3,0,0,0,0,0,0,0,0 //SP_SHA##
-4240,2604,7,2602,3,0,0,0,0,0,0,0,0 //SP_SWHOO##
+4240,2604,10,2602,3,0,0,0,0,0,0,0,0 //SP_SWHOO##
 4240,2605,7,2611,3,0,0,0,0,0,0,0,0 //SP_SOULUNITY##
-4240,2606,5,2602,5,2603,5,0,0,0,0,0,0 //SP_SOULDIVISION##
+4240,2606,5,2602,10,2603,5,0,0,0,0,0,0 //SP_SOULDIVISION##
 4240,2607,5,2609,1,0,0,0,0,0,0,0,0 //SP_SOULREAPER##
 4240,2608,3,2611,3,2612,3,0,0,0,0,0,0 //SP_SOULREVOLVE##
 4240,2609,5,0,0,0,0,0,0,0,0,0,0 //SP_SOULCOLLECT##
@@ -6329,7 +6329,7 @@
 4241,444,1,443,9,0,0,0,0,0,0,0,0 //SG_FUSION#Union of the Sun, Moon and Stars#
 4241,2574,5,2576,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFMOON##
 4241,2575,3,2588,1,0,0,0,0,0,0,0,0 //SJ_LUNARSTANCE##
-4241,2576,7,2579,7,0,0,0,0,0,0,0,0 //SJ_FULLMOONKICK##
+4241,2576,10,2579,7,0,0,0,0,0,0,0,0 //SJ_FULLMOONKICK##
 4241,2577,5,2584,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFSTAR##
 4241,2578,3,2588,1,0,0,0,0,0,0,0,0 //SJ_STARSTANCE##
 4241,2579,7,2575,1,0,0,0,0,0,0,0,0 //SJ_NEWMOONKICK##
@@ -6337,7 +6337,7 @@
 4241,2581,5,2582,5,2583,3,0,0,0,0,0,0 //SJ_STAREMPEROR##
 4241,2582,5,2583,1,0,0,0,0,0,0,0,0 //SJ_NOVAEXPLOSING##
 4241,2583,3,2575,3,2578,3,2591,3,0,0,0,0 //SJ_UNIVERSESTANCE##
-4241,2584,7,2580,7,0,0,0,0,0,0,0,0 //SJ_FALLINGSTAR##
+4241,2584,10,2580,7,0,0,0,0,0,0,0,0 //SJ_FALLINGSTAR##
 4241,2585,1,2583,1,0,0,0,0,0,0,0,0 //SJ_GRAVITYCONTROL##
 4241,2586,5,2581,3,2588,3,0,0,0,0,0,0 //SJ_BOOKOFDIMENSION##
 4241,2587,5,2581,3,2588,3,0,0,0,0,0,0 //SJ_BOOKOFCREATINGSTAR##
@@ -6345,7 +6345,7 @@
 4241,2589,1,441,10,0,0,0,0,0,0,0,0 //SJ_PURIFY##
 4241,2590,5,2592,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFSUN##
 4241,2591,3,2588,1,0,0,0,0,0,0,0,0 //SJ_SUNSTANCE##
-4241,2592,7,2593,7,0,0,0,0,0,0,0,0 //SJ_SOLARBURST##
+4241,2592,10,2593,7,0,0,0,0,0,0,0,0 //SJ_SOLARBURST##
 4241,2593,7,2591,1,0,0,0,0,0,0,0,0 //SJ_PROMINENCEKICK##
 4241,408,1,0,0,0,0,0,0,0,0,0,0 //WE_BABY#Baby#
 4241,409,1,0,0,0,0,0,0,0,0,0,0 //WE_CALLPARENT#Call Parent#
@@ -6402,13 +6402,13 @@
 4242,2597,5,2605,5,0,0,0,0,0,0,0,0 //SP_SOULSHADOW##
 4242,2598,5,2608,2,0,0,0,0,0,0,0,0 //SP_SOULFALCON##
 4242,2599,5,2605,5,0,0,0,0,0,0,0,0 //SP_SOULFAIRY##
-4242,2600,5,2601,3,0,0,0,0,0,0,0,0 //SP_CURSEEXPLOSION##
+4242,2600,10,2601,3,0,0,0,0,0,0,0,0 //SP_CURSEEXPLOSION##
 4242,2601,5,2607,3,0,0,0,0,0,0,0,0 //SP_SOULCURSE##
-4242,2602,5,2603,1,0,0,0,0,0,0,0,0 //SP_SPA##
+4242,2602,10,2603,1,0,0,0,0,0,0,0,0 //SP_SPA##
 4242,2603,5,2607,3,0,0,0,0,0,0,0,0 //SP_SHA##
-4242,2604,7,2602,3,0,0,0,0,0,0,0,0 //SP_SWHOO##
+4242,2604,10,2602,3,0,0,0,0,0,0,0,0 //SP_SWHOO##
 4242,2605,7,2611,3,0,0,0,0,0,0,0,0 //SP_SOULUNITY##
-4242,2606,5,2602,5,2603,5,0,0,0,0,0,0 //SP_SOULDIVISION##
+4242,2606,5,2602,10,2603,5,0,0,0,0,0,0 //SP_SOULDIVISION##
 4242,2607,5,2609,1,0,0,0,0,0,0,0,0 //SP_SOULREAPER##
 4242,2608,3,2611,3,2612,3,0,0,0,0,0,0 //SP_SOULREVOLVE##
 4242,2609,5,0,0,0,0,0,0,0,0,0,0 //SP_SOULCOLLECT##
@@ -6459,7 +6459,7 @@
 4243,444,1,443,9,0,0,0,0,0,0,0,0 //SG_FUSION#Union of the Sun, Moon and Stars#
 4243,2574,5,2576,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFMOON##
 4243,2575,3,2588,1,0,0,0,0,0,0,0,0 //SJ_LUNARSTANCE##
-4243,2576,7,2579,7,0,0,0,0,0,0,0,0 //SJ_FULLMOONKICK##
+4243,2576,10,2579,7,0,0,0,0,0,0,0,0 //SJ_FULLMOONKICK##
 4243,2577,5,2584,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFSTAR##
 4243,2578,3,2588,1,0,0,0,0,0,0,0,0 //SJ_STARSTANCE##
 4243,2579,7,2575,1,0,0,0,0,0,0,0,0 //SJ_NEWMOONKICK##
@@ -6467,7 +6467,7 @@
 4243,2581,5,2582,5,2583,3,0,0,0,0,0,0 //SJ_STAREMPEROR##
 4243,2582,5,2583,1,0,0,0,0,0,0,0,0 //SJ_NOVAEXPLOSING##
 4243,2583,3,2575,3,2578,3,2591,3,0,0,0,0 //SJ_UNIVERSESTANCE##
-4243,2584,7,2580,7,0,0,0,0,0,0,0,0 //SJ_FALLINGSTAR##
+4243,2584,10,2580,7,0,0,0,0,0,0,0,0 //SJ_FALLINGSTAR##
 4243,2585,1,2583,1,0,0,0,0,0,0,0,0 //SJ_GRAVITYCONTROL##
 4243,2586,5,2581,3,2588,3,0,0,0,0,0,0 //SJ_BOOKOFDIMENSION##
 4243,2587,5,2581,3,2588,3,0,0,0,0,0,0 //SJ_BOOKOFCREATINGSTAR##
@@ -6475,7 +6475,7 @@
 4243,2589,1,441,10,0,0,0,0,0,0,0,0 //SJ_PURIFY##
 4243,2590,5,2592,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFSUN##
 4243,2591,3,2588,1,0,0,0,0,0,0,0,0 //SJ_SUNSTANCE##
-4243,2592,7,2593,7,0,0,0,0,0,0,0,0 //SJ_SOLARBURST##
+4243,2592,10,2593,7,0,0,0,0,0,0,0,0 //SJ_SOLARBURST##
 4243,2593,7,2591,1,0,0,0,0,0,0,0,0 //SJ_PROMINENCEKICK##
 4243,410,1,0,0,0,0,0,0,0,0,0,0 //WE_CALLBABY#Call Baby#
 
@@ -6519,7 +6519,7 @@
 4244,444,1,443,9,0,0,0,0,0,0,0,0 //SG_FUSION#Union of the Sun, Moon and Stars#
 4244,2574,5,2576,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFMOON##
 4244,2575,3,2588,1,0,0,0,0,0,0,0,0 //SJ_LUNARSTANCE##
-4244,2576,7,2579,7,0,0,0,0,0,0,0,0 //SJ_FULLMOONKICK##
+4244,2576,10,2579,7,0,0,0,0,0,0,0,0 //SJ_FULLMOONKICK##
 4244,2577,5,2584,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFSTAR##
 4244,2578,3,2588,1,0,0,0,0,0,0,0,0 //SJ_STARSTANCE##
 4244,2579,7,2575,1,0,0,0,0,0,0,0,0 //SJ_NEWMOONKICK##
@@ -6527,7 +6527,7 @@
 4244,2581,5,2582,5,2583,3,0,0,0,0,0,0 //SJ_STAREMPEROR##
 4244,2582,5,2583,1,0,0,0,0,0,0,0,0 //SJ_NOVAEXPLOSING##
 4244,2583,3,2575,3,2578,3,2591,3,0,0,0,0 //SJ_UNIVERSESTANCE##
-4244,2584,7,2580,7,0,0,0,0,0,0,0,0 //SJ_FALLINGSTAR##
+4244,2584,10,2580,7,0,0,0,0,0,0,0,0 //SJ_FALLINGSTAR##
 4244,2585,1,2583,1,0,0,0,0,0,0,0,0 //SJ_GRAVITYCONTROL##
 4244,2586,5,2581,3,2588,3,0,0,0,0,0,0 //SJ_BOOKOFDIMENSION##
 4244,2587,5,2581,3,2588,3,0,0,0,0,0,0 //SJ_BOOKOFCREATINGSTAR##
@@ -6535,7 +6535,7 @@
 4244,2589,1,441,10,0,0,0,0,0,0,0,0 //SJ_PURIFY##
 4244,2590,5,2592,3,0,0,0,0,0,0,0,0 //SJ_LIGHTOFSUN##
 4244,2591,3,2588,1,0,0,0,0,0,0,0,0 //SJ_SUNSTANCE##
-4244,2592,7,2593,7,0,0,0,0,0,0,0,0 //SJ_SOLARBURST##
+4244,2592,10,2593,7,0,0,0,0,0,0,0,0 //SJ_SOLARBURST##
 4244,2593,7,2591,1,0,0,0,0,0,0,0,0 //SJ_PROMINENCEKICK##
 4244,408,1,0,0,0,0,0,0,0,0,0,0 //WE_BABY#Baby#
 4244,409,1,0,0,0,0,0,0,0,0,0,0 //WE_CALLPARENT#Call Parent#

+ 26 - 3
src/map/atcommand.cpp

@@ -1309,7 +1309,7 @@ ACMD_FUNC(heal)
 	}
 
 	if ( hp < 0 && sp <= 0 ) {
-		status_damage(NULL, &sd->bl, -hp, -sp, 0, 0);
+		status_damage(NULL, &sd->bl, -hp, -sp, 0, 0, 0);
 		clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, DMG_ENDURE, 0, false);
 		clif_displaymessage(fd, msg_txt(sd,156)); // HP or/and SP modified.
 		return 0;
@@ -1320,7 +1320,7 @@ ACMD_FUNC(heal)
 		if (hp > 0)
 			status_heal(&sd->bl, hp, 0, 0);
 		else {
-			status_damage(NULL, &sd->bl, -hp, 0, 0, 0);
+			status_damage(NULL, &sd->bl, -hp, 0, 0, 0, 0);
 			clif_damage(&sd->bl,&sd->bl, gettick(), 0, 0, -hp, 0, DMG_ENDURE, 0, false);
 		}
 	}
@@ -1329,7 +1329,7 @@ ACMD_FUNC(heal)
 		if (sp > 0)
 			status_heal(&sd->bl, 0, sp, 0);
 		else
-			status_damage(NULL, &sd->bl, 0, -sp, 0, 0);
+			status_damage(NULL, &sd->bl, 0, -sp, 0, 0, 0);
 	}
 
 	clif_displaymessage(fd, msg_txt(sd,156)); // HP or/and SP modified.
@@ -3490,6 +3490,28 @@ ACMD_FUNC(spiritball)
 	return 0;
 }
 
+ACMD_FUNC(soulball)
+{
+	uint32 max_soulballs = min(ARRAYLENGTH(sd->soul_timer), 0x7FFF);
+	int number;
+	nullpo_retr(-1, sd);
+
+	if (!message || !*message || (number = atoi(message)) < 0 || number > max_soulballs) {
+		char msg[CHAT_SIZE_MAX];
+		safesnprintf(msg, sizeof(msg), "Usage: @soulball <number: 0-%d>", max_soulballs);
+		clif_displaymessage(fd, msg);
+		return -1;
+	}
+
+	if (sd->soulball > 0)
+		pc_delsoulball(sd, sd->soulball, 1);
+	sd->soulball = number;
+	clif_soulball(sd);
+	// no message, player can see the difference
+
+	return 0;
+}
+
 /*==========================================
  *
  *------------------------------------------*/
@@ -10289,6 +10311,7 @@ void atcommand_basecommands(void) {
 		ACMD_DEF(questskill),
 		ACMD_DEF(lostskill),
 		ACMD_DEF(spiritball),
+		ACMD_DEF(soulball),
 		ACMD_DEF(party),
 		ACMD_DEF(guild),
 		ACMD_DEF(breakguild),

+ 151 - 19
src/map/battle.cpp

@@ -268,9 +268,9 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int
 void battle_damage(struct block_list *src, struct block_list *target, int64 damage, t_tick delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, t_tick tick, bool isspdamage) {
 	map_freeblock_lock();
 	if (isspdamage)
-		status_fix_spdamage(src, target, damage, delay);
+		status_fix_spdamage(src, target, damage, delay, skill_id);
 	else
-		status_fix_damage(src, target, damage, delay); // We have to separate here between reflect damage and others [icescope]
+		status_fix_damage(src, target, damage, delay, skill_id); // We have to separate here between reflect damage and others [icescope]
 	if (attack_type && !status_isdead(target) && additional_effects)
 		skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, tick);
 	if (dmg_lv > ATK_BLOCK && attack_type)
@@ -316,7 +316,7 @@ TIMER_FUNC(battle_delay_damage_sub){
 				battle_damage(src, target, dat->damage, dat->delay, dat->skill_lv, dat->skill_id, dat->dmg_lv, dat->attack_type, dat->additional_effects, tick, dat->isspdamage);
 			} else if( !src && dat->skill_id == CR_REFLECTSHIELD ) { // it was monster reflected damage, and the monster died, we pass the damage to the character as expected
 				map_freeblock_lock();
-				status_fix_damage(target, target, dat->damage, dat->delay);
+				status_fix_damage(target, target, dat->damage, dat->delay, dat->skill_id);
 				map_freeblock_unlock();
 			}
 		}
@@ -576,6 +576,22 @@ int64 battle_attr_fix(struct block_list *src, struct block_list *target, int64 d
 					damage += (int64)(damage * tsc->data[SC_ANTI_M_BLAST]->val2 / 100);
 #endif
 				break;
+			case ELE_DARK:
+				if (tsc->data[SC_SOULCURSE]) {
+					if (status_get_class_(target) == CLASS_BOSS)
+#ifdef RENEWAL
+						ratio += 20;
+#else
+						damage += (int64)(damage * 20 / 100);
+#endif
+					else
+#ifdef RENEWAL
+						ratio += 100;
+#else
+						damage *= 2;
+#endif
+				}
+				break;
 		}
 	}
 
@@ -1057,7 +1073,7 @@ bool battle_check_sc(struct block_list *src, struct block_list *target, struct s
 int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Damage *d,int64 damage,uint16 skill_id,uint16 skill_lv)
 {
 	struct map_session_data *sd = NULL;
-	struct status_change *sc;
+	struct status_change *sc, *tsc;
 	struct status_change_entry *sce;
 	int div_ = d->div_, flag = d->flag;
 
@@ -1096,12 +1112,19 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 	if (sc && sc->data[SC_MAXPAIN])
 		return 0;
 
+	switch (skill_id) {
 #ifndef RENEWAL
-	if (skill_id == PA_PRESSURE
-		|| skill_id == HW_GRAVITATION
-		)
-		return damage; //These skills bypass everything else.
+    case PA_PRESSURE:
+		case HW_GRAVITATION:
 #endif
+		case SP_SOULEXPLOSION:
+			return damage; //These skills bypass everything else.
+  }
+
+	// Nothing can reduce the damage, but Safety Wall and Millennium Shield can block it completely.
+	// So can defense sphere's but what the heck is that??? [Rytech]
+	if (skill_id == SJ_NOVAEXPLOSING && !(sc && (sc->data[SC_SAFETYWALL] || sc->data[SC_MILLENNIUMSHIELD])))
+		return damage;
 
 	if( sc && sc->count ) { // SC_* that reduce damage to 0.
 #ifdef RENEWAL
@@ -1109,7 +1132,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 #else
 		if (sc->data[SC_BASILICA]
 #endif
-			&& !status_bl_has_mode(src,MD_STATUS_IMMUNE) ) {
+			&& !status_bl_has_mode(src,MD_STATUS_IMMUNE) && skill_id != SP_SOULEXPLOSION ) {
 			d->dmg_lv = ATK_BLOCK;
 			return 0;
 		}
@@ -1137,7 +1160,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		if (!battle_check_sc(src, bl, sc, d, damage, skill_id, skill_lv))
 			return 0;
 
-		if (sc->data[SC__MANHOLE] || (src->type == BL_PC && sc->data[SC_KINGS_GRACE])) {
+		if (sc->data[SC__MANHOLE] || (src->type == BL_PC && sc->data[SC_KINGS_GRACE]) || sc->data[SC_GRAVITYCONTROL]) {
 			d->dmg_lv = ATK_BLOCK;
 			return 0;
 		}
@@ -1481,6 +1504,26 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 				status_change_end(bl, SC_TUNAPARTY, INVALID_TIMER);
 		}
 
+		if ((sce = sc->data[SC_DIMENSION1]) && damage > 0) {
+			sce->val2 -= (int)cap_value(damage, INT_MIN, INT_MAX);
+			if (sce->val2 >= 0)
+				damage = 0;
+			else
+				damage = -sce->val2;
+			if (sce->val2 <= 0)
+				status_change_end(bl, SC_DIMENSION1, INVALID_TIMER);
+		}
+
+		if ((sce = sc->data[SC_DIMENSION2]) && damage > 0) {
+			sce->val2 -= (int)cap_value(damage, INT_MIN, INT_MAX);
+			if (sce->val2 >= 0)
+				damage = 0;
+			else
+				damage = -sce->val2;
+			if (sce->val2 <= 0)
+				status_change_end(bl, SC_DIMENSION2, INVALID_TIMER);
+		}
+
 		if( sc->data[SC_MEIKYOUSISUI] && rnd()%100 < 40 ) // custom value
 			damage = 0;
 
@@ -1527,6 +1570,7 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 
 	//SC effects from caster side.
 	sc = status_get_sc(src);
+	tsc = status_get_sc(src);
 
 	if (sc && sc->count) {
 		if( sc->data[SC_INVINCIBLE] && !sc->data[SC_INVINCIBLEOFF] )
@@ -1579,6 +1623,19 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 		}
 	} //End of caster SC_ check
 
+	if (tsc && tsc->count) {
+		struct map_session_data *tsd = (struct map_session_data *)src;
+
+		if (tsc->data[SC_INVINCIBLE] && !tsc->data[SC_INVINCIBLEOFF])
+			damage += damage * 75 / 100;
+		if (tsd && (sce = tsc->data[SC_SOULREAPER])) {
+			if (rnd()%100 < sce->val2 && tsd->soulball < MAX_SOUL_BALL) {
+				clif_specialeffect(src, 1208, AREA);
+				pc_addsoulball(tsd, 0, 5 + 3 * pc_checkskill(tsd, SP_SOULENERGY));
+			}
+		}
+	}
+
 	//PK damage rates
 	if (battle_config.pk_mode && sd && bl->type == BL_PC && damage && map_getmapflag(bl->m, MF_PVP)) {
 		if (flag & BF_SKILL) { //Skills get a different reduction than non-skills. [Skotlex]
@@ -2880,6 +2937,9 @@ static int battle_get_weapon_element(struct Damage* wd, struct block_list *src,
 			if (sc && sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 4)
 				element = ELE_HOLY;
 			break;
+		case SJ_PROMINENCEKICK:
+ 				element = ELE_FIRE;
+ 			break;
 		case RL_H_MINE:
 			if (sd && sd->flicker) //Force RL_H_MINE deals fire damage if activated by RL_FLICKER
 				element = ELE_FIRE;
@@ -4424,8 +4484,12 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
 		case KO_SETSUDAN:
 			skillratio += 100 * (skill_lv - 1);
 			RE_LVL_DMOD(100);
-			if(tsc && tsc->data[SC_SPIRIT])
-				skillratio += 200 * tsc->data[SC_SPIRIT]->val1;
+			if (tsc) {
+				struct status_change_entry *sce;
+
+				if ((sce = tsc->data[SC_SPIRIT]) || (sce = tsc->data[SC_SOULGOLEM]) || (sce = tsc->data[SC_SOULSHADOW]) || (sce = tsc->data[SC_SOULFALCON]) || (sce = tsc->data[SC_SOULFAIRY])) // Bonus damage added when target is soul linked.
+					skillratio += 200 * sce->val1;
+			}
 			break;
 		case KO_BAKURETSU:
 			skillratio += -100 + (sd ? pc_checkskill(sd,NJ_TOBIDOUGU) : 1) * (50 + sstatus->dex / 4) * skill_lv * 4 / 10;
@@ -4540,6 +4604,34 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
 			if (sd && pc_checkskill(sd, SU_SPIRITOFLIFE))
 				skillratio += skillratio * status_get_hp(src) / status_get_max_hp(src);
 			break;
+		case SJ_FULLMOONKICK:
+			skillratio += 1000 + 100 * skill_lv;
+			RE_LVL_DMOD(100);
+			if (sc && sc->data[SC_LIGHTOFMOON])
+				skillratio += skillratio * sc->data[SC_LIGHTOFMOON]->val2 / 100;
+			break;
+		case SJ_NEWMOONKICK:
+			skillratio += 600 + 100 * skill_lv;
+			break;
+		case SJ_STAREMPEROR:
+			skillratio += 700 + 200 * skill_lv;
+			break;
+		case SJ_SOLARBURST:
+			skillratio += 900 + 220 * skill_lv;
+			RE_LVL_DMOD(100);
+			if (sc && sc->data[SC_LIGHTOFSUN])
+				skillratio += skillratio * sc->data[SC_LIGHTOFSUN]->val2 / 100;
+			break;
+		case SJ_PROMINENCEKICK:
+				skillratio += 50 + 50 * skill_lv;
+			break;
+		case SJ_FALLINGSTAR_ATK:
+		case SJ_FALLINGSTAR_ATK2:
+			skillratio += 100 * skill_lv;
+			RE_LVL_DMOD(100);
+			if (sc && sc->data[SC_LIGHTOFSTAR])
+				skillratio += skillratio * sc->data[SC_LIGHTOFSTAR]->val2 / 100;
+			break;
 	}
 	return skillratio;
 }
@@ -5245,7 +5337,7 @@ static void battle_calc_weapon_final_atk_modifiers(struct Damage* wd, struct blo
 		)
 	{
 		ATK_RATER(wd->damage, 50)
-		status_fix_damage(target,src,wd->damage,clif_damage(target,src,gettick(),0,0,wd->damage,0,DMG_NORMAL,0,false));
+		status_fix_damage(target,src,wd->damage,clif_damage(target,src,gettick(),0,0,wd->damage,0,DMG_NORMAL,0,false),ST_REJECTSWORD);
 		clif_skill_nodamage(target,target,ST_REJECTSWORD,tsc->data[SC_REJECTSWORD]->val1,1);
 		if( --(tsc->data[SC_REJECTSWORD]->val3) <= 0 )
 			status_change_end(target, SC_REJECTSWORD, INVALID_TIMER);
@@ -5262,8 +5354,8 @@ static void battle_calc_weapon_final_atk_modifiers(struct Damage* wd, struct blo
 		clif_skill_damage(target, src, gettick(), status_get_amotion(src), 0, rdamage,
 			1, SR_CRESCENTELBOW_AUTOSPELL, tsc->data[SC_CRESCENTELBOW]->val1, DMG_SINGLE); // This is how official does
 		clif_damage(src, target, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, DMG_NORMAL, 0, false);
-		status_damage(target, src, rdamage, 0, 0, 0);
-		status_damage(src, target, rdamage/10, 0, 0, 1);
+		status_damage(target, src, rdamage, 0, 0, 0, 0);
+		status_damage(src, target, rdamage/10, 0, 0, 1, 0);
 		status_change_end(target, SC_CRESCENTELBOW, INVALID_TIMER);
 	}
 
@@ -5983,6 +6075,10 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 					MATK_ADD(sstatus->matk_min);
 				}
 
+				if (sd) { // Soul energy spheres adds MATK.
+					MATK_ADD(3*sd->soulball);
+				}
+
 				if (nk[NK_SPLASHSPLIT]) { // Divide MATK in case of multiple targets skill
 					if (mflag>0)
 						ad.damage /= mflag;
@@ -6407,6 +6503,23 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						i = cap_value(i, 1, 4);
 						skillratio = 2500 + ((skill_lv - i + 1) * 500);
 						break;
+					case SP_CURSEEXPLOSION:
+						if (tsc && tsc->data[SC_SOULCURSE])
+							skillratio += 1400 + 200 * skill_lv;
+						else
+							skillratio += 300 + 100 * skill_lv;
+						break;
+					case SP_SPA:
+						skillratio += 400 + 250 * skill_lv;
+						RE_LVL_DMOD(100);
+						break;
+					case SP_SHA:
+						skillratio += -100 + 5 * skill_lv;
+						break;
+					case SP_SWHOO:
+						skillratio += 1000 + 200 * skill_lv;
+						RE_LVL_DMOD(100);
+						break;
 				}
 
 				if (sc) {// Insignia's increases the damage of offensive magic by a fixed percentage depending on the element.
@@ -6880,6 +6993,16 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 		case SU_SV_ROOTTWIST_ATK:
 			md.damage = 100;
 			break;
+		case SP_SOULEXPLOSION:
+			md.damage = tstatus->hp * (20 + 10 * skill_lv) / 100;
+			break;
+		case SJ_NOVAEXPLOSING:
+			// (Base ATK + Weapon ATK) * Ratio
+			md.damage = (sstatus->batk + sstatus->rhw.atk) * (200 + 100 * skill_lv) / 100;
+
+			// Additional Damage
+			md.damage += sstatus->max_hp / (6 - min(5, skill_lv)) + status_get_max_sp(src) * (2 * skill_lv);
+			break;
 	}
 
 	if (nk[NK_SPLASHSPLIT]) { // Divide ATK among targets
@@ -7311,7 +7434,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) {
 		if( amotion )
 			battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true,false);
 		else
-			status_fix_damage(src,bl,damage,0);
+			status_fix_damage(src,bl,damage,0,LG_REFLECTDAMAGE);
 		clif_damage(bl,bl,tick,amotion,dmotion,damage,1,DMG_ENDURE,0,false);
 		skill_additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
 		map_freeblock_unlock();
@@ -7397,6 +7520,8 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 			status_change_end(src, SC_CLOAKING, INVALID_TIMER);
 		else if (sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4 & 2))
 			status_change_end(src, SC_CLOAKINGEXCEED, INVALID_TIMER);
+		else if (sc->data[SC_NEWMOON] && --(sc->data[SC_NEWMOON]->val2) <= 0)
+			status_change_end(src, SC_NEWMOON, INVALID_TIMER);
 	}
 	if (tsc && tsc->data[SC_AUTOCOUNTER] && status_check_skilluse(target, src, KN_AUTOCOUNTER, 1)) {
 		uint8 dir = map_calc_dir(target,src->x,src->y);
@@ -7615,7 +7740,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 					}
 
 					clif_damage(d_bl, d_bl, gettick(), wd.amotion, wd.dmotion, damage, 1, DMG_NORMAL, 0, false);
-					status_fix_damage(NULL, d_bl, damage, 0);
+					status_fix_damage(NULL, d_bl, damage, 0, CR_DEVOTION);
 				}
 			}
 			else
@@ -7634,7 +7759,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 
 			if (e_bl && !status_isdead(e_bl)) {
 				clif_damage(e_bl, e_bl, tick, 0, 0, damage, wd.div_, DMG_NORMAL, 0, false);
-				status_fix_damage(NULL, e_bl, damage, 0);
+				status_fix_damage(NULL, e_bl, damage, 0, EL_WATER_SCREEN);
 			}
 		}
 	}
@@ -7737,7 +7862,14 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
 				clif_status_change(src, EFST_POSTDELAY, 1, skill_delayfix(src, r_skill, r_lv), 0, 0, 1);
 			}
 		}
-
+		if (wd.flag&BF_WEAPON && sc && sc->data[SC_FALLINGSTAR] && rand()%100 < sc->data[SC_FALLINGSTAR]->val2) {
+			if (sd)
+				sd->state.autocast = 1;
+			if (status_charge(src, 0, skill_get_sp(SJ_FALLINGSTAR_ATK, sc->data[SC_FALLINGSTAR]->val1)))
+				skill_castend_nodamage_id(src, src, SJ_FALLINGSTAR_ATK, sc->data[SC_FALLINGSTAR]->val1, tick, flag);
+			if (sd)
+				sd->state.autocast = 0;
+		}
 		if (wd.flag & BF_WEAPON && src != target && damage > 0) {
 			if (battle_config.left_cardfix_to_right)
 				battle_drain(sd, target, wd.damage, wd.damage, tstatus->race, tstatus->class_);

+ 65 - 4
src/map/clif.cpp

@@ -1387,6 +1387,29 @@ static void clif_spiritcharm_single(int fd, struct map_session_data *sd)
 	WFIFOSET(fd, packet_len(0x08cf));
 }
 
+
+/// Notifies the client of an object's souls.
+/// Note: Spirit spheres and Soul spheres work on
+/// seprate systems officially, but both send out
+/// the same packet which leads to confusion on how
+/// much soul energy a Soul Reaper acturally has
+/// should the player also have spirit spheres.
+/// They will likely create a new packet for this soon
+/// to seprate the animations for spirit and soul spheres.
+/// For now well use this and replace it later when possible. [Rytech]
+///
+/// 01d0 <id>.L <amount>.W (ZC_SPIRITS)
+/// 01e1 <id>.L <amount>.W (ZC_SPIRITS2)
+static void clif_soulball_single(int fd, struct map_session_data *sd)
+{
+	WFIFOHEAD(fd, packet_len(0x1d0));
+	WFIFOW(fd,0)=0x1d0;
+	WFIFOL(fd,2)=sd->bl.id;
+	WFIFOW(fd,6)=sd->soulball;
+	WFIFOSET(fd, packet_len(0x1d0));
+}
+
+
 /*==========================================
  * Run when player changes map / refreshes
  * Tells its client to display all weather settings being used by this map
@@ -1476,6 +1499,8 @@ int clif_spawn(struct block_list *bl)
 
 			if (sd->spiritball > 0)
 				clif_spiritball(&sd->bl);
+			if (sd->soulball > 0)
+				clif_soulball(sd);
 			if(sd->state.size==SZ_BIG) // tiny/big players [Valaris]
 				clif_specialeffect(bl,EF_GIANTBODY2,AREA);
 			else if(sd->state.size==SZ_MEDIUM)
@@ -4608,6 +4633,33 @@ void clif_storageclose(struct map_session_data* sd)
 	WFIFOSET(fd,packet_len(0xf8));
 }
 
+
+/// Notifies clients in an area of an object's souls.
+/// Note: Spirit spheres and Soul spheres work on
+/// seprate systems officially, but both send out
+/// the same packet which leads to confusion on how
+/// much soul energy a Soul Reaper acturally has
+/// should the player also have spirit spheres.
+/// They will likely create a new packet for this soon
+/// to seprate the animations for spirit and soul spheres.
+/// For now well use this and replace it later when possible. [Rytech]
+/// 
+/// 01d0 <id>.L <amount>.W (ZC_SPIRITS)
+/// 01e1 <id>.L <amount>.W (ZC_SPIRITS2)
+void clif_soulball(struct map_session_data *sd)
+{
+	unsigned char buf[8];
+
+	nullpo_retv(sd);
+
+	WBUFW(buf,0)=0x1d0;
+	WBUFL(buf,2)=sd->bl.id;
+	WBUFW(buf,6)=sd->soulball;
+	clif_send(buf,packet_len(0x1d0),&sd->bl,AREA);
+	return;
+}
+
+
 /*==========================================
  * Server tells 'sd' player client the abouts of 'dstsd' player
  *------------------------------------------*/
@@ -4629,6 +4681,8 @@ static void clif_getareachar_pc(struct map_session_data* sd,struct map_session_d
 		clif_spiritball_single(sd->fd, dstsd);
 	if (dstsd->spiritcharm_type != CHARM_TYPE_NONE && dstsd->spiritcharm > 0)
 		clif_spiritcharm_single(sd->fd, dstsd);
+	if (dstsd->soulball > 0)
+		clif_soulball_single(sd->fd, dstsd);
 	if( (sd->status.party_id && dstsd->status.party_id == sd->status.party_id) || //Party-mate, or hpdisp setting.
 		(sd->bg_id && sd->bg_id == dstsd->bg_id) || //BattleGround
 		pc_has_permission(sd, PC_PERM_VIEW_HPMETER)
@@ -6027,6 +6081,10 @@ void clif_status_change_sub(struct block_list *bl, int id, int type, int flag, t
 
 	nullpo_retv(bl);
 
+	// Statuses with an infinite duration, but still needs a duration sent to display properly.
+	if (type == EFST_LUNARSTANCE || type == EFST_UNIVERSESTANCE || type == EFST_SUNSTANCE || type == EFST_STARSTANCE)
+		tick = 200;
+
 #if PACKETVER >= 20120618
 	if (flag && battle_config.display_status_timers)
 		WBUFW(buf,0) = 0x983;
@@ -9503,6 +9561,8 @@ void clif_refresh(struct map_session_data *sd)
 		clif_spiritball_single(sd->fd, sd);
 	if (sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0)
 		clif_spiritcharm_single(sd->fd, sd);
+	if (sd->soulball)
+		clif_soulball_single(sd->fd, sd);
 	if (sd->vd.cloth_color)
 		clif_refreshlook(&sd->bl,sd->bl.id,LOOK_CLOTHES_COLOR,sd->vd.cloth_color,SELF);
 	if (sd->vd.body_style)
@@ -10705,7 +10765,7 @@ void clif_parse_LoadEndAck(int fd,struct map_session_data *sd)
 	if(!sd->state.autotrade && mapdata->flag[MF_LOADEVENT]) // Lance
 		npc_script_event(sd, NPCE_LOADMAP);
 
-	if (pc_checkskill(sd, SG_DEVIL) && pc_is_maxjoblv(sd))
+	if (pc_checkskill(sd, SG_DEVIL) && ((sd->class_&MAPID_THIRDMASK) == MAPID_STAR_EMPEROR || pc_is_maxjoblv(sd)))
 		clif_status_load(&sd->bl, EFST_DEVIL1, 1);  //blindness [Komurka]
 
 	if (sd->sc.opt2) //Client loses these on warp.
@@ -10985,7 +11045,7 @@ void clif_parse_QuitGame(int fd, struct map_session_data *sd)
 {
 	/*	Rovert's prevent logout option fixed [Valaris]	*/
 	//int type = RFIFOW(fd,packet_db[RFIFOW(fd,0)].pos[0]);
-	if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC_SUHIDE] &&
+	if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC_SUHIDE] && !sd->sc.data[SC_NEWMOON] &&
 		(!battle_config.prevent_logout || sd->canlog_tick == 0 || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
 	{
 		set_eof(fd);
@@ -11221,7 +11281,8 @@ void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action_type,
 		(sd->sc.data[SC_AUTOCOUNTER] && action_type != 0x07) ||
 		 sd->sc.data[SC_BLADESTOP] ||
 		 sd->sc.data[SC__MANHOLE] ||
-		 sd->sc.data[SC_SUHIDE] ))
+		 sd->sc.data[SC_SUHIDE] ||
+		 sd->sc.data[SC_GRAVITYCONTROL]))
 		return;
 
 	if(action_type != 0x00 && action_type != 0x07)
@@ -11348,7 +11409,7 @@ void clif_parse_Restart(int fd, struct map_session_data *sd)
 		break;
 	case 0x01:
 		/*	Rovert's Prevent logout option - Fixed [Valaris]	*/
-		if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC_SUHIDE] &&
+		if( !sd->sc.data[SC_CLOAKING] && !sd->sc.data[SC_HIDING] && !sd->sc.data[SC_CHASEWALK] && !sd->sc.data[SC_CLOAKINGEXCEED] && !sd->sc.data[SC_SUHIDE] && !sd->sc.data[SC_NEWMOON] &&
 			(!battle_config.prevent_logout || sd->canlog_tick == 0 || DIFF_TICK(gettick(), sd->canlog_tick) > battle_config.prevent_logout) )
 		{	//Send to char-server for character selection.
 			pc_damage_log_clear(sd,0);

+ 1 - 0
src/map/clif.hpp

@@ -714,6 +714,7 @@ void clif_skillunit_update(struct block_list* bl);
 void clif_autospell(struct map_session_data *sd,uint16 skill_lv);
 void clif_devotion(struct block_list *src, struct map_session_data *tsd);
 void clif_spiritball(struct block_list *bl);
+void clif_soulball(struct map_session_data *sd);
 void clif_combo_delay(struct block_list *bl,t_tick wait);
 void clif_bladestop(struct block_list *src, int dst_id, int active);
 void clif_changemapcell(int fd, int16 m, int x, int y, int type, enum send_target target);

+ 4 - 0
src/map/map.cpp

@@ -2146,6 +2146,10 @@ int map_quit(struct map_session_data *sd) {
 			status_change_end(&sd->bl, SC_GLASTHEIM_STATE, INVALID_TIMER);
 			status_change_end(&sd->bl, SC_GLASTHEIM_ITEMDEF, INVALID_TIMER);
 			status_change_end(&sd->bl, SC_GLASTHEIM_HPSP, INVALID_TIMER);
+			status_change_end(&sd->bl, SC_SOULGOLEM, INVALID_TIMER);
+			status_change_end(&sd->bl, SC_SOULSHADOW, INVALID_TIMER);
+			status_change_end(&sd->bl, SC_SOULFALCON, INVALID_TIMER);
+			status_change_end(&sd->bl, SC_SOULFAIRY, INVALID_TIMER);
 		}
 	}
 

+ 147 - 3
src/map/pc.cpp

@@ -505,6 +505,115 @@ void pc_delspiritball(struct map_session_data *sd,int count,int type)
 	}
 }
 
+static TIMER_FUNC(pc_soulball_timer)
+{
+	struct map_session_data *sd;
+
+	if ((sd = (struct map_session_data *)map_id2sd(id)) == nullptr || sd->bl.type != BL_PC)
+		return 1;
+
+	if (sd->soulball <= 0) {
+		ShowError("pc_soulball_timer: %d soulball's available. (aid=%d tid=%d)\n", sd->soulball, sd->status.account_id, tid);
+		sd->soulball = 0;
+		return 0;
+	}
+
+	int i;
+
+	ARR_FIND(0, sd->soulball, i, sd->soul_timer[i] == tid);
+	if (i == sd->soulball) {
+		ShowError("pc_soulball_timer: timer not found (aid=%d tid=%d)\n", sd->status.account_id, tid);
+		return 0;
+	}
+
+	sd->soulball--;
+	if (i != sd->soulball)
+		memmove(sd->soul_timer + i, sd->soul_timer + i + 1, (sd->soulball - i) * sizeof(int));
+	sd->soul_timer[sd->soulball] = INVALID_TIMER;
+	clif_soulball(sd);
+
+	return 0;
+}
+
+/**
+ * Adds a soulball to player for 'interval' ms
+ * @param sd: Player data
+ * @param interval: Duration
+ * @param max: Max amount of soulballs
+ */
+int pc_addsoulball(struct map_session_data *sd, int interval, int max)
+{
+	nullpo_ret(sd);
+
+	max = min(max, MAX_SOUL_BALL);
+	sd->soulball = cap_value(sd->soulball, 0, MAX_SOUL_BALL);
+
+	if (sd->soulball && sd->soulball >= max) {
+		if (sd->soul_timer[0] != INVALID_TIMER)
+			delete_timer(sd->soul_timer[0], pc_soulball_timer);
+		sd->soulball--;
+		if (sd->soulball != 0)
+			memmove(sd->soul_timer + 0, sd->soul_timer + 1, (sd->soulball) * sizeof(int));
+		sd->soul_timer[sd->soulball] = INVALID_TIMER;
+	}
+
+	if (interval > 0) {
+		int tid = add_timer(gettick() + interval, pc_soulball_timer, sd->bl.id, 0), i;
+
+		ARR_FIND(0, sd->soulball, i, sd->soul_timer[i] == INVALID_TIMER || DIFF_TICK(get_timer(tid)->tick, get_timer(sd->soul_timer[i])->tick) < 0);
+		if (i != sd->soulball)
+			memmove(sd->soul_timer + i + 1, sd->soul_timer + i, (sd->soulball - i) * sizeof(int));
+		sd->soul_timer[i] = tid;
+	}
+
+	sd->soulball++;
+	clif_soulball(sd);
+
+	return 0;
+}
+
+/**
+ * Removes number of soulball from player
+ * @param sd: Player data
+ * @param count: Amount to remove
+ * @param type: 1 = doesn't give client effect
+ */
+int pc_delsoulball(struct map_session_data *sd, int count, int type)
+{
+	nullpo_ret(sd);
+
+	if (sd->soulball <= 0) {
+		sd->soulball = 0;
+		return 0;
+	}
+
+	if (count <= 0)
+		return 0;
+
+	if (count > sd->soulball)
+		count = sd->soulball;
+	sd->soulball -= count;
+	if (count > MAX_SKILL_LEVEL)
+		count = MAX_SKILL_LEVEL;
+
+	for (int i = 0; i < count; i++) {
+		if (sd->soul_timer[i] != INVALID_TIMER) {
+			delete_timer(sd->soul_timer[i], pc_soulball_timer);
+			sd->soul_timer[i] = INVALID_TIMER;
+		}
+	}
+
+	for (int i = count; i < MAX_SKILL_LEVEL; i++) {
+		sd->soul_timer[i - count] = sd->soul_timer[i];
+		sd->soul_timer[i] = INVALID_TIMER;
+	}
+
+	if (!type)
+		clif_soulball(sd);
+
+	return 0;
+}
+
 /**
 * Increases a player's fame points and displays a notice to him
 * @param sd Player
@@ -1383,6 +1492,8 @@ bool pc_authok(struct map_session_data *sd, uint32 login_id2, time_t expiration_
 
 	for(i = 0; i < MAX_SPIRITBALL; i++)
 		sd->spirit_timer[i] = INVALID_TIMER;
+	for (i = 0; i < MAX_SOUL_BALL; i++)
+		sd->soul_timer[i] = INVALID_TIMER;
 
 	if (battle_config.item_auto_get)
 		sd->state.autoloot = 10000;
@@ -6016,6 +6127,13 @@ bool pc_memo(struct map_session_data* sd, int pos)
  * @return player skill cooldown
  */
 int pc_get_skillcooldown(struct map_session_data *sd, uint16 skill_id, uint16 skill_lv) {
+	if (skill_id == SJ_NOVAEXPLOSING) {
+		struct status_change *sc = status_get_sc(&sd->bl);
+
+		if (sc && sc->data[SC_DIMENSION])
+			return 0;
+	}
+
 	int cooldown = skill_get_cooldown(skill_id, skill_lv);
 
 	if (cooldown == 0)
@@ -6900,7 +7018,7 @@ int pc_checkjoblevelup(struct map_session_data *sd)
 	clif_updatestatus(sd,SP_SKILLPOINT);
 	status_calc_pc(sd,SCO_FORCE);
 	clif_misceffect(&sd->bl,1);
-	if (pc_checkskill(sd, SG_DEVIL) && pc_is_maxbaselv(sd))
+	if (pc_checkskill(sd, SG_DEVIL) && ((sd->class_&MAPID_THIRDMASK) == MAPID_STAR_EMPEROR || pc_is_maxjoblv(sd)) )
 		clif_status_change(&sd->bl, EFST_DEVIL1, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
 
 	npc_script_event(sd, NPCE_JOBLVUP);
@@ -7456,6 +7574,8 @@ void pc_skillup(struct map_session_data *sd,uint16 skill_id)
 			clif_updatestatus(sd,SP_SKILLPOINT);
 			if( skill_id == GN_REMODELING_CART ) /* cart weight info was updated by status_calc_pc */
 				clif_updatestatus(sd,SP_CARTINFO);
+			if (pc_checkskill(sd, SG_DEVIL) && ((sd->class_&MAPID_THIRDMASK) == MAPID_STAR_EMPEROR || pc_is_maxjoblv(sd)))
+				clif_status_change(&sd->bl, EFST_DEVIL1, 1, 0, 0, 0, 1); //Permanent blind effect from SG_DEVIL.
 			if (!pc_has_permission(sd, PC_PERM_ALL_SKILL)) // may skill everything at any time anyways, and this would cause a huge slowdown
 				clif_skillinfoblock(sd);
 		}
@@ -7684,7 +7804,7 @@ int pc_resetskill(struct map_session_data* sd, int flag)
 		if( pc_is_taekwon_ranker(sd) )
 			return 0;
 
-		if( pc_checkskill(sd, SG_DEVIL) && pc_is_maxjoblv(sd) )
+		if( pc_checkskill(sd, SG_DEVIL) && ((sd->class_&MAPID_THIRDMASK) == MAPID_STAR_EMPEROR || pc_is_maxjoblv(sd)) )
 			clif_status_load(&sd->bl, EFST_DEVIL1, 0); //Remove perma blindness due to skill-reset. [Skotlex]
 		i = sd->sc.option;
 		if( i&OPTION_RIDING && pc_checkskill(sd, KN_RIDING) )
@@ -7802,7 +7922,7 @@ int pc_resethate(struct map_session_data* sd)
 	int i;
 	nullpo_ret(sd);
 
-	for (i=0; i<3; i++)
+	for (i=0; i<MAX_PC_FEELHATE; i++)
 	{
 		sd->hate_mob[i] = -1;
 		pc_setglobalreg(sd, add_str(sg_info[i].hate_var), 0);
@@ -8030,6 +8150,27 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 			sd->devotion[k] = 0;
 		}
 	}
+
+	for (k = 0; k < MAX_STELLAR_MARKS; k++) {
+		if (sd->stellar_mark[k]) {
+			struct map_session_data *smarksd = map_id2sd(sd->stellar_mark[k]);
+
+			if (smarksd)
+				status_change_end(&smarksd->bl, SC_FLASHKICK, INVALID_TIMER);
+			sd->stellar_mark[k] = 0;
+		}
+	}
+
+	for (k = 0; k < MAX_UNITED_SOULS; k++) {
+		if (sd->united_soul[k]) {
+			struct map_session_data *usoulsd = map_id2sd(sd->united_soul[k]);
+
+			if (usoulsd)
+				status_change_end(&usoulsd->bl, SC_SOULUNITY, INVALID_TIMER);
+			sd->united_soul[k] = 0;
+		}
+	}
+
 	if(sd->shadowform_id) { //if we were target of shadowform
 		status_change_end(map_id2bl(sd->shadowform_id), SC__SHADOWFORM, INVALID_TIMER);
 		sd->shadowform_id = 0; //should be remove on status end anyway
@@ -8088,6 +8229,8 @@ int pc_dead(struct map_session_data *sd,struct block_list *src)
 
 	if ( sd->spiritball !=0 )
 		pc_delspiritball(sd,sd->spiritball,0);
+	if (sd->soulball != 0)
+		pc_delsoulball(sd, sd->soulball, 0);
 
 	if (sd->spiritcharm_type != CHARM_TYPE_NONE && sd->spiritcharm > 0)
 		pc_delspiritcharm(sd,sd->spiritcharm,sd->spiritcharm_type);
@@ -13273,6 +13416,7 @@ void do_init_pc(void) {
 	add_timer_func_list(pc_calc_pvprank_timer, "pc_calc_pvprank_timer");
 	add_timer_func_list(pc_autosave, "pc_autosave");
 	add_timer_func_list(pc_spiritball_timer, "pc_spiritball_timer");
+	add_timer_func_list(pc_soulball_timer, "pc_soulball_timer");
 	add_timer_func_list(pc_follow_timer, "pc_follow_timer");
 	add_timer_func_list(pc_endautobonus, "pc_endautobonus");
 	add_timer_func_list(pc_spiritcharm_timer, "pc_spiritcharm_timer");

+ 10 - 0
src/map/pc.hpp

@@ -35,6 +35,9 @@ enum sc_type : int16;
 #define MAX_SPIRITBALL 15 /// Max spirit balls
 #define MAX_DEVOTION 5 /// Max Devotion slots
 #define MAX_SPIRITCHARM 10 /// Max spirit charms
+#define MAX_SOUL_BALL 20 /// Max soul ball
+#define MAX_STELLAR_MARKS 5 /// Max stellar marks
+#define MAX_UNITED_SOULS 12 /// Max united souls
 
 #define LANGTYPE_VAR "#langtype"
 #define CASHPOINT_VAR "#CASHPOINTS"
@@ -534,12 +537,16 @@ struct map_session_data {
 	short spiritcharm; //No. of spirit
 	int spiritcharm_type; //Spirit type
 	int spiritcharm_timer[MAX_SPIRITCHARM];
+	int8 soulball, soulball_old;
+	int soul_timer[MAX_SOUL_BALL];
 
 	unsigned char potion_success_counter; //Potion successes in row counter
 	unsigned char mission_count; //Stores the bounty kill count for TK_MISSION
 	short mission_mobid; //Stores the target mob_id for TK_MISSION
 	int die_counter; //Total number of times you've died
 	int devotion[MAX_DEVOTION]; //Stores the account IDs of chars devoted to.
+	int stellar_mark[MAX_STELLAR_MARKS]; // Stores the account ID's of character's with a stellar mark.
+	int united_soul[MAX_UNITED_SOULS]; // Stores the account ID's of character's who's soul is united.
 
 	int trade_partner;
 	struct s_deal {
@@ -1292,6 +1299,9 @@ void pc_delinvincibletimer(struct map_session_data* sd);
 
 void pc_addspiritball(struct map_session_data *sd,int interval,int max);
 void pc_delspiritball(struct map_session_data *sd,int count,int type);
+int pc_addsoulball(struct map_session_data *sd,int interval,int max);
+int pc_delsoulball(struct map_session_data *sd,int count,int type);
+
 void pc_addfame(struct map_session_data *sd,int count);
 unsigned char pc_famerank(uint32 char_id, int job);
 bool pc_set_hate_mob(struct map_session_data *sd, int pos, struct block_list *bl);

+ 30 - 0
src/map/script_constants.hpp

@@ -1546,6 +1546,35 @@
 	export_constant(SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT);
 	export_constant(SC_ADAPTATION);
 	export_constant(SC_BASILICA_CELL);
+	export_constant(SC_LIGHTOFMOON);
+	export_constant(SC_LIGHTOFSUN);
+	export_constant(SC_LIGHTOFSTAR);
+	export_constant(SC_LUNARSTANCE);
+	export_constant(SC_UNIVERSESTANCE);
+	export_constant(SC_SUNSTANCE);
+	export_constant(SC_FLASHKICK);
+	export_constant(SC_NEWMOON);
+	export_constant(SC_STARSTANCE);
+	export_constant(SC_DIMENSION);
+	export_constant(SC_DIMENSION1);
+	export_constant(SC_DIMENSION2);
+	export_constant(SC_CREATINGSTAR);
+	export_constant(SC_FALLINGSTAR);
+	export_constant(SC_NOVAEXPLOSING);
+	export_constant(SC_GRAVITYCONTROL);
+	export_constant(SC_SOULCOLLECT);
+	export_constant(SC_SOULREAPER);
+	export_constant(SC_SOULUNITY);
+	export_constant(SC_SOULSHADOW);
+	export_constant(SC_SOULFAIRY);
+	export_constant(SC_SOULFALCON);
+	export_constant(SC_SOULGOLEM);
+	export_constant(SC_SOULDIVISION);
+	export_constant(SC_SOULENERGY);
+	export_constant(SC_USE_SKILL_SP_SPA);
+	export_constant(SC_USE_SKILL_SP_SHA);
+	export_constant(SC_SP_SHA);
+	export_constant(SC_SOULCURSE);
 #ifdef RENEWAL
 	export_constant(SC_EXTREMITYFIST2);
 #endif
@@ -7689,6 +7718,7 @@
 	export_constant(UNT_FIRE_RAIN);
 	export_constant(UNT_CATNIPPOWDER);
 	export_constant(UNT_NYANGGRASS);
+	export_constant(UNT_CREATINGSTAR);
 	export_constant(UNT_GD_LEADERSHIP);
 	export_constant(UNT_GD_GLORYWOUNDS);
 	export_constant(UNT_GD_SOULCOLD);

A diferenza do arquivo foi suprimida porque é demasiado grande
+ 513 - 33
src/map/skill.cpp


+ 6 - 0
src/map/skill.hpp

@@ -646,6 +646,10 @@ enum e_require_state : uint8 {
 	ST_ELEMENTALSPIRIT,
 	ST_ELEMENTALSPIRIT2,
 	ST_PECO,
+	ST_SUNSTANCE,
+	ST_MOONSTANCE,
+	ST_STARSTANCE,
+	ST_UNIVERSESTANCE
 };
 
 /// List of Skills
@@ -2227,6 +2231,8 @@ enum e_skill_unit_id : uint16 {
 	UNT_CATNIPPOWDER,
 	UNT_NYANGGRASS,
 
+	UNT_CREATINGSTAR,
+
 	/**
 	 * Guild Auras
 	 **/

+ 304 - 21
src/map/status.cpp

@@ -1065,6 +1065,36 @@ void initChangeTables(void)
 
 	set_sc( WE_CHEERUP				, SC_CHEERUP		, EFST_CHEERUP		, SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
 
+	// Star Emperor
+	set_sc( SJ_LIGHTOFMOON			, SC_LIGHTOFMOON	, EFST_LIGHTOFMOON		, SCB_NONE );
+	set_sc( SJ_LIGHTOFSTAR			, SC_LIGHTOFSTAR	, EFST_LIGHTOFSTAR		, SCB_NONE );
+	set_sc( SJ_LUNARSTANCE			, SC_LUNARSTANCE	, EFST_LUNARSTANCE		, SCB_MAXHP );
+	add_sc( SJ_FULLMOONKICK			, SC_BLIND );
+	set_sc( SJ_STARSTANCE			, SC_STARSTANCE		, EFST_STARSTANCE		, SCB_ASPD );
+	set_sc( SJ_NEWMOONKICK			, SC_NEWMOON		, EFST_NEWMOON			, SCB_NONE );
+	set_sc( SJ_FLASHKICK			, SC_FLASHKICK		, EFST_FLASHKICK		, SCB_NONE );
+	add_sc( SJ_STAREMPEROR			, SC_SILENCE );
+	set_sc( SJ_NOVAEXPLOSING		, SC_NOVAEXPLOSING	, EFST_NOVAEXPLOSING	, SCB_NONE );
+	set_sc( SJ_UNIVERSESTANCE		, SC_UNIVERSESTANCE	, EFST_UNIVERSESTANCE	, SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
+	set_sc( SJ_FALLINGSTAR			, SC_FALLINGSTAR	, EFST_FALLINGSTAR		, SCB_NONE );
+	set_sc( SJ_GRAVITYCONTROL		, SC_GRAVITYCONTROL	, EFST_GRAVITYCONTROL	, SCB_NONE );
+	set_sc( SJ_BOOKOFDIMENSION		, SC_DIMENSION		, EFST_DIMENSION		, SCB_NONE );
+	set_sc( SJ_BOOKOFCREATINGSTAR	, SC_CREATINGSTAR	, EFST_CREATINGSTAR		, SCB_SPEED );
+	set_sc( SJ_LIGHTOFSUN			, SC_LIGHTOFSUN		, EFST_LIGHTOFSUN		, SCB_NONE );
+	set_sc( SJ_SUNSTANCE			, SC_SUNSTANCE		, EFST_SUNSTANCE		, SCB_BATK|SCB_WATK );
+
+	// Soul Reaper
+	set_sc( SP_SOULGOLEM	, SC_SOULGOLEM		, EFST_SOULGOLEM	, SCB_DEF|SCB_MDEF );
+	set_sc( SP_SOULSHADOW	, SC_SOULSHADOW		, EFST_SOULSHADOW	, SCB_ASPD|SCB_CRI );
+	set_sc( SP_SOULFALCON	, SC_SOULFALCON		, EFST_SOULFALCON	, SCB_WATK|SCB_HIT );
+	set_sc( SP_SOULFAIRY	, SC_SOULFAIRY		, EFST_SOULFAIRY	, SCB_MATK );
+	set_sc( SP_SOULCURSE	, SC_SOULCURSE		, EFST_SOULCURSE	, SCB_NONE );
+	set_sc( SP_SHA			, SC_SP_SHA			, EFST_SP_SHA		, SCB_SPEED );
+	set_sc( SP_SOULUNITY	, SC_SOULUNITY		, EFST_SOULUNITY	, SCB_NONE );
+	set_sc( SP_SOULDIVISION	, SC_SOULDIVISION	, EFST_SOULDIVISION	, SCB_NONE );
+	set_sc( SP_SOULREAPER	, SC_SOULREAPER		, EFST_SOULREAPER	, SCB_NONE );
+	set_sc( SP_SOULCOLLECT	, SC_SOULCOLLECT	, EFST_SOULCOLLECT	, SCB_NONE );
+
 	/* Storing the target job rather than simply SC_SPIRIT simplifies code later on */
 	SkillStatusChangeTable[skill_get_index(SL_ALCHEMIST)]	= (sc_type)MAPID_ALCHEMIST,
 	SkillStatusChangeTable[skill_get_index(SL_MONK)]		= (sc_type)MAPID_MONK,
@@ -1511,6 +1541,10 @@ void initChangeTables(void)
 	StatusChangeFlagTable[SC_DORAM_BUF_01] |= SCB_REGEN;
 	StatusChangeFlagTable[SC_DORAM_BUF_02] |= SCB_REGEN;
 
+	// Soul Reaper
+	StatusIconChangeTable[SC_USE_SKILL_SP_SPA] = EFST_USE_SKILL_SP_SPA;
+	StatusIconChangeTable[SC_USE_SKILL_SP_SHA] = EFST_USE_SKILL_SP_SHA;
+
 #ifdef RENEWAL
 	// renewal EDP increases your weapon atk
 	StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
@@ -1616,6 +1650,7 @@ void initChangeTables(void)
 #ifdef RENEWAL
 	StatusChangeStateTable[SC_LONGING]				|= SCS_NOMOVE;
 #endif
+	StatusChangeStateTable[SC_GRAVITYCONTROL]		|= SCS_NOMOVE;
 
 	/* StatusChangeState (SCS_) NOPICKUPITEMS */
 	StatusChangeStateTable[SC_HIDING]				|= SCS_NOPICKITEM;
@@ -1626,6 +1661,7 @@ void initChangeTables(void)
 	StatusChangeStateTable[SC__FEINTBOMB]			|= SCS_NOPICKITEM;
 	StatusChangeStateTable[SC_NOCHAT]				|= SCS_NOPICKITEM|SCS_NOPICKITEMCOND;
 	StatusChangeStateTable[SC_SUHIDE]				|= SCS_NOPICKITEM;
+	StatusChangeStateTable[SC_NEWMOON]				|= SCS_NOPICKITEM;
 
 	/* StatusChangeState (SCS_) NODROPITEMS */
 	StatusChangeStateTable[SC_AUTOCOUNTER]			|= SCS_NODROPITEM;
@@ -1653,6 +1689,7 @@ void initChangeTables(void)
 	StatusChangeStateTable[SC_SATURDAYNIGHTFEVER]	|= SCS_NOCAST;
 	StatusChangeStateTable[SC_CURSEDCIRCLE_TARGET]	|= SCS_NOCAST;
 	StatusChangeStateTable[SC_KINGS_GRACE]			|= SCS_NOCAST;
+	StatusChangeStateTable[SC_GRAVITYCONTROL]		|= SCS_NOCAST;
 
 	/* StatusChangeState (SCS_) NOCHAT (skills) */
 	StatusChangeStateTable[SC_BERSERK]				|= SCS_NOCHAT;
@@ -1818,7 +1855,7 @@ int64 status_charge(struct block_list* bl, int64 hp, int64 sp)
 {
 	if(!(bl->type&BL_CONSUME))
 		return (int)hp+sp; // Assume all was charged so there are no 'not enough' fails.
-	return status_damage(NULL, bl, hp, sp, 0, 3);
+	return status_damage(NULL, bl, hp, sp, 0, 3, 0);
 }
 
 /**
@@ -1837,7 +1874,7 @@ int64 status_charge(struct block_list* bl, int64 hp, int64 sp)
  * Note: HP/SP are integer values, not percentages. Values should be
  *	 calculated either within function call or before
  */
-int status_damage(struct block_list *src,struct block_list *target,int64 dhp, int64 dsp, t_tick walkdelay, int flag)
+int status_damage(struct block_list *src,struct block_list *target,int64 dhp, int64 dsp, t_tick walkdelay, int flag, uint16 skill_id)
 {
 	struct status_data *status;
 	struct status_change *sc;
@@ -1905,6 +1942,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in
 			status_change_end(target, SC_CAMOUFLAGE, INVALID_TIMER);
 			status_change_end(target, SC_DEEPSLEEP, INVALID_TIMER);
 			status_change_end(target, SC_SUHIDE, INVALID_TIMER);
+			status_change_end(target, SC_NEWMOON, INVALID_TIMER);
 			if ((sce=sc->data[SC_ENDURE]) && !sce->val4) {
 				/** [Skotlex]
 				* Endure count is only reduced by non-players on non-gvg maps.
@@ -2094,7 +2132,7 @@ int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag)
 	if (hp < 0) {
 		if (hp == INT_MIN) // -INT_MIN == INT_MIN in some architectures!
 			hp++;
-		status_damage(NULL, bl, -hp, 0, 0, 1);
+		status_damage(NULL, bl, -hp, 0, 0, 1, 0);
 		hp = 0;
 	}
 
@@ -2113,7 +2151,7 @@ int status_heal(struct block_list *bl,int64 hhp,int64 hsp, int flag)
 	if(sp < 0) {
 		if (sp == INT_MIN)
 			sp++;
-		status_damage(NULL, bl, 0, -sp, 0, 1);
+		status_damage(NULL, bl, 0, -sp, 0, 1, 0);
 		sp = 0;
 	}
 
@@ -2200,19 +2238,19 @@ int status_percent_change(struct block_list *src, struct block_list *target, int
 	if (hp > INT_MAX) {
 		hp -= INT_MAX;
 		if (flag)
-			status_damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1));
+			status_damage(src, target, INT_MAX, 0, 0, (!src||src==target?5:1), 0);
 		else
 			status_heal(target, INT_MAX, 0, 0);
 	}
 	if (sp > INT_MAX) {
 		sp -= INT_MAX;
 		if (flag)
-			status_damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1));
+			status_damage(src, target, 0, INT_MAX, 0, (!src||src==target?5:1), 0);
 		else
 			status_heal(target, 0, INT_MAX, 0);
 	}
 	if (flag)
-		return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1));
+		return status_damage(src, target, hp, sp, 0, (!src||src==target?5:1), 0);
 	return status_heal(target, hp, sp, 0);
 }
 
@@ -2409,6 +2447,8 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
 				(sc->data[SC_ANKLE] && skill_block_check(src, SC_ANKLE, skill_id)) ||
 				(sc->data[SC_STASIS] && skill_block_check(src, SC_STASIS, skill_id)) ||
 				(sc->data[SC_BITE] && skill_block_check(src, SC_BITE, skill_id)) ||
+				(sc->data[SC_NOVAEXPLOSING] && skill_block_check(src, SC_NOVAEXPLOSING, skill_id)) ||
+				(sc->data[SC_GRAVITYCONTROL] && skill_block_check(src, SC_GRAVITYCONTROL, skill_id)) ||
 				(sc->data[SC_KAGEHUMI] && skill_block_check(src, SC_KAGEHUMI, skill_id))
 			))
 				return false;
@@ -2476,7 +2516,7 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
 				if (tsc) {
 					if ((tsc->option&hide_flag) && !is_boss && (tsd->special_state.perfect_hiding || !is_detect))
 						return false;
-					if (tsc->data[SC_CLOAKINGEXCEED] && !is_boss && (tsd->special_state.perfect_hiding || is_detect))
+					if ((tsc->data[SC_CLOAKINGEXCEED] || tsc->data[SC_NEWMOON]) && !is_boss && (tsd->special_state.perfect_hiding || is_detect))
 						return false; // Works against insect and demon but not against bosses
 					if (tsc->data[SC__FEINTBOMB] && (is_boss || is_detect))
 						return false; // Works against all
@@ -2548,7 +2588,7 @@ int status_check_visibility(struct block_list *src, struct block_list *target)
 
 					if (((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_STEALTHFIELD] || tsc->data[SC_SUHIDE]) && !is_boss && (tsd->special_state.perfect_hiding || !is_detector))
 						return 0;
-					if (tsc->data[SC_CLOAKINGEXCEED] && !is_boss && ((tsd && tsd->special_state.perfect_hiding) || is_detector))
+					if ((tsc->data[SC_CLOAKINGEXCEED] || tsc->data[SC_NEWMOON]) && !is_boss && ((tsd && tsd->special_state.perfect_hiding) || is_detector))
 						return 0;
 					if (tsc->data[SC__FEINTBOMB] && !is_boss && !is_detector)
 						return 0;
@@ -2602,7 +2642,7 @@ int status_base_amotion_pc(struct map_session_data* sd, struct status_data* stat
 	temp_aspd = (float)(sqrt(temp_aspd) * 0.25f) + 0xc4;
 	if ((skill_lv = pc_checkskill(sd,SA_ADVANCEDBOOK)) > 0 && sd->status.weapon == W_BOOK)
 		val += (skill_lv - 1) / 2 + 1;
-	if ((skill_lv = pc_checkskill(sd, SG_DEVIL)) > 0 && pc_is_maxjoblv(sd))
+	if ((skill_lv = pc_checkskill(sd, SG_DEVIL)) > 0 && ((sd->class_&MAPID_THIRDMASK) == MAPID_STAR_EMPEROR || pc_is_maxjoblv(sd)))
 		val += 1 + skill_lv;
 	if ((skill_lv = pc_checkskill(sd,GS_SINGLEACTION)) > 0 && (sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
 		val += ((skill_lv + 1) / 2);
@@ -3360,6 +3400,8 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
 			if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_HPRATE)
 				bonus += 30;
 #endif
+			if(sc->data[SC_LUNARSTANCE])
+				bonus += bonus * sc->data[SC_LUNARSTANCE]->val2 / 100;
 
 			//Decreasing
 			if(sc->data[SC_VENOMBLEED])
@@ -4353,7 +4395,7 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt)
 #ifndef RENEWAL_ASPD
 	if((skill=pc_checkskill(sd,SA_ADVANCEDBOOK))>0 && sd->status.weapon == W_BOOK)
 		base_status->aspd_rate -= 5*skill;
-	if((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && pc_is_maxjoblv(sd))
+	if ((skill = pc_checkskill(sd,SG_DEVIL)) > 0 && ((sd->class_&MAPID_THIRDMASK) == MAPID_STAR_EMPEROR || pc_is_maxjoblv(sd)))
 		base_status->aspd_rate -= 30*skill;
 	if((skill=pc_checkskill(sd,GS_SINGLEACTION))>0 &&
 		(sd->status.weapon >= W_REVOLVER && sd->status.weapon <= W_GRENADE))
@@ -5874,6 +5916,8 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
 	if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_ALLSTAT)
 		str += 15;
 #endif
+	if (sc->data[SC_UNIVERSESTANCE])
+		str += sc->data[SC_UNIVERSESTANCE]->val2;
 
 	return (unsigned short)cap_value(str,0,USHRT_MAX);
 }
@@ -5954,6 +5998,8 @@ static unsigned short status_calc_agi(struct block_list *bl, struct status_chang
 	if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_ALLSTAT)
 		agi += 15;
 #endif
+	if (sc->data[SC_UNIVERSESTANCE])
+		agi += sc->data[SC_UNIVERSESTANCE]->val2;
 
 	return (unsigned short)cap_value(agi,0,USHRT_MAX);
 }
@@ -6024,6 +6070,8 @@ static unsigned short status_calc_vit(struct block_list *bl, struct status_chang
 	if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_ALLSTAT)
 		vit += 15;
 #endif
+	if (sc->data[SC_UNIVERSESTANCE])
+		vit += sc->data[SC_UNIVERSESTANCE]->val2;
 
 	return (unsigned short)cap_value(vit,0,USHRT_MAX);
 }
@@ -6098,6 +6146,8 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
 		int_ += 3;
 	if(sc->data[SC_GLASTHEIM_STATE])
 		int_ += sc->data[SC_GLASTHEIM_STATE]->val1;
+	if (sc->data[SC_UNIVERSESTANCE])
+		int_ += sc->data[SC_UNIVERSESTANCE]->val2;
 
 	if(bl->type != BL_PC) {
 		if(sc->data[SC_STRIPHELM])
@@ -6191,6 +6241,8 @@ static unsigned short status_calc_dex(struct block_list *bl, struct status_chang
 	if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_ALLSTAT)
 		dex += 15;
 #endif
+	if (sc->data[SC_UNIVERSESTANCE])
+		dex += sc->data[SC_UNIVERSESTANCE]->val2;
 
 	return (unsigned short)cap_value(dex,0,USHRT_MAX);
 }
@@ -6259,6 +6311,8 @@ static unsigned short status_calc_luk(struct block_list *bl, struct status_chang
 	if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_ALLSTAT)
 		luk += 15;
 #endif
+	if (sc->data[SC_UNIVERSESTANCE])
+		luk += sc->data[SC_UNIVERSESTANCE]->val2;
 
 	return (unsigned short)cap_value(luk,0,USHRT_MAX);
 }
@@ -6336,6 +6390,8 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
 	if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_ATKRATE)
 		batk += batk * 20 / 100;
 #endif
+	if (sc->data[SC_SUNSTANCE])
+		batk += batk * sc->data[SC_SUNSTANCE]->val2 / 100;
 
 	return (unsigned short)cap_value(batk,0,USHRT_MAX);
 }
@@ -6436,6 +6492,10 @@ static unsigned short status_calc_watk(struct block_list *bl, struct status_chan
 		watk -= watk * sc->data[SC_CATNIPPOWDER]->val2 / 100;
 	if (sc->data[SC_CHATTERING])
 		watk += sc->data[SC_CHATTERING]->val2;
+	if (sc->data[SC_SUNSTANCE])
+		watk += watk * sc->data[SC_SUNSTANCE]->val2 / 100;
+	if (sc->data[SC_SOULFALCON])
+		watk += sc->data[SC_SOULFALCON]->val2;
 
 	return (unsigned short)cap_value(watk,0,USHRT_MAX);
 }
@@ -6493,6 +6553,8 @@ static unsigned short status_calc_ematk(struct block_list *bl, struct status_cha
 		matk += sc->data[SC_CHATTERING]->val2;
 	if (sc->data[SC_DORAM_MATK])
 		matk += sc->data[SC_DORAM_MATK]->val1;
+	if (sc->data[SC_SOULFAIRY])
+		matk += sc->data[SC_SOULFAIRY]->val2;
 
 	return (unsigned short)cap_value(matk,0,USHRT_MAX);
 }
@@ -6604,6 +6666,8 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
 		critical -= sc->data[SC__UNLUCKY]->val2;
 	if(sc->data[SC_BEYONDOFWARCRY])
 		critical += sc->data[SC_BEYONDOFWARCRY]->val3;
+	if (sc->data[SC_SOULSHADOW])
+		critical += 10 * sc->data[SC_SOULSHADOW]->val3;
 
 	return (short)cap_value(critical,10,SHRT_MAX);
 }
@@ -6668,6 +6732,8 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
 	if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_HIT)
 		hit += 50;
 #endif
+	if (sc->data[SC_SOULFALCON])
+		hit += sc->data[SC_SOULFALCON]->val3;
 
 	return (short)cap_value(hit,1,SHRT_MAX);
 }
@@ -6901,6 +6967,8 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
 		def -= def * sc->data[SC_OVERED_BOOST]->val4 / 100;
 	if(sc->data[SC_GLASTHEIM_ITEMDEF])
 		def += sc->data[SC_GLASTHEIM_ITEMDEF]->val1;
+	if (sc->data[SC_SOULGOLEM])
+		def += sc->data[SC_SOULGOLEM]->val2;
 
 	return (defType)cap_value(def,DEFTYPE_MIN,DEFTYPE_MAX);
 }
@@ -7027,6 +7095,8 @@ static defType status_calc_mdef(struct block_list *bl, struct status_change *sc,
 		mdef -= 20 * sc->data[SC_ODINS_POWER]->val1;
 	if(sc->data[SC_GLASTHEIM_ITEMDEF])
 		mdef += sc->data[SC_GLASTHEIM_ITEMDEF]->val2;
+	if (sc->data[SC_SOULGOLEM])
+		mdef += sc->data[SC_SOULGOLEM]->val3;
 
 	return (defType)cap_value(mdef,DEFTYPE_MIN,DEFTYPE_MAX);
 }
@@ -7186,6 +7256,10 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
 				val = max( val, sc->data[SC_B_TRAP]->val3 );
 			if (sc->data[SC_CATNIPPOWDER])
 				val = max(val, sc->data[SC_CATNIPPOWDER]->val3);
+			if (sc->data[SC_SP_SHA])
+				val = max(val, sc->data[SC_SP_SHA]->val2);
+			if (sc->data[SC_CREATINGSTAR])
+				val = max(val, 90);
 
 			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 );
@@ -7428,6 +7502,8 @@ static short status_calc_fix_aspd(struct block_list *bl, struct status_change *s
 		aspd -= sc->data[SC_MTF_ASPD]->val1;
 	if (sc->data[SC_MTF_ASPD2])
 		aspd -= sc->data[SC_MTF_ASPD2]->val1;
+	if (sc->data[SC_SOULSHADOW])
+		aspd -= 10 * sc->data[SC_SOULSHADOW]->val2;
 
 	return cap_value(aspd, 0, 2000); // Will be recap for proper bl anyway
 }
@@ -7578,6 +7654,8 @@ static short status_calc_aspd_rate(struct block_list *bl, struct status_change *
 		aspd_rate -= sc->data[SC_GOLDENE_FERSE]->val3 * 10;
 	if (sc->data[SC_WIND_INSIGNIA] && sc->data[SC_WIND_INSIGNIA]->val1 == 2)
 		aspd_rate -= 100;
+	if (sc->data[SC_STARSTANCE])
+		aspd_rate -= 10 * sc->data[SC_STARSTANCE]->val2;
 
 	return (short)cap_value(aspd_rate,0,SHRT_MAX);
 }
@@ -8893,6 +8971,9 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 	if (status_change_isDisabledOnMap(type, map_getmapdata(bl->m)))
 		return 0;
 
+	if (sc->data[SC_GRAVITYCONTROL])
+		return 0; // !TODO: Confirm what statuses/conditions (if not all) are blocked.
+
 	// Uncomment to prevent status adding hp to gvg mob (like bloodylust=hp*3 etc...
 //	if (bl->type == BL_MOB)
 //		if (status_get_race2(bl) == RC2_GVG && status_sc2scb_flag(type)&SCB_MAXHP) return 0;
@@ -8978,6 +9059,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 	case SC_DECREASEAGI:
 	case SC_QUAGMIRE:
 	case SC_DONTFORGETME:
+	case SC_CREATINGSTAR:
 		if(sc->data[SC_SPEEDUP1])
 			return 0;
 		break;
@@ -9123,6 +9205,10 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		if( sd && pc_checkskill(sd, AS_CLOAKING) < 3 && !skill_check_cloaking(bl,NULL) )
 			return 0;
 	break;
+	case SC_NEWMOON:
+ 		if (sc->data[SC_BITE])
+ 			return 0;
+ 	break;
 	case SC_MODECHANGE:
 	{
 		enum e_mode mode;
@@ -9397,6 +9483,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			case SC_CATNIPPOWDER:
 			case SC_SV_ROOTTWIST:
 			case SC_BITESCAR:
+			case SC_SP_SHA:
 			case SC_FRESHSHRIMP:
 				return 0;
 		}
@@ -9515,6 +9602,30 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 	  	// Cancels Normal Overthrust. [Skotlex]
 		status_change_end(bl, SC_OVERTHRUST, INVALID_TIMER);
 		break;
+	case SC_SUNSTANCE:
+	case SC_LUNARSTANCE:
+	case SC_STARSTANCE:
+	case SC_UNIVERSESTANCE:
+		if (sc->data[type])
+			break;
+		status_change_end(bl, SC_SUNSTANCE, INVALID_TIMER);
+		status_change_end(bl, SC_LUNARSTANCE, INVALID_TIMER);
+		status_change_end(bl, SC_STARSTANCE, INVALID_TIMER);
+		status_change_end(bl, SC_UNIVERSESTANCE, INVALID_TIMER);
+		break;
+	case SC_SPIRIT:
+	case SC_SOULGOLEM:
+	case SC_SOULSHADOW:
+	case SC_SOULFALCON:
+	case SC_SOULFAIRY:
+		if (sc->data[type])
+			break;
+		status_change_end(bl, SC_SPIRIT, INVALID_TIMER);
+		status_change_end(bl, SC_SOULGOLEM, INVALID_TIMER);
+		status_change_end(bl, SC_SOULSHADOW, INVALID_TIMER);
+		status_change_end(bl, SC_SOULFALCON, INVALID_TIMER);
+		status_change_end(bl, SC_SOULFAIRY, INVALID_TIMER);
+		break;
 	case SC_MAGNIFICAT:
 		status_change_end(bl,SC_OFFERTORIUM,INVALID_TIMER);
 		break;
@@ -9893,6 +10004,8 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			case SC_LHZ_DUN_N2:
 			case SC_LHZ_DUN_N3:
 			case SC_LHZ_DUN_N4:
+			case SC_FLASHKICK:
+			case SC_SOULUNITY:
 				break;
 			case SC_GOSPEL:
 				 // Must not override a casting gospel char.
@@ -11762,6 +11875,83 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			val2 = 30; // SP Recovery rate bonus
 			break;
 
+		case SC_SUNSTANCE:
+			val2 = 2 + val1; // ATK Increase
+			tick = INFINITE_TICK;
+			break;
+		case SC_LUNARSTANCE:
+			val2 = 2 + val1; // MaxHP Increase
+			tick = INFINITE_TICK;
+			break;
+		case SC_STARSTANCE:
+			val2 = 4 + 2 * val1; // ASPD Increase
+			tick = INFINITE_TICK;
+			break;
+		case SC_UNIVERSESTANCE:
+			val2 = 2 + val1; // All Stats Increase
+			tick = INFINITE_TICK;
+			break;
+		case SC_NEWMOON:
+			val2 = 7; // Number of Regular Attacks Until Reveal
+			tick_time = 1000;
+			val4 = tick / tick_time;
+			break;
+		case SC_FALLINGSTAR:
+			val2 = 8 + 2 * (1 + val1) / 2; // Autocast Chance
+			if (val1 >= 7)
+				val2 += 1; // Make it 15% at level 7.
+			break;
+		case SC_CREATINGSTAR:
+			tick_time = 500;
+			val4 = tick / tick_time;
+			break;
+		case SC_LIGHTOFSUN:
+		case SC_LIGHTOFMOON:
+		case SC_LIGHTOFSTAR:
+			val2 = 5 * val1; // Skill Damage Increase.
+			break;
+		case SC_SOULGOLEM:
+			val2 = 60 * val1; // DEF Increase
+			val3 = 15 + 5 * val1; // MDEF Increase
+			break;
+		case SC_SOULSHADOW:
+			val2 = (1 + val1) / 2; // ASPD Increase
+			val3 = 10 + 2 * val1; // CRIT Increase
+			break;
+		case SC_SOULFALCON:
+			val2 = 10 * val1; // WATK Increase
+			val3 = 10; // HIT Increase
+			if (val1 >= 3)
+				val3 += 3;
+			else if (val1 >= 5)
+				val3 += 5;
+			break;
+		case SC_SOULFAIRY:
+			val2 = 10 * val1; // MATK Increase
+			val3 = 5; // Variable Cast Time Reduction
+			if (val1 >= 3)
+				val3 += 2;
+			else if (val1 >= 5)
+				val3 += 5;
+			break;
+		case SC_SOULUNITY:
+			tick_time = 3000;
+			val4 = tick / tick_time;
+			break;
+		case SC_SOULDIVISION:
+			val2 = 10 * val1; // Skill Aftercast Increase
+			break;
+		case SC_SOULREAPER:
+			val2 = 10 + 5 * val1; // Chance of Getting A Soul Sphere.
+			break;
+		case SC_SOULCOLLECT:
+			val2 = 5 + 3 * val2; // Max Soul Sphere's.
+			val3 = tick > 0 ? tick : 60000;
+			break;
+		case SC_SP_SHA:
+			val2 = 50; // Move speed reduction
+			break;
+
 		default:
 			if( calc_flag == SCB_NONE && StatusSkillChangeTable[type] == -1 && StatusIconChangeTable[type] == EFST_BLANK ) {
 				// Status change with no calc, no icon, and no skill associated...?
@@ -11919,6 +12109,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 				pc_setstand(sd, true);
 		case SC_FREEZE:
 		case SC_STUN:
+		case SC_GRAVITYCONTROL:
 			if (sc->data[SC_DANCING])
 				unit_stop_walking(bl, 1);
 		case SC_TRICKDEAD:
@@ -11988,6 +12179,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		case SC_HANBOK:
 		case SC_OKTOBERFEST:
 		case SC_DRESSUP:
+		case SC_NEWMOON:
 		case SC_SUHIDE:
 			unit_stop_attack(bl);
 			break;
@@ -12122,6 +12314,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 		case SC_CLOAKING:
 		case SC_CLOAKINGEXCEED:
 		case SC__INVISIBILITY:
+		case SC_NEWMOON:
 			sc->option |= OPTION_CLOAK;
 		case SC_CAMOUFLAGE:
 		case SC_STEALTHFIELD:
@@ -12683,7 +12876,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 				int damage = status->max_hp*sce->val3/100;
 				if(status->hp < damage) // to not kill him
 					damage = status->hp-1;
-				status_damage(NULL,bl,damage,0,0,1);
+				status_damage(NULL,bl,damage,0,0,1,0);
 			}
 			break;
 		case SC_PYROCLASTIC:
@@ -12755,6 +12948,26 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 			}
 			break;
 
+		case SC_FLASHKICK: {
+				map_session_data *tsd;
+
+				if (!(tsd = map_id2sd(sce->val1)))
+					break;
+
+				tsd->stellar_mark[sce->val2] = 0;
+			}
+			break;
+
+		case SC_SOULUNITY: {
+				map_session_data *tsd;
+
+				if (!(tsd = map_id2sd(sce->val2)))
+					break;
+
+				tsd->united_soul[sce->val3] = 0;
+			}
+			break;
+
 		case SC_BLADESTOP:
 			if(sce->val4) {
 				int tid2 = sce->val4; //stop the status for the other guy of bladestop as well
@@ -12961,7 +13174,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 				struct block_list* src = map_id2bl(sce->val2);
 				if( tid == -1 || !src)
 					break; // Terminated by Damage
-				status_fix_damage(src,bl,400*sce->val1,clif_damage(bl,bl,gettick(),0,0,400*sce->val1,0,DMG_NORMAL,0,false));
+				status_fix_damage(src,bl,400*sce->val1,clif_damage(bl,bl,gettick(),0,0,400*sce->val1,0,DMG_NORMAL,0,false),WL_WHITEIMPRISON);
 			}
 			break;
 		case SC_WUGDASH:
@@ -13051,6 +13264,32 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 		case SC_INTRAVISION:
 			calc_flag = SCB_ALL; // Required for overlapping
 			break;
+
+		case SC_SUNSTANCE:
+			status_change_end(bl, SC_LIGHTOFSUN, INVALID_TIMER);
+			break;
+		case SC_LUNARSTANCE:
+			status_change_end(bl, SC_NEWMOON, INVALID_TIMER);
+			status_change_end(bl, SC_LIGHTOFMOON, INVALID_TIMER);
+			break;
+		case SC_STARSTANCE:
+			status_change_end(bl, SC_FALLINGSTAR, INVALID_TIMER);
+			status_change_end(bl, SC_LIGHTOFSTAR, INVALID_TIMER);
+			break;
+		case SC_UNIVERSESTANCE:
+			status_change_end(bl, SC_LIGHTOFSUN, INVALID_TIMER);
+			status_change_end(bl, SC_NEWMOON, INVALID_TIMER);
+			status_change_end(bl, SC_LIGHTOFMOON, INVALID_TIMER);
+			status_change_end(bl, SC_FALLINGSTAR, INVALID_TIMER);
+			status_change_end(bl, SC_LIGHTOFSTAR, INVALID_TIMER);
+			status_change_end(bl, SC_DIMENSION, INVALID_TIMER);
+			break;
+		case SC_GRAVITYCONTROL:
+			status_fix_damage(bl, bl, sce->val2, clif_damage(bl, bl, gettick(), 0, 0, sce->val2, 0, DMG_NORMAL, 0, false), 0);
+			clif_specialeffect(bl, 223, AREA);
+			clif_specialeffect(bl, 330, AREA);
+			break;
+			
 		case SC_OVERED_BOOST:
 			switch (bl->type) {
 				case BL_HOM: {
@@ -13158,6 +13397,7 @@ int status_change_end_(struct block_list* bl, enum sc_type type, int tid, const
 	case SC_CLOAKING:
 	case SC_CLOAKINGEXCEED:
 	case SC__INVISIBILITY:
+	case SC_NEWMOON:
 		sc->option &= ~OPTION_CLOAK;
 	case SC_CAMOUFLAGE:
 	case SC_STEALTHFIELD:
@@ -13518,7 +13758,7 @@ TIMER_FUNC(status_change_timer){
 			int64 damage = 1000 + (3 * status->max_hp) / 100; // Deals fixed (1000 + 3%*MaxHP)
 			map_freeblock_lock();
 			dounlock = true;
-			status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, 0, 1, damage, 1, DMG_NORMAL, 0, false));
+			status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, 0, 1, damage, 1, DMG_NORMAL, 0, false),0);
 		}
 		break;
 
@@ -13526,7 +13766,7 @@ TIMER_FUNC(status_change_timer){
 		if (sce->val4 >= 0) { // Damage is every 10 seconds including 3%sp drain.
 			map_freeblock_lock();
 			dounlock = true;
-			status_damage(bl, bl, 1, status->max_sp * 3 / 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 1, 1, DMG_NORMAL, 0, false), 0);
+			status_damage(bl, bl, 1, status->max_sp * 3 / 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 1, 1, DMG_NORMAL, 0, false), 0, 0);
 		}
 		break;
 
@@ -13579,7 +13819,7 @@ TIMER_FUNC(status_change_timer){
 		if (sce->val4 >= 0) {
 			map_freeblock_lock();
 			dounlock = true;
-			status_fix_damage(bl, bl, 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 100, 1, DMG_NORMAL, 0, false));
+			status_fix_damage(bl, bl, 100, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, 100, 1, DMG_NORMAL, 0, false),0);
 		}
 		break;
 
@@ -13588,7 +13828,7 @@ TIMER_FUNC(status_change_timer){
 			int64 damage = status->vit * (sce->val1 - 3) + (int)status->max_hp / 100; // {Target VIT x (New Poison Research Skill Level - 3)} + (Target HP/100)
 			map_freeblock_lock();
 			dounlock = true;
-			status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, damage, 1, DMG_NORMAL, 0, false));
+			status_fix_damage(bl, bl, damage, clif_damage(bl, bl, tick, status->amotion, status->dmotion + 500, damage, 1, DMG_NORMAL, 0, false),0);
 			unit_skillcastcancel(bl, 2);
 		}
 		break;
@@ -13908,7 +14148,7 @@ TIMER_FUNC(status_change_timer){
 				damage = 1;
 			else
 				damage =  200 + 100 * sce->val1 + status_get_int(src);
-			status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,DMG_NORMAL,0,false), 0);
+			status_damage(src, bl, damage, 0, clif_damage(bl,bl,tick,status->amotion,status->dmotion+200,damage,1,DMG_NORMAL,0,false), 0, 0);
 			unit_skillcastcancel(bl,1);
 			if ( sc->data[type] ) {
 				sc_timer_next(1000 + tick);
@@ -14024,7 +14264,7 @@ TIMER_FUNC(status_change_timer){
 			if (damage >= status->hp)
 				damage = status->hp - 1; // Do not kill, just keep you with 1 hp minimum
 			map_freeblock_lock();
-			status_fix_damage(NULL, bl, damage, clif_damage(bl, bl, tick, 0, 0, damage, 0, DMG_NORMAL, 0, false));
+			status_fix_damage(NULL, bl, damage, clif_damage(bl, bl, tick, 0, 0, damage, 0, DMG_NORMAL, 0, false),0);
 			if (sc->data[type]) {
 				sc_timer_next(1000 + tick);
 			}
@@ -14111,7 +14351,7 @@ TIMER_FUNC(status_change_timer){
 
 			map_freeblock_lock();
 			clif_damage(bl, bl, tick, 0, 0, damage, 1, DMG_MULTI_HIT_ENDURE, 0, false);
-			status_damage(src, bl, damage,0, 0, 1);
+			status_damage(src, bl, damage,0, 0, 1, 0);
 			if( sc->data[type] ) {
 				sc_timer_next(2000 + tick);
 			}
@@ -14305,6 +14545,46 @@ TIMER_FUNC(status_change_timer){
 			return 0;
 		}
 		break;
+	case SC_NEWMOON:
+		if (--(sce->val4) >= 0) {
+			if (!status_charge(bl, 0, 1))
+				break;
+			sc_timer_next(1000 + tick);
+			return 0;
+		}
+		break;
+	case SC_CREATINGSTAR:
+		if (--(sce->val4) >= 0) { // Needed to check who the caster is and what AoE is giving the status.
+			struct block_list *star_caster = map_id2bl(sce->val2), *star_aoe = map_id2bl(sce->val3);
+
+			if (!star_caster || status_isdead(star_caster) || star_caster->m != bl->m)
+				break;
+
+			map_freeblock_lock();
+			if (star_aoe)
+				skill_attack(BF_WEAPON,star_caster,star_aoe,bl,SJ_BOOKOFCREATINGSTAR,sce->val1,tick,0);
+			if (sc->data[type])
+				sc_timer_next(500 + tick);
+			map_freeblock_unlock();
+			return 0;
+		}
+		break;
+	case SC_SOULUNITY:
+		if (--(sce->val4) >= 0) { // Needed to check the caster's location for the range check.
+			struct block_list *unity_src = map_id2bl(sce->val2);
+
+			if (!unity_src || status_isdead(unity_src) || unity_src->m != bl->m || !check_distance_bl(bl, unity_src, 11))
+				break;
+
+			status_heal(bl, 150 * sce->val1, 0, 2);
+			sc_timer_next(3000 + tick);
+			return 0;
+		}
+		break;
+	case SC_SOULCOLLECT:
+		pc_addsoulball(sd, skill_get_time2(SP_SOULCOLLECT, sce->val1), sce->val2);
+		sc_timer_next(sce->val3 + tick);
+		return 0;
 	}
 
 	// If status has an interval and there is at least 100ms remaining time, wait for next interval
@@ -14349,17 +14629,19 @@ int status_change_timer_sub(struct block_list* bl, va_list ap)
 		status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
 		status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
 		status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
+		status_change_end(bl, SC_NEWMOON, INVALID_TIMER);
 		if (tsc && tsc->data[SC__SHADOWFORM] && (sce && sce->val4 > 0 && sce->val4%2000 == 0) && // For every 2 seconds do the checking
 			rnd()%100 < 100 - tsc->data[SC__SHADOWFORM]->val1 * 10) // [100 - (Skill Level x 10)] %
 				status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
 		break;
 	case SC_RUWACH: // Reveal hidden target and deal little dammages if enemy
 		if (tsc && (tsc->data[SC_HIDING] || tsc->data[SC_CLOAKING] ||
-				tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_CLOAKINGEXCEED])) {
+				tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_NEWMOON] || tsc->data[SC_CLOAKINGEXCEED])) {
 			status_change_end(bl, SC_HIDING, INVALID_TIMER);
 			status_change_end(bl, SC_CLOAKING, INVALID_TIMER);
 			status_change_end(bl, SC_CAMOUFLAGE, INVALID_TIMER);
 			status_change_end(bl, SC_CLOAKINGEXCEED, INVALID_TIMER);
+			status_change_end(bl, SC_NEWMOON, INVALID_TIMER);
 			if(battle_check_target( src, bl, BCT_ENEMY ) > 0)
 				skill_attack(BF_MAGIC,src,src,bl,AL_RUWACH,1,tick,0);
 		}
@@ -14610,6 +14892,7 @@ void status_change_clear_buffs(struct block_list* bl, uint8 type)
 			case SC_FEAR:
 			case SC_MAGNETICFIELD:
 			case SC_NETHERWORLD:
+			case SC_CREATINGSTAR:
 				if (!(type&SCCB_DEBUFFS))
 					continue;
 				break;

+ 37 - 4
src/map/status.hpp

@@ -887,6 +887,39 @@ enum sc_type : int16 {
 	SC_ENTRY_QUEUE_APPLY_DELAY,
 	SC_ENTRY_QUEUE_NOTIFY_ADMISSION_TIME_OUT,
 
+	// Star Emperor
+	SC_LIGHTOFMOON,
+	SC_LIGHTOFSUN,
+	SC_LIGHTOFSTAR,
+	SC_LUNARSTANCE,
+	SC_UNIVERSESTANCE,
+	SC_SUNSTANCE,
+	SC_FLASHKICK,
+	SC_NEWMOON,
+	SC_STARSTANCE,
+	SC_DIMENSION,
+	SC_DIMENSION1,
+	SC_DIMENSION2,
+	SC_CREATINGSTAR,
+	SC_FALLINGSTAR,
+	SC_NOVAEXPLOSING,
+	SC_GRAVITYCONTROL,
+
+	// Soul Reaper
+	SC_SOULCOLLECT,
+	SC_SOULREAPER,
+	SC_SOULUNITY,
+	SC_SOULSHADOW,
+	SC_SOULFAIRY,
+	SC_SOULFALCON,
+	SC_SOULGOLEM,
+	SC_SOULDIVISION,
+	SC_SOULENERGY,
+	SC_USE_SKILL_SP_SPA,
+	SC_USE_SKILL_SP_SHA,
+	SC_SP_SHA,
+	SC_SOULCURSE,
+
 #ifdef RENEWAL
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled
 #endif
@@ -2432,13 +2465,13 @@ int status_sc2skill(sc_type sc);
 unsigned int status_sc2scb_flag(sc_type sc);
 int status_type2relevant_bl_types(int type);
 
-int status_damage(struct block_list *src,struct block_list *target,int64 dhp,int64 dsp, t_tick walkdelay, int flag);
+int status_damage(struct block_list *src,struct block_list *target,int64 dhp,int64 dsp, t_tick walkdelay, int flag, uint16 skill_id);
 //Define for standard HP damage attacks.
-#define status_fix_damage(src, target, hp, walkdelay) status_damage(src, target, hp, 0, walkdelay, 0)
+#define status_fix_damage(src, target, hp, walkdelay, skill) status_damage(src, target, hp, 0, walkdelay, 0, skill)
 //Define for standard SP damage attacks.
-#define status_fix_spdamage(src, target, sp, walkdelay) status_damage(src, target, 0, sp, walkdelay, 0)
+#define status_fix_spdamage(src, target, sp, walkdelay, skill) status_damage(src, target, 0, sp, walkdelay, 0, skill)
 //Define for standard HP/SP damage triggers.
-#define status_zap(bl, hp, sp) status_damage(NULL, bl, hp, sp, 0, 1)
+#define status_zap(bl, hp, sp) status_damage(NULL, bl, hp, sp, 0, 1, 0)
 //Define for standard HP/SP skill-related cost triggers (mobs require no HP/SP to use skills)
 int64 status_charge(struct block_list* bl, int64 hp, int64 sp);
 int status_percent_change(struct block_list *src, struct block_list *target, int8 hp_rate, int8 sp_rate, uint8 flag);

+ 13 - 0
src/map/unit.cpp

@@ -1924,6 +1924,10 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
 
 			if (!src->prev)
 				return 0;
+		} else if (sc->data[SC_NEWMOON] && skill_id != SJ_NEWMOONKICK) {
+			status_change_end(src, SC_NEWMOON, INVALID_TIMER);
+			if (!src->prev)
+				return 0; // Warped away!
 		}
 	}
 
@@ -2097,6 +2101,11 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
 		} else if (sc->data[SC_CLOAKINGEXCEED] && !(sc->data[SC_CLOAKINGEXCEED]->val4&4)) {
 			status_change_end(src, SC_CLOAKINGEXCEED, INVALID_TIMER);
 
+			if (!src->prev)
+				return 0;
+		} else if (sc->data[SC_NEWMOON]) {
+			status_change_end(src, SC_NEWMOON, INVALID_TIMER);
+
 			if (!src->prev)
 				return 0;
 		}
@@ -2904,6 +2913,8 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 		status_change_end(bl, SC_CLOSECONFINE2, INVALID_TIMER);
 		status_change_end(bl, SC_TINDER_BREAKER, INVALID_TIMER);
 		status_change_end(bl, SC_TINDER_BREAKER2, INVALID_TIMER);
+		status_change_end(bl, SC_FLASHKICK, INVALID_TIMER);
+		status_change_end(bl, SC_SOULUNITY, INVALID_TIMER);
 		status_change_end(bl, SC_HIDING, INVALID_TIMER);
 		// Ensure the bl is a PC; if so, we'll handle the removal of cloaking and cloaking exceed later
 		if ( bl->type != BL_PC ) {
@@ -2924,6 +2935,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
 		status_change_end(bl, SC__SHADOWFORM, INVALID_TIMER);
 		status_change_end(bl, SC__MANHOLE, INVALID_TIMER);
 		status_change_end(bl, SC_VACUUM_EXTREME, INVALID_TIMER);
+		status_change_end(bl, SC_NEWMOON, INVALID_TIMER);
 		status_change_end(bl, SC_CURSEDCIRCLE_ATKER, INVALID_TIMER); // callme before warp
 		status_change_end(bl, SC_SUHIDE, INVALID_TIMER);
 	}
@@ -3262,6 +3274,7 @@ int unit_free(struct block_list *bl, clr_type clrtype)
 			pc_inventory_rental_clear(sd);
 			pc_delspiritball(sd, sd->spiritball, 1);
 			pc_delspiritcharm(sd, sd->spiritcharm, sd->spiritcharm_type);
+			pc_delsoulball(sd,sd->soulball, 1);
 
 			if( sd->st && sd->st->state != RUN ) {// free attached scripts that are waiting
 				script_free_state(sd->st);

Algúns arquivos non se mostraron porque demasiados arquivos cambiaron neste cambio