Преглед на файлове

Job Improvement Project - Minstrel/Wanderer (#4701)

* Fixes #4211.
* kRO Changelog: http://ro.gnjoy.com/news/update/View.asp?seq=235&curpage=1
* kRO Changelog 2: http://ro.gnjoy.com/news/update/View.asp?seq=246&curpage=1
Thanks to @Angelic234, @Litro, @LordWhiplash, @Feelmeone, @ecdarreola, and @teededung!
Aleos преди 5 години
родител
ревизия
fde031fb19

+ 0 - 31
db/import-tmpl/improvise_db.yml

@@ -1,31 +0,0 @@
-# This file is a part of rAthena.
-#   Copyright(C) 2019 rAthena Development Team
-#   https://rathena.org - https://github.com/rathena
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-###########################################################################
-# Improvised Song Database
-###########################################################################
-#
-# Improvised Song Settings
-#
-###########################################################################
-# - Skill             Skill to be casted by Improvised Song.
-#   Probability       Probability of skill compared to others in database (1 = 0.01%, 10000 = 100%).
-###########################################################################
-
-Header:
-  Type: IMPROVISED_SONG_DB
-  Version: 1

+ 0 - 37
db/improvise_db.yml

@@ -1,37 +0,0 @@
-# This file is a part of rAthena.
-#   Copyright(C) 2019 rAthena Development Team
-#   https://rathena.org - https://github.com/rathena
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-###########################################################################
-# Improvised Song Database
-###########################################################################
-#
-# Improvised Song Settings
-#
-###########################################################################
-# - Skill             Skill to be casted by Improvised Song.
-#   Probability       Probability of skill compared to others in database (1 = 0.01%, 10000 = 100%).
-###########################################################################
-
-Header:
-  Type: IMPROVISED_SONG_DB
-  Version: 1
-
-Footer:
-  Imports:
-  - Path: db/re/improvise_db.yml
-    Mode: Renewal
-  - Path: db/import/improvise_db.yml

+ 4 - 15
db/pre-re/skill_db.yml

@@ -2071,8 +2071,6 @@ Body:
     TargetType: Attack
     DamageFlags:
       NoDamage: true
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range: -2
     Hit: Single
     HitCount: 1
@@ -6699,8 +6697,6 @@ Body:
     MaxLevel: 5
     Type: Weapon
     TargetType: Attack
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range:
       - Level: 1
         Size: 3
@@ -10658,7 +10654,6 @@ Body:
       IgnoreDefense: true
     Flags:
       TargetTrap: true
-      IncreaseGloomyDayDamage: true
     Range: 5
     Hit: Multi_Hit
     HitCount: 5
@@ -12834,8 +12829,6 @@ Body:
     MaxLevel: 5
     Type: Weapon
     TargetType: Attack
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range: 4
     Hit: Multi_Hit
     HitCount: 5
@@ -16847,8 +16840,6 @@ Body:
     MaxLevel: 10
     Type: Weapon
     TargetType: Attack
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range: 5
     Hit: Multi_Hit
     HitCount: -5
@@ -19889,9 +19880,9 @@ Body:
       IgnoreDefCard: true
     Flags:
       AllowOnWarg: true
-      IncreaseDanceWithWugDamage: true
       IgnoreAutoGuard: true
       IgnoreCicada: true
+      IncreaseDanceWithWugDamage: true
     Range: 9
     Hit: Single
     HitCount: 1
@@ -19919,9 +19910,9 @@ Body:
       IgnoreDefCard: true
     Flags:
       AlterRangeVulture: true
-      IncreaseDanceWithWugDamage: true
       IgnoreAutoGuard: true
       IgnoreCicada: true
+      IncreaseDanceWithWugDamage: true
     Range: 9
     Hit: Single
     HitCount: 1
@@ -24313,7 +24304,7 @@ Body:
         Reproduce: true
     Requires:
       SpCost: 1
-  - Id: 2417
+  - Id: 2417 # Removed on kRO
     Name: WM_DOMINION_IMPULSE
     Description: Dominion Impulse
     MaxLevel: 1
@@ -24326,6 +24317,7 @@ Body:
     HitCount: 1
     SplashArea: 5
     AfterCastActDelay: 1000
+    FixedCastTime: -1
     Requires:
       SpCost: 10
   - Id: 2418
@@ -32136,8 +32128,6 @@ Body:
     TargetType: Attack
     DamageFlags:
       NoDamage: true
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range: -2
     Hit: Single
     HitCount: 1
@@ -32162,7 +32152,6 @@ Body:
       IgnoreDefense: true
     Flags:
       TargetTrap: true
-      IncreaseGloomyDayDamage: true
     Range: 5
     Hit: Multi_Hit
     HitCount: 5

+ 12 - 12
db/pre-re/skill_tree.txt

@@ -3219,9 +3219,9 @@
 4068,2382,5,2422,1,0,0,0,0,0,0,0,0 //MI_ECHOSONG#Echo Song#
 4068,2383,5,2422,1,0,0,0,0,0,0,0,0 //MI_HARMONIZE#Harmonize#
 4068,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4068,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4068,2413,5,0,0,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4068,2414,5,317,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4068,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4068,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4068,2418,5,316,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4068,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4068,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -3275,9 +3275,9 @@
 4069,2351,5,2422,1,0,0,0,0,0,0,0,0 //WA_SYMPHONY_OF_LOVER#Symphony of Lovers#
 4069,2352,5,2422,1,0,0,0,0,0,0,0,0 //WA_MOONLIT_SERENADE#Moonlit Serenade#
 4069,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4069,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4069,2413,5,0,0,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4069,2414,5,325,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4069,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4069,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4069,2418,5,324,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4069,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4069,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -3649,9 +3649,9 @@
 4075,2382,5,2422,1,0,0,0,0,0,0,0,0 //MI_ECHOSONG#Echo Song#
 4075,2383,5,2422,1,0,0,0,0,0,0,0,0 //MI_HARMONIZE#Harmonize#
 4075,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4075,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4075,2413,5,0,0,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4075,2414,5,317,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4075,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4075,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4075,2418,5,316,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4075,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4075,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -3711,9 +3711,9 @@
 4076,2351,5,2422,1,0,0,0,0,0,0,0,0 //WA_SYMPHONY_OF_LOVER#Symphony of Lovers#
 4076,2352,5,2422,1,0,0,0,0,0,0,0,0 //WA_MOONLIT_SERENADE#Moonlit Serenade#
 4076,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4076,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4076,2413,5,0,0,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4076,2414,5,325,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4076,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4076,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4076,2418,5,324,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4076,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4076,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -4870,9 +4870,9 @@
 4104,2382,5,2422,1,0,0,0,0,0,0,0,0 //MI_ECHOSONG#Echo Song#
 4104,2383,5,2422,1,0,0,0,0,0,0,0,0 //MI_HARMONIZE#Harmonize#
 4104,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4104,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4104,2413,5,0,0,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4104,2414,5,317,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4104,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4104,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4104,2418,5,316,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4104,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4104,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -4927,9 +4927,9 @@
 4105,2351,5,2422,1,0,0,0,0,0,0,0,0 //WA_SYMPHONY_OF_LOVER#Symphony of Lovers#
 4105,2352,5,2422,1,0,0,0,0,0,0,0,0 //WA_MOONLIT_SERENADE#Moonlit Serenade#
 4105,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4105,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4105,2413,5,0,0,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4105,2414,5,325,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4105,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4105,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4105,2418,5,324,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4105,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4105,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#

+ 0 - 65
db/re/improvise_db.yml

@@ -1,65 +0,0 @@
-# This file is a part of rAthena.
-#   Copyright(C) 2019 rAthena Development Team
-#   https://rathena.org - https://github.com/rathena
-#
-# This program is free software: you can redistribute it and/or modify
-# it under the terms of the GNU General Public License as published by
-# the Free Software Foundation, either version 3 of the License, or
-# (at your option) any later version.
-#
-# This program is distributed in the hope that it will be useful,
-# but WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-# GNU General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program. If not, see <http://www.gnu.org/licenses/>.
-#
-###########################################################################
-# Improvised Song Database
-###########################################################################
-#
-# Improvised Song Settings
-#
-###########################################################################
-# - Skill             Skill to be casted by Improvised Song.
-#   Probability       Probability of skill compared to others in database (1 = 0.01%, 10000 = 100%).
-###########################################################################
-
-Header:
-  Type: IMPROVISED_SONG_DB
-  Version: 1
-
-Body:
-  - Skill: MG_NAPALMBEAT
-    Probability: 6000
-  - Skill: MG_SAFETYWALL
-    Probability: 4000
-  - Skill: MG_SOULSTRIKE
-    Probability: 6000
-  - Skill: MG_COLDBOLT
-    Probability: 6000
-  - Skill: MG_FROSTDIVER
-    Probability: 6000
-  - Skill: MG_FIREBALL
-    Probability: 6000
-  - Skill: MG_FIREWALL
-    Probability: 4000
-  - Skill: MG_FIREBOLT
-    Probability: 6000
-  - Skill: MG_LIGHTNINGBOLT
-    Probability: 6000
-  - Skill: MG_THUNDERSTORM
-    Probability: 4000
-  - Skill: WZ_FIREPILLAR
-    Probability: 4000
-  - Skill: WZ_METEOR
-    Probability: 4000
-  - Skill: WZ_JUPITEL
-    Probability: 6000
-  - Skill: WZ_VERMILION
-    Probability: 4000
-  - Skill: WZ_WATERBALL
-    Probability: 6000
-  - Skill: WZ_STORMGUST
-    Probability: 4000

+ 102 - 231
db/re/skill_db.yml

@@ -2106,8 +2106,6 @@ Body:
     TargetType: Attack
     DamageFlags:
       NoDamage: true
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range: -2
     Hit: Multi_Hit
     HitCount: -3
@@ -7077,8 +7075,6 @@ Body:
     MaxLevel: 5
     Type: Weapon
     TargetType: Attack
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range:
       - Level: 1
         Size: 3
@@ -8555,7 +8551,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 60000
     Cooldown: 20000
     Requires:
@@ -8609,7 +8605,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 60000
     Cooldown: 20000
     Requires:
@@ -8695,7 +8691,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 60000
     Cooldown: 20000
     Requires:
@@ -8717,7 +8713,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 60000
     Cooldown: 20000
     Requires:
@@ -8835,7 +8831,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 20000
     Cooldown: 20000
     Requires:
@@ -8877,7 +8873,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 20000
     Cooldown: 20000
     Requires:
@@ -8919,7 +8915,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 20000
     Cooldown: 20000
     Requires:
@@ -8961,7 +8957,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 20000
     Cooldown: 20000
     Requires:
@@ -9087,7 +9083,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 20000
     Cooldown: 20000
     Requires:
@@ -9171,7 +9167,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 20000
     Cooldown: 20000
     Requires:
@@ -9213,7 +9209,7 @@ Body:
     HitCount: 1
     SplashArea: 15
     CastTime: 1000
-    Duration1: 60000
+    Duration1: 180000
     Duration2: 20000
     Cooldown: 20000
     Requires:
@@ -10976,7 +10972,6 @@ Body:
     TargetType: Attack
     Flags:
       TargetTrap: true
-      IncreaseGloomyDayDamage: true
     Range: 5
     Hit: Multi_Hit
     HitCount: 5
@@ -13209,8 +13204,6 @@ Body:
     MaxLevel: 5
     Type: Weapon
     TargetType: Attack
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range:
       - Level: 1
         Size: 7
@@ -17536,8 +17529,6 @@ Body:
     MaxLevel: 10
     Type: Weapon
     TargetType: Attack
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range: 5
     Hit: Multi_Hit
     HitCount: -5
@@ -20668,9 +20659,9 @@ Body:
       IgnoreDefCard: true
     Flags:
       AllowOnWarg: true
-      IncreaseDanceWithWugDamage: true
       IgnoreAutoGuard: true
       IgnoreCicada: true
+      IncreaseDanceWithWugDamage: true
     Range: 9
     Hit: Single
     HitCount: 1
@@ -20698,9 +20689,9 @@ Body:
       IgnoreDefCard: true
     Flags:
       AlterRangeVulture: true
-      IncreaseDanceWithWugDamage: true
       IgnoreAutoGuard: true
       IgnoreCicada: true
+      IncreaseDanceWithWugDamage: true
     Range: 9
     Hit: Single
     HitCount: 1
@@ -23106,8 +23097,6 @@ Body:
     MaxLevel: 10
     Type: Weapon
     TargetType: Attack
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range: 1
     Hit: Single
     HitCount: 5
@@ -24842,21 +24831,11 @@ Body:
       Splash: true
     Hit: Single
     HitCount: 1
-    SplashArea:
-      - Level: 1
-        Area: 7
-      - Level: 2
-        Area: 8
-      - Level: 3
-        Area: 9
-      - Level: 4
-        Area: 10
-      - Level: 5
-        Area: 11
+    SplashArea: -1
     CastCancel: true
     CastTime: 1000
     AfterCastActDelay: 2000
-    Duration1: 60000
+    Duration1: 180000
     FixedCastTime: -1
     Requires:
       SpCost:
@@ -24883,21 +24862,11 @@ Body:
       Splash: true
     Hit: Single
     HitCount: 1
-    SplashArea:
-      - Level: 1
-        Area: 7
-      - Level: 2
-        Area: 8
-      - Level: 3
-        Area: 9
-      - Level: 4
-        Area: 10
-      - Level: 5
-        Area: 11
+    SplashArea: -1
     CastCancel: true
     CastTime: 1000
     AfterCastActDelay: 2000
-    Duration1: 60000
+    Duration1: 180000
     FixedCastTime: -1
     Requires:
       SpCost:
@@ -24924,21 +24893,11 @@ Body:
       Splash: true
     Hit: Single
     HitCount: 1
-    SplashArea:
-      - Level: 1
-        Area: 7
-      - Level: 2
-        Area: 8
-      - Level: 3
-        Area: 9
-      - Level: 4
-        Area: 10
-      - Level: 5
-        Area: 11
+    SplashArea: -1
     CastCancel: true
     CastTime: 1000
     AfterCastActDelay: 2000
-    Duration1: 60000
+    Duration1: 180000
     FixedCastTime: -1
     Requires:
       SpCost:
@@ -24965,21 +24924,11 @@ Body:
       Splash: true
     Hit: Single
     HitCount: 1
-    SplashArea:
-      - Level: 1
-        Area: 7
-      - Level: 2
-        Area: 8
-      - Level: 3
-        Area: 9
-      - Level: 4
-        Area: 10
-      - Level: 5
-        Area: 11
+    SplashArea: -1
     CastCancel: true
     CastTime: 1000
     AfterCastActDelay: 2000
-    Duration1: 60000
+    Duration1: 180000
     FixedCastTime: -1
     Requires:
       SpCost:
@@ -25020,7 +24969,7 @@ Body:
     CastCancel: true
     CastTime: 1000
     AfterCastActDelay: 2000
-    Duration1: 60000
+    Duration1: 180000
     FixedCastTime: -1
     Requires:
       SpCost:
@@ -25088,29 +25037,7 @@ Body:
       Skill:
         Reproduce: true
     CastCancel: true
-    CastTime: # !TODO: Confirm all times
-      - Level: 1
-        Time: 1000
-      - Level: 2
-        Time: 1500
-      - Level: 3
-        Time: 2000
-      - Level: 4
-        Time: 2500
-      - Level: 5
-        Time: 3000
-      - Level: 6
-        Time: 3500
-      - Level: 7
-        Time: 4000
-      - Level: 8
-        Time: 4500
-      - Level: 9
-        Time: 5000
-      - Level: 10
-        Time: 5500
-    AfterCastActDelay: 1000
-    Cooldown:
+    CastTime: # !TODO: Confirm cast times
       - Level: 1
         Time: 1000
       - Level: 2
@@ -25131,6 +25058,8 @@ Body:
         Time: 5000
       - Level: 10
         Time: 5500
+    AfterCastActDelay: 500
+    Cooldown: 2500
     FixedCastTime: -1
     Requires:
       SpCost:
@@ -25158,44 +25087,33 @@ Body:
     Name: WM_REVERBERATION
     Description: Reverberation
     MaxLevel: 5
-    TargetType: Ground
+    TargetType: Attack
     DamageFlags:
-      NoDamage: true
       Splash: true
     Flags:
       IsTrap: true
     Range: 9
     Hit: Single
     HitCount: 1
-    SplashArea: 2
-    CopyFlags:
-      Skill:
-        Reproduce: true
-    CastCancel: true
-    CastTime:
-      - Level: 1
-        Time: 1100
-      - Level: 2
-        Time: 1200
-      - Level: 3
-        Time: 1300
-      - Level: 4
-        Time: 1400
-      - Level: 5
-        Time: 1500
-    AfterCastActDelay: 1000
-    Duration1:
+    SplashArea:
       - Level: 1
-        Time: 9000
+        Area: 2
       - Level: 2
-        Time: 10000
+        Area: 2
       - Level: 3
-        Time: 11000
+        Area: 2
       - Level: 4
-        Time: 12000
+        Area: 3
       - Level: 5
-        Time: 13000
-    FixedCastTime: -1
+        Area: 3
+    CopyFlags:
+      Skill:
+        Reproduce: true
+    CastCancel: true
+    CastTime: 1000
+    AfterCastActDelay: 500
+    Cooldown: 150
+    FixedCastTime: 500
     Requires:
       SpCost:
         - Level: 1
@@ -25208,13 +25126,10 @@ Body:
           Amount: 42
         - Level: 5
           Amount: 48
-    Unit:
-      Id: Reverberation
-      Interval: 1000
-      Target: Enemy
-      Flag:
-        NoKnockback: true
-  - Id: 2415
+      Ammo:
+        Arrow: true
+      AmmoAmount: 10
+  - Id: 2415 # Removed on kRO
     Name: WM_REVERBERATION_MELEE
     Description: Reverberation Melee
     MaxLevel: 5
@@ -25222,7 +25137,6 @@ Body:
     TargetType: Attack
     DamageFlags:
       Splash: true
-      SplashSplit: true
     Hit: Single
     HitCount: 1
     Element: Weapon
@@ -25238,18 +25152,12 @@ Body:
     MaxLevel: 5
     Type: Magic
     TargetType: Attack
-    DamageFlags:
-      Splash: true
-      SplashSplit: true
-    Hit: Single
-    HitCount: 1
-    SplashArea: 2
+    Hit: Multi_Hit
+    HitCount: 10
     CopyFlags:
       Skill:
         Reproduce: true
-    Requires:
-      SpCost: 1
-  - Id: 2417
+  - Id: 2417 # Removed on kRO
     Name: WM_DOMINION_IMPULSE
     Description: Dominion Impulse
     MaxLevel: 1
@@ -25387,7 +25295,7 @@ Body:
         Whip: true
       ItemCost:
         - Item: Protect_Neck_Candy
-          Amount: 1
+          Amount: 2
     Unit:
       Id: Netherworld
       Range: 1
@@ -25505,7 +25413,7 @@ Body:
     Name: WM_LULLABY_DEEPSLEEP
     Description: Deep Sleep Lullaby
     MaxLevel: 5
-    TargetType: Self
+    TargetType: Attack
     DamageFlags:
       NoDamage: true
       Splash: true
@@ -25513,19 +25421,19 @@ Body:
     HitCount: 1
     SplashArea:
       - Level: 1
-        Area: 5
+        Area: 1
       - Level: 2
-        Area: 6
+        Area: 1
       - Level: 3
-        Area: 7
+        Area: 1
       - Level: 4
-        Area: 8
+        Area: 2
       - Level: 5
-        Area: 9
+        Area: 2
     CastCancel: true
     CastTime: 2000
     AfterCastActDelay: 1000
-    Duration1:
+    Duration1: # !TODO: What's the updated duration?
       - Level: 1
         Time: 12000
       - Level: 2
@@ -25553,6 +25461,9 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 2
   - Id: 2423
     Name: WM_SIRCLEOFNATURE
     Description: Circle of Nature's Sound
@@ -25563,21 +25474,11 @@ Body:
       Splash: true
     Hit: Single
     HitCount: 1
-    SplashArea:
-      - Level: 1
-        Area: 3
-      - Level: 2
-        Area: 4
-      - Level: 3
-        Area: 5
-      - Level: 4
-        Area: 6
-      - Level: 5
-        Area: 7
+    SplashArea: -1
     CastCancel: true
     CastTime: 2000
     AfterCastActDelay: 1000
-    Duration1: 60000
+    Duration1: 180000
     Cooldown: 15000
     FixedCastTime: -1
     Requires:
@@ -25600,7 +25501,7 @@ Body:
     Description: Improvised Song
     MaxLevel: 5
     Type: Magic
-    TargetType: Self
+    TargetType: Attack
     DamageFlags:
       NoDamage: true
     Range: 9
@@ -25638,17 +25539,7 @@ Body:
     CastCancel: true
     CastTime: 1000
     AfterCastActDelay: 1000
-    Duration1:
-      - Level: 1
-        Time: 30000
-      - Level: 2
-        Time: 45000
-      - Level: 3
-        Time: 60000
-      - Level: 4
-        Time: 75000
-      - Level: 5
-        Time: 90000
+    Duration1: 60000
     Cooldown: 10000
     FixedCastTime: 500
     Requires:
@@ -25719,7 +25610,7 @@ Body:
           Amount: 120
       ItemCost:
         - Item: Protect_Neck_Candy
-          Amount: 1
+          Amount: 2
   - Id: 2427
     Name: WM_SONG_OF_MANA
     Description: Song of Mana
@@ -25746,17 +25637,7 @@ Body:
     CastCancel: true
     CastTime: 1000
     AfterCastActDelay: 1000
-    Duration1:
-      - Level: 1
-        Time: 30000
-      - Level: 2
-        Time: 60000
-      - Level: 3
-        Time: 90000
-      - Level: 4
-        Time: 120000
-      - Level: 5
-        Time: 150000
+    Duration1: 120000
     Cooldown: 90000
     FixedCastTime: 500
     Requires:
@@ -25774,6 +25655,9 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 1
   - Id: 2428
     Name: WM_DANCE_WITH_WUG
     Description: Dance With A Warg
@@ -25810,17 +25694,7 @@ Body:
       - Level: 5
         Time: 3500
     AfterCastActDelay: 1000
-    Duration1:
-      - Level: 1
-        Time: 30000
-      - Level: 2
-        Time: 60000
-      - Level: 3
-        Time: 90000
-      - Level: 4
-        Time: 120000
-      - Level: 5
-        Time: 150000
+    Duration1: 120000
     Cooldown: 90000
     FixedCastTime: 500
     Requires:
@@ -25838,30 +25712,32 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 1
   - Id: 2429
     Name: WM_SOUND_OF_DESTRUCTION
     Description: Sound of Destruction
     MaxLevel: 5
-    TargetType: Ground
+    TargetType: Self
     DamageFlags:
+      NoDamage: true
       Splash: true
-      IgnoreFlee: true
     Flags:
       IsChorus: true
-    Range: 9
     Hit: Single
     HitCount: 1
     SplashArea:
       - Level: 1
-        Area: 4
+        Area: 5
       - Level: 2
-        Area: 4
-      - Level: 3
         Area: 5
+      - Level: 3
+        Area: 6
       - Level: 4
-        Area: 5
-      - Level: 5
         Area: 6
+      - Level: 5
+        Area: 7
     CastCancel: true
     CastTime:
       - Level: 2
@@ -25873,18 +25749,8 @@ Body:
       - Level: 5
         Time: 2000
     AfterCastActDelay: 1000
-    Duration1: 5000
-    Cooldown:
-      - Level: 1
-        Time: 6000
-      - Level: 2
-        Time: 7000
-      - Level: 3
-        Time: 8000
-      - Level: 4
-        Time: 9000
-      - Level: 5
-        Time: 10000
+    Duration1: 10000
+    Cooldown: 60000
     FixedCastTime: 500
     Requires:
       SpCost:
@@ -25901,6 +25767,9 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 10
   - Id: 2430
     Name: WM_SATURDAY_NIGHT_FEVER
     Description: Saturday Night Fever
@@ -25959,7 +25828,7 @@ Body:
         Time: 4000
       - Level: 5
         Time: 2000
-    Cooldown: 180000
+    Cooldown: 60000
     FixedCastTime: 1000
     Requires:
       SpCost:
@@ -25976,6 +25845,9 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 5
   - Id: 2431
     Name: WM_LERADS_DEW
     Description: Lerad's Dew
@@ -26002,17 +25874,7 @@ Body:
     CastCancel: true
     CastTime: 1000
     AfterCastActDelay: 1000
-    Duration1:
-      - Level: 1
-        Time: 20000
-      - Level: 2
-        Time: 30000
-      - Level: 3
-        Time: 40000
-      - Level: 4
-        Time: 50000
-      - Level: 5
-        Time: 60000
+    Duration1: 120000
     Cooldown: 180000
     FixedCastTime: 500
     Requires:
@@ -26030,6 +25892,9 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 1
   - Id: 2432
     Name: WM_MELODYOFSINK
     Description: Melody of Sink
@@ -26067,7 +25932,7 @@ Body:
         Time: 50000
       - Level: 5
         Time: 60000
-    Cooldown: 180000
+    Cooldown: 20000
     FixedCastTime: 500
     Requires:
       SpCost:
@@ -26084,6 +25949,9 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 2
   - Id: 2433
     Name: WM_BEYOND_OF_WARCRY
     Description: Warcry of Beyond
@@ -26121,7 +25989,7 @@ Body:
         Time: 50000
       - Level: 5
         Time: 60000
-    Cooldown: 180000
+    Cooldown: 20000
     FixedCastTime: 500
     Requires:
       SpCost:
@@ -26138,6 +26006,9 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 2
   - Id: 2434
     Name: WM_UNLIMITED_HUMMING_VOICE
     Description: Unlimited Humming Voice
@@ -26202,6 +26073,9 @@ Body:
       Weapon:
         Musical: true
         Whip: true
+      ItemCost:
+        - Item: Protect_Neck_Candy
+          Amount: 5
   - Id: 2516
     Name: WM_SEVERE_RAINSTORM_MELEE
     Description: Severe Rainstorm Melee
@@ -35983,8 +35857,6 @@ Body:
     TargetType: Attack
     DamageFlags:
       NoDamage: true
-    Flags:
-      IncreaseGloomyDayDamage: true
     Range: -2
     Hit: Single
     HitCount: 1
@@ -36009,7 +35881,6 @@ Body:
     TargetType: Attack
     Flags:
       TargetTrap: true
-      IncreaseGloomyDayDamage: true
     Range: 5
     Hit: Multi_Hit
     HitCount: 5

+ 4 - 0
db/re/skill_nocast_db.txt

@@ -33,7 +33,11 @@
 328,1	//DC_DONTFORGETME
 2422,1	//WM_LULLABY_DEEPSLEEP
 2423,1	//WM_SIRCLEOFNATURE
+2425,1	//WM_GLOOMYDAY
+2429,1	//WM_SOUND_OF_DESTRUCTION
 2430,1	//WM_SATURDAY_NIGHT_FEVER
+2432,1	//WM_MELODYOFSINK
+2433,1	//WM_BEYOND_OF_WARCRY
 2455,1	//SO_ARRULLO
 2299,1	//SC_MANHOLE
 

+ 12 - 12
db/re/skill_tree.txt

@@ -3250,9 +3250,9 @@
 4068,2382,5,2422,1,0,0,0,0,0,0,0,0 //MI_ECHOSONG#Echo Song#
 4068,2383,5,2422,1,0,0,0,0,0,0,0,0 //MI_HARMONIZE#Harmonize#
 4068,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4068,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4068,2413,10,2414,5,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4068,2414,5,317,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4068,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4068,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4068,2418,5,316,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4068,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4068,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -3306,9 +3306,9 @@
 4069,2351,5,2422,1,0,0,0,0,0,0,0,0 //WA_SYMPHONY_OF_LOVER#Symphony of Lovers#
 4069,2352,5,2422,1,0,0,0,0,0,0,0,0 //WA_MOONLIT_SERENADE#Moonlit Serenade#
 4069,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4069,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4069,2413,10,2414,5,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4069,2414,5,325,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4069,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4069,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4069,2418,5,324,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4069,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4069,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -3681,9 +3681,9 @@
 4075,2382,5,2422,1,0,0,0,0,0,0,0,0 //MI_ECHOSONG#Echo Song#
 4075,2383,5,2422,1,0,0,0,0,0,0,0,0 //MI_HARMONIZE#Harmonize#
 4075,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4075,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4075,2413,10,2414,5,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4075,2414,5,317,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4075,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4075,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4075,2418,5,316,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4075,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4075,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -3744,9 +3744,9 @@
 4076,2351,5,2422,1,0,0,0,0,0,0,0,0 //WA_SYMPHONY_OF_LOVER#Symphony of Lovers#
 4076,2352,5,2422,1,0,0,0,0,0,0,0,0 //WA_MOONLIT_SERENADE#Moonlit Serenade#
 4076,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4076,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4076,2413,10,2414,5,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4076,2414,5,325,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4076,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4076,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4076,2418,5,324,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4076,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4076,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -4913,9 +4913,9 @@
 4104,2382,5,2422,1,0,0,0,0,0,0,0,0 //MI_ECHOSONG#Echo Song#
 4104,2383,5,2422,1,0,0,0,0,0,0,0,0 //MI_HARMONIZE#Harmonize#
 4104,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4104,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4104,2413,10,2414,5,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4104,2414,5,317,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4104,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4104,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4104,2418,5,316,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4104,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4104,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#
@@ -4971,9 +4971,9 @@
 4105,2351,5,2422,1,0,0,0,0,0,0,0,0 //WA_SYMPHONY_OF_LOVER#Symphony of Lovers#
 4105,2352,5,2422,1,0,0,0,0,0,0,0,0 //WA_MOONLIT_SERENADE#Moonlit Serenade#
 4105,2412,10,0,0,0,0,0,0,0,0,0,0 //WM_LESSON#Lesson#
-4105,2413,10,2417,1,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
+4105,2413,10,2414,5,0,0,0,0,0,0,0,0 //WM_METALICSOUND#Metallic Sound#
 4105,2414,5,325,5,0,0,0,0,0,0,0,0 //WM_REVERBERATION#Reverberation#
-4105,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
+//4105,2417,1,2414,1,0,0,0,0,0,0,0,0 //WM_DOMINION_IMPULSE#Dominion Impulse#
 4105,2418,5,324,5,0,0,0,0,0,0,0,0 //WM_SEVERE_RAINSTORM#Severe Rainstorm#
 4105,2419,5,2412,1,0,0,0,0,0,0,0,0 //WM_POEMOFNETHERWORLD#Poem Of The Netherworld#
 4105,2420,5,2419,3,0,0,0,0,0,0,0,0 //WM_VOICEOFSIREN#Voice Of Siren#

+ 0 - 1
doc/skill_db.txt

@@ -97,7 +97,6 @@ AllowOnWarg					- Usable while riding Warg.
 AllowOnMado					- Usable while on Madogear.
 TargetManHole				- Target enemy with SC__MANHOLE.
 TargetHidden				- Target enemy with OPTION_HIDE.
-IncreaseGloomyDayDamage		- Increase SC_GLOOMYDAY_SK damage.
 IncreaseDanceWithWugDamage	- Increase SC_DANCEWITHWUG damage.
 IgnoreWugBite				- Ignore RA_WUGBITE.
 IgnoreAutoGuard			- Not blocked by SC_AUTOGUARD (When TargetType is Weapon only).

+ 0 - 10
doc/yaml/db/improvise_db.yml

@@ -1,10 +0,0 @@
-###########################################################################
-# Improvised Song Database
-###########################################################################
-#
-# Improvised Song Settings
-#
-###########################################################################
-# - Skill             Skill to be casted by Improvised Song.
-#   Probability       Probability of skill compared to others in database (1 = 0.01%, 10000 = 100%).
-###########################################################################

+ 3 - 0
sql-files/upgrades/upgrade_2020xxxx.sql

@@ -0,0 +1,3 @@
+-- WM_DOMINION_IMPULSE
+UPDATE `char` c, `skill` s SET `c`.skill_point = `c`.skill_point + `s`.lv WHERE `s`.id = 2417 AND `c`.char_id = `s`.char_id;
+DELETE FROM `skill` WHERE `id` = 2417;

+ 21 - 23
src/map/battle.cpp

@@ -1340,6 +1340,9 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 				status_change_end(bl,SC_VOICEOFSIREN,INVALID_TIMER);
 		}
 
+		if (sc->data[SC_SOUNDOFDESTRUCTION])
+			damage <<= 1;
+
 		// Damage reductions
 		// Assumptio increases DEF on RE mode, otherwise gives a reduction on the final damage. [Igniz]
 #ifndef RENEWAL
@@ -1624,6 +1627,10 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
 			damage += damage * sce->val1 / 100;
 		if (flag & BF_MAGIC && (sce = sc->data[SC_ADD_MATK_DAMAGE]))
 			damage += damage * sce->val1 / 100;
+		if (sc->data[SC_DANCEWITHWUG] && (flag&(BF_LONG|BF_WEAPON)) == (BF_LONG|BF_WEAPON))
+			damage += damage * sc->data[SC_DANCEWITHWUG]->val1 / 100;
+		if (sc->data[SC_UNLIMITEDHUMMINGVOICE] && flag&BF_MAGIC)
+			damage += damage * sc->data[SC_UNLIMITEDHUMMINGVOICE]->val3 / 100;
 	} //End of caster SC_ check
 
 	if (tsc && tsc->count) {
@@ -2393,7 +2400,7 @@ bool is_infinite_defense(struct block_list *target, int flag)
 	if(target->type == BL_SKILL) {
 		TBL_SKILL *su = ((TBL_SKILL*)target);
 
-		if (su && su->group && (su->group->skill_id == WM_REVERBERATION || su->group->skill_id == NPC_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD))
+		if (su && su->group && (su->group->skill_id == NPC_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD))
 			return true;
 	}
 
@@ -4411,11 +4418,6 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
 				skillratio += skillratio * 25 / 100;
 			RE_LVL_DMOD(100);
 			break;
-		case WM_REVERBERATION_MELEE:
-			// ATK [{(Skill Level x 100) + 300} x Caster Base Level / 100]
-			skillratio += 200 + 100 * ((sd) ? pc_checkskill(sd, WM_REVERBERATION) : 1);
-			RE_LVL_DMOD(100);
-			break;
 		case WM_SEVERE_RAINSTORM_MELEE:
 			//ATK [{(Caster DEX + AGI) x (Skill Level / 5)} x Caster Base Level / 100] %
 			skillratio = (status_get_dex(src) + status_get_agi(src)) * skill_lv / 5;
@@ -4424,13 +4426,11 @@ static int battle_calc_attack_skill_ratio(struct Damage* wd, struct block_list *
 			RE_LVL_DMOD(100);
 			break;
 		case WM_GREAT_ECHO:
-			skillratio += 300 + 200 * skill_lv;
+			skillratio += -100 + 250 + 500 * skill_lv;
 			if (sd) {
-				int chorusbonus = battle_calc_chorusbonus(sd);
-
-				// Chorus bonus don't count the first 2 Minstrels/Wanderers and only increases when their are 3 or more. [Rytech]
-				if (chorusbonus >= 1 && chorusbonus <= 5)
-					skillratio += 100<<(chorusbonus-1); // 1->100; 2->200; 3->400; 4->800; 5->1600
+				skillratio += pc_checkskill(sd, WM_LESSON) * 50; // !TODO: Confirm bonus
+				if (skill_check_pc_partner(sd, skill_id, &skill_lv, AREA_SIZE, 0) > 0)
+					skillratio <<= 1;
 			}
 			RE_LVL_DMOD(100);
 			break;
@@ -4843,10 +4843,6 @@ static void battle_attack_sc_bonus(struct Damage* wd, struct block_list *src, st
 #endif
 			}
 		}
-		if (sc->data[SC_GLOOMYDAY_SK] && skill_get_inf2(skill_id, INF2_INCREASEGLOOMYDAYDAMAGE)) {
-			ATK_ADDRATE(wd->damage, wd->damage2, sc->data[SC_GLOOMYDAY_SK]->val2);
-			RE_ALLATK_ADDRATE(wd, sc->data[SC_GLOOMYDAY_SK]->val2);
-		}
 		if (sc->data[SC_DANCEWITHWUG]) {
 			if (skill_get_inf2(skill_id, INF2_INCREASEDANCEWITHWUGDAMAGE)) {
 				ATK_ADDRATE(wd->damage, wd->damage2, sc->data[SC_DANCEWITHWUG]->val1 * 10 * battle_calc_chorusbonus(sd));
@@ -6034,6 +6030,10 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 			if (mflag&ELE_DARK)
 				s_ele = ELE_DARK;
 			break;
+		case WM_REVERBERATION_MAGIC:
+			if (sd)
+				s_ele = sd->bonus.arrow_ele;
+			break;
 		case SO_PSYCHIC_WAVE:
 			if( sc && sc->count ) {
 				if( sc->data[SC_HEATER_OPTION] )
@@ -6449,11 +6449,13 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
 						break;
 					case WM_METALICSOUND:
 						skillratio += -100 + 120 * skill_lv + 60 * ((sd) ? pc_checkskill(sd, WM_LESSON) : 1);
+						if (tsc && tsc->data[SC_SLEEP])
+							skillratio += 100; // !TODO: Confirm target sleeping bonus
 						RE_LVL_DMOD(100);
 						break;
 					case WM_REVERBERATION_MAGIC:
-						// MATK [{(Skill Level x 100) + 100} x Casters Base Level / 100] %
-						skillratio += 100 * skill_lv;
+						// MATK [{(Skill Level x 300) + 400} x Casters Base Level / 100] %
+						skillratio += -100 + 700 + 300 * skill_lv;
 						RE_LVL_DMOD(100);
 						break;
 					case SO_FIREWALK:
@@ -7009,10 +7011,6 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
 		case NC_MAGMA_ERUPTION_DOTDAMAGE: // 'Eruption' damage
 			md.damage = 800 + 200 * skill_lv;
 			break;
-		case WM_SOUND_OF_DESTRUCTION:
-			md.damage = 1000 * skill_lv + sstatus->int_ * ((sd) ? pc_checkskill(sd,WM_LESSON) : 1);
-			md.damage += md.damage * 10 * ((sd) ? battle_calc_chorusbonus(sd) / 100 : 0);
-			break;
 		case GN_THORNS_TRAP:
 			md.damage = 100 + 200 * skill_lv + status_get_int(src);
 			break;
@@ -8099,7 +8097,7 @@ int battle_check_target( struct block_list *src, struct block_list *target,int f
 			if( !su || !su->group)
 				return 0;
 			if( skill_get_inf2(su->group->skill_id, INF2_ISTRAP) && su->group->unit_id != UNT_USED_TRAPS) {
-				if (!skill_id || su->group->skill_id == WM_REVERBERATION || su->group->skill_id == NPC_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) {
+				if (!skill_id || su->group->skill_id == NPC_REVERBERATION || su->group->skill_id == WM_POEMOFNETHERWORLD) {
 					;
 				}
 				else if (skill_get_inf2(skill_id, INF2_TARGETTRAP)) { // Only a few skills can target traps

+ 0 - 1
src/map/map-server.vcxproj

@@ -307,7 +307,6 @@
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\guild_skill_tree.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\guild_skill_tree.yml')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\homun_skill_tree.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\homun_skill_tree.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\homunculus_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\homunculus_db.txt')" />
-    <Copy SourceFiles="$(SolutionDir)db\import-tmpl\improvise_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\improvise_db.yml')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\instance_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\instance_db.yml')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\item_avail.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\item_avail.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\item_bluebox.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\item_bluebox.txt')" />

+ 1 - 1
src/map/script_constants.hpp

@@ -1582,6 +1582,7 @@
 	export_constant(SC_REF_T_POTION);
 	export_constant(SC_ADD_ATK_DAMAGE);
 	export_constant(SC_ADD_MATK_DAMAGE);
+	export_constant(SC_SOUNDOFDESTRUCTION);
 #ifdef RENEWAL
 	export_constant(SC_EXTREMITYFIST2);
 #endif
@@ -7518,7 +7519,6 @@
 	export_constant(INF2_ALLOWONMADO);
 	export_constant(INF2_TARGETMANHOLE);
 	export_constant(INF2_TARGETHIDDEN);
-	export_constant(INF2_INCREASEGLOOMYDAYDAMAGE);
 	export_constant(INF2_INCREASEDANCEWITHWUGDAMAGE);
 	export_constant(INF2_IGNOREWUGBITE);
 	export_constant(INF2_IGNOREAUTOGUARD);

+ 82 - 233
src/map/skill.cpp

@@ -89,8 +89,6 @@ static unsigned short skill_arrow_count;
 
 AbraDatabase abra_db;
 
-ImprovisedSongDatabase improvised_song_db;
-
 ReadingSpellbookDatabase reading_spellbook_db;
 
 #define MAX_SKILL_CHANGEMATERIAL_DB 75
@@ -932,6 +930,7 @@ bool skill_isNotOk(uint16 skill_id, struct map_session_data *sd)
 		case WM_SIRCLEOFNATURE:
 		case WM_SOUND_OF_DESTRUCTION:
 		case WM_LULLABY_DEEPSLEEP:
+		case WM_GLOOMYDAY:
 		case WM_SATURDAY_NIGHT_FEVER:
 			if( !mapdata_flag_vs(mapdata) ) {
 				clif_skill_teleportmessage(sd,2); // This skill uses this msg instead of skill fails.
@@ -1832,47 +1831,6 @@ int skill_additional_effect(struct block_list* src, struct block_list *bl, uint1
 	case SR_HOWLINGOFLION:
 		sc_start(src,bl, SC_FEAR, 5 + 5 * skill_lv, skill_lv, skill_get_time(skill_id, skill_lv));
 		break;
-	case WM_SOUND_OF_DESTRUCTION:
-		if( tsc && ( tsc->data[SC_SWINGDANCE] || tsc->data[SC_SYMPHONYOFLOVER] || tsc->data[SC_MOONLITSERENADE] || 
-		tsc->data[SC_RUSHWINDMILL] || tsc->data[SC_ECHOSONG] || tsc->data[SC_HARMONIZE] || 
-		tsc->data[SC_VOICEOFSIREN] || tsc->data[SC_DEEPSLEEP] || tsc->data[SC_SIRCLEOFNATURE] || 
-		tsc->data[SC_GLOOMYDAY] || tsc->data[SC_GLOOMYDAY_SK] || tsc->data[SC_SONGOFMANA] || 
-		tsc->data[SC_DANCEWITHWUG] || tsc->data[SC_SATURDAYNIGHTFEVER] || tsc->data[SC_LERADSDEW] || 
-		tsc->data[SC_MELODYOFSINK] || tsc->data[SC_BEYONDOFWARCRY] || tsc->data[SC_UNLIMITEDHUMMINGVOICE] ) && 
-		rnd()%100 < 4 * skill_lv + 2 * ((sd) ? pc_checkskill(sd, WM_LESSON) : skill_get_max(WM_LESSON)) + 10 * battle_calc_chorusbonus(sd)) {
-			status_change_start(src, bl, SC_STUN, 10000, skill_lv, 0, 0, 0, skill_get_time(skill_id,skill_lv), SCSTART_NOTICKDEF);
-			status_change_end(bl, SC_DANCING, INVALID_TIMER);
-			status_change_end(bl, SC_RICHMANKIM, INVALID_TIMER);
-			status_change_end(bl, SC_ETERNALCHAOS, INVALID_TIMER);
-			status_change_end(bl, SC_DRUMBATTLE, INVALID_TIMER);
-			status_change_end(bl, SC_NIBELUNGEN, INVALID_TIMER);
-			status_change_end(bl, SC_INTOABYSS, INVALID_TIMER);
-			status_change_end(bl, SC_SIEGFRIED, INVALID_TIMER);
-			status_change_end(bl, SC_WHISTLE, INVALID_TIMER);
-			status_change_end(bl, SC_ASSNCROS, INVALID_TIMER);
-			status_change_end(bl, SC_POEMBRAGI, INVALID_TIMER);
-			status_change_end(bl, SC_APPLEIDUN, INVALID_TIMER);
-			status_change_end(bl, SC_HUMMING, INVALID_TIMER);
-			status_change_end(bl, SC_FORTUNE, INVALID_TIMER);
-			status_change_end(bl, SC_SERVICE4U, INVALID_TIMER);
-#ifndef RENEWAL
-			status_change_end(bl, SC_LONGING, INVALID_TIMER);
-#endif
-			status_change_end(bl, SC_SWINGDANCE, INVALID_TIMER);
-			status_change_end(bl, SC_SYMPHONYOFLOVER, INVALID_TIMER);
-			status_change_end(bl, SC_MOONLITSERENADE, INVALID_TIMER);
-			status_change_end(bl, SC_RUSHWINDMILL, INVALID_TIMER);
-			status_change_end(bl, SC_ECHOSONG, INVALID_TIMER);
-			status_change_end(bl, SC_HARMONIZE, INVALID_TIMER);
-			status_change_end(bl, SC_WINKCHARM, INVALID_TIMER);
-			status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
-			status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
-			status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
-			status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
-			status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
-			status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
-		}
-		break;
 	case SO_EARTHGRAVE:
 		sc_start2(src,bl, SC_BLEEDING, 5 * skill_lv, skill_lv, src->id, skill_get_time2(skill_id, skill_lv));	// Need official rate. [LimitLine]
 		break;
@@ -3681,6 +3639,8 @@ int64 skill_attack (int attack_type, struct block_list* src, struct block_list *
 				type = DMG_SPLASH;
 			if (!(flag&SD_ANIMATION))
 				clif_skill_nodamage(dsrc, bl, skill_id, skill_lv, 1);
+			// Fall through
+		case WM_REVERBERATION_MAGIC:
 			dmg.dmotion = clif_skill_damage(dsrc, bl, tick, dmg.amotion, dmg.dmotion, damage, dmg.div_, skill_id, -2, dmg_type);
 			break;
 		case SJ_FALLINGSTAR_ATK:
@@ -3962,7 +3922,6 @@ static int skill_check_unit_range_sub(struct block_list *bl, va_list ap)
 		case SC_DIMENSIONDOOR:
 		case SC_BLOODYLUST:
 		case NPC_REVERBERATION:
-		case WM_REVERBERATION:
 		case GN_THORNS_TRAP:
 		case RL_B_TRAP:
 		case SC_ESCAPE:
@@ -4382,8 +4341,6 @@ static TIMER_FUNC(skill_timerskill){
 					}
 					break;
 				case NPC_REVERBERATION_ATK:
-				case WM_REVERBERATION_MELEE:
-				case WM_REVERBERATION_MAGIC:
 					skill_castend_damage_id(src,target,skl->skill_id,skl->skill_lv,tick,skl->flag|SD_LEVEL|SD_ANIMATION);
 					break;
 				case LG_MOONSLASHER:
@@ -4550,7 +4507,7 @@ static int skill_active_reverberation(struct block_list *bl, va_list ap) {
 
 	if (bl->type != BL_SKILL)
 		return 0;
-	if (su->alive && (sg = su->group) && (sg->skill_id == WM_REVERBERATION || sg->skill_id == NPC_REVERBERATION)) {
+	if (su->alive && (sg = su->group) && sg->skill_id == NPC_REVERBERATION) {
 		map_foreachinallrange(skill_trap_splash, bl, skill_get_splash(sg->skill_id, sg->skill_lv), sg->bl_flag, bl, gettick());
 		su->limit = DIFF_TICK(gettick(), sg->tick);
 		sg->unit_id = UNT_USED_TRAPS;
@@ -5173,8 +5130,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 	case SR_SKYNETBLOW:
 	case SR_WINDMILL:
 	case SR_RIDEINLIGHTNING:
-	case WM_REVERBERATION_MELEE:
-	case WM_REVERBERATION_MAGIC:
 	case SO_VARETYR_SPEAR:
 	case GN_CART_TORNADO:
 	case GN_CARTCANNON:
@@ -5261,8 +5216,6 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 					skill_addtimerskill(src,tick+250,src->id,0,0,skill_id,skill_lv,2,flag|BCT_ENEMY|SD_SPLASH|1);
 					break;
 				case NPC_REVERBERATION_ATK:
-				case WM_REVERBERATION_MELEE:
-				case WM_REVERBERATION_MAGIC:
 				case NC_ARMSCANNON:
 					skill_area_temp[1] = 0;
 					starget = splash_target(src);
@@ -5688,7 +5641,7 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 		break;
 	case RK_STORMBLAST:
 		if( flag&1 )
-			skill_attack(BF_WEAPON,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);
 		else {
 			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 			map_foreachinallrange(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_nodamage_id);
@@ -6075,6 +6028,16 @@ int skill_castend_damage_id (struct block_list* src, struct block_list *bl, uint
 		}
 		break;
 
+	case WM_REVERBERATION:
+		if (flag & 1)
+			skill_attack(skill_get_type(WM_REVERBERATION_MAGIC), src, src, bl, WM_REVERBERATION_MAGIC, skill_lv, tick, flag);
+		else {
+			clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
+			map_foreachinallrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR|BL_SKILL, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|SD_SPLASH|1, skill_castend_damage_id);
+			battle_consume_ammo(sd, skill_id, skill_lv); // Consume here since Magic/Misc attacks reset arrow_atk
+		}
+		break;
+
 	case SO_POISON_BUSTER:
 		if( tsc && tsc->data[SC_POISON] ) {
 			skill_attack(skill_get_type(skill_id), src, src, bl, skill_id, skill_lv, tick, flag);
@@ -10713,25 +10676,15 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			if( !status_isdead(bl) )
 				break;
 
-			if( rnd()%100 < 88 + 2 * skill_lv ) {
-				int heal = tstatus->sp;
-				if( heal <= 0 )
-					heal = 1;
-				tstatus->hp = heal;
-				tstatus->sp -= tstatus->sp * ( 60 - 10 * skill_lv ) / 100;
-				clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
-				pc_revive((TBL_PC*)bl,heal,0);
-				clif_resurrection(bl,1);
-			}
-		}
-		break;
+			int heal = tstatus->sp;
 
-	case WM_SIRCLEOFNATURE:
-		if( flag&1 )
-			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv));
-		else {
-			map_foreachinallrange(skill_area_sub,src,skill_get_splash(skill_id,skill_lv),BL_PC,src,skill_id,skill_lv,tick,flag|BCT_ALL|1,skill_castend_nodamage_id);
+			if( heal <= 0 )
+				heal = 1;
+			tstatus->hp = heal;
+			tstatus->sp -= tstatus->sp * ( 60 - 10 * skill_lv ) / 100;
 			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
+			pc_revive((TBL_PC*)bl,heal,0);
+			clif_resurrection(bl,1);
 		}
 		break;
 
@@ -10752,7 +10705,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		if( dstsd && ( pc_checkskill(dstsd,KN_BRANDISHSPEAR) || pc_checkskill(dstsd,LK_SPIRALPIERCE) ||
 				pc_checkskill(dstsd,CR_SHIELDCHARGE) || pc_checkskill(dstsd,CR_SHIELDBOOMERANG) ||
 				pc_checkskill(dstsd,PA_SHIELDCHAIN) || pc_checkskill(dstsd,LG_SHIELDPRESS) ) )
-			{
+			{ // !TODO: Which skills aren't boosted anymore?
 				sc_start(src,bl,SC_GLOOMYDAY_SK,100,skill_lv,skill_get_time(skill_id,skill_lv));
 				break;
 			}
@@ -10760,31 +10713,17 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 
 	case WM_SATURDAY_NIGHT_FEVER:
-		if( flag&1 ) {	// Affect to all targets arround the caster and caster too.
-			if (tsc && ((tsc->option&(OPTION_HIDE|OPTION_CLOAK|OPTION_CHASEWALK)) || tsc->data[SC_CAMOUFLAGE] || tsc->data[SC_STEALTHFIELD] || tsc->data[SC__SHADOWFORM]))
-				break;
-			sc_start(src,bl, type, 100, skill_lv,skill_get_time(skill_id, skill_lv));
-		} else if( flag&2 ) {
-			if( src->id != bl->id && battle_check_target(src,bl,BCT_ENEMY) > 0 )
-				status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,DMG_NORMAL,0,false),skill_id);
-		} else if( sd ) {
-			short chance = sstatus->int_/6 + sd->status.job_level/5 + skill_lv*4;
-			if( !sd->status.party_id || (rnd()%100 > chance)) {
-				clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_HELPER,0);
-				break;
+		if( flag&1 ) {
+			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv));
+		} else if (sd) {
+			if( rnd()%100 < sstatus->int_ / 6 + sd->status.job_level / 5 + skill_lv * 4 + pc_checkskill(sd, WM_LESSON) ) { // !TODO: What's the Lesson bonus?
+				map_foreachinallrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+				clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 			}
-			if( map_foreachinallrange(skill_area_sub, bl, skill_get_splash(skill_id,skill_lv),
-					BL_PC, src, skill_id, skill_lv, tick, BCT_ENEMY, skill_area_sub_count) > 7 )
-				flag |= 2;
-			else
-				flag |= 1;
-			map_foreachinallrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|BCT_SELF, skill_castend_nodamage_id);
-			clif_skill_nodamage(src, bl, skill_id, skill_lv,
-				sc_start(src,src,SC_STOP,100,skill_lv,skill_get_time2(skill_id,skill_lv)));
-			if( flag&2 ) // Dealed here to prevent conflicts
-				status_fix_damage(src,bl,9999,clif_damage(src,bl,tick,0,0,9999,0,DMG_NORMAL,0,false),skill_id);
 		}
 		break;
+
+	case WM_SIRCLEOFNATURE:
 	case WM_SONG_OF_MANA:
 	case WM_DANCE_WITH_WUG:
 	case WM_LERADS_DEW:
@@ -10792,87 +10731,58 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		if( flag&1 ) {	// These affect to to all party members near the caster.
 			struct status_change *sc = status_get_sc(src);
 			if( sc && sc->data[type] ) {
-				sc_start2(src,bl,type,100,skill_lv,battle_calc_chorusbonus(sd),skill_get_time(skill_id,skill_lv));
+				sc_start2(src,bl,type,100,skill_lv,pc_checkskill(sd, WM_LESSON),skill_get_time(skill_id,skill_lv));
 			}
 		} else if( sd ) {
-			if( sc_start2(src,bl,type,100,skill_lv,battle_calc_chorusbonus(sd),skill_get_time(skill_id,skill_lv)) )
+			if( sc_start2(src,bl,type,100,skill_lv,pc_checkskill(sd, WM_LESSON),skill_get_time(skill_id,skill_lv)) )
 				party_foreachsamemap(skill_area_sub,sd,skill_get_splash(skill_id,skill_lv),src,skill_id,skill_lv,tick,flag|BCT_PARTY|1,skill_castend_nodamage_id);
 			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 		}
 		break;
 
 	case WM_MELODYOFSINK:
-	case WM_BEYOND_OF_WARCRY:
 		if( flag&1 ) {
-			sc_start2(src,bl,type,100,skill_lv,battle_calc_chorusbonus(sd),skill_get_time(skill_id,skill_lv));
-		} else {	// These affect to all targets arround the caster.
-			if( rnd()%100 < 15 + 5 * skill_lv * 5 * battle_calc_chorusbonus(sd) ) {
+			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv));
+		} else {	// These affect to all targets around the caster.
+			if( rnd()%100 < 5 + 5 * skill_lv + pc_checkskill(sd, WM_LESSON) ) { // !TODO: What's the Lesson bonus?
 				map_foreachinallrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
 				clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
 			}
 		}
 		break;
 
-	case WM_RANDOMIZESPELL:
-		if (improvised_song_db.empty()) {
-			clif_skill_nodamage (src, bl, skill_id, skill_lv, 1);
-			break;
+	case WM_BEYOND_OF_WARCRY:
+		if( flag&1 ) {
+			sc_start(src,bl,type,100,skill_lv,skill_get_time(skill_id,skill_lv));
+		} else {	// These affect to all targets around the caster.
+			if( rnd()%100 < 12 + 3 * skill_lv + (sd ? pc_checkskill(sd, WM_LESSON) : 0) ) { // !TODO: What's the Lesson bonus?
+				map_foreachinallrange(skill_area_sub, src, skill_get_splash(skill_id,skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+				clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
+			}
 		}
-		else {
-			int improv_skill_id = 0, improv_skill_lv, checked = 0, checked_max = improvised_song_db.size() * 3;
-
-			do {
-				auto improvise_spell = improvised_song_db.random();
-
-				improv_skill_id = improvise_spell->skill_id;
-
-				if( rnd() % 10000 >= improvise_spell->per ){
-					break;
-				}
-			} while (checked++ < checked_max);
+		break;
 
-			if (!skill_get_index(improv_skill_id)) {
-				if (sd)
-					clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
-				break;
-			}
+	case WM_SOUND_OF_DESTRUCTION:
+		if (flag&1) {
+			sc_start(src, bl, type, 100, skill_lv, (sd ? pc_checkskill(sd, WM_LESSON) * 500 : 0) + skill_get_time(skill_id, skill_lv)); // !TODO: Confirm Lesson increase
+		} else {
+			map_foreachinallrange(skill_area_sub, src, skill_get_splash(skill_id, skill_lv),BL_PC, src, skill_id, skill_lv, tick, flag|BCT_ENEMY|1, skill_castend_nodamage_id);
+			clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
+		}
+		break;
 
-			improv_skill_lv = min(4 + skill_lv, skill_get_max(improv_skill_id));
-			clif_skill_nodamage (src, bl, skill_id, skill_lv, 1);
+	case WM_RANDOMIZESPELL:
+		if (rnd() % 100 < 30 + (10 * skill_lv)) {
+			status_change_end(bl, SC_SONGOFMANA, INVALID_TIMER);
+			status_change_end(bl, SC_DANCEWITHWUG, INVALID_TIMER);
+			status_change_end(bl, SC_LERADSDEW, INVALID_TIMER);
+			status_change_end(bl, SC_SATURDAYNIGHTFEVER, INVALID_TIMER);
+			status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
+			status_change_end(bl, SC_MELODYOFSINK, INVALID_TIMER);
+			status_change_end(bl, SC_BEYONDOFWARCRY, INVALID_TIMER);
+			status_change_end(bl, SC_UNLIMITEDHUMMINGVOICE, INVALID_TIMER);
 
-			if( sd ) {
-				sd->state.abra_flag = 2;
-				sd->skillitem = improv_skill_id;
-				sd->skillitemlv = improv_skill_lv;
-				sd->skillitem_keep_requirement = false;
-				clif_item_skill(sd, improv_skill_id, improv_skill_lv);
-			} else {
-				struct unit_data *ud = unit_bl2ud(src);
-				int inf = skill_get_inf(improv_skill_id);
-				if (!ud) break;
-				if (inf&INF_SELF_SKILL || inf&INF_SUPPORT_SKILL) {
-					if (src->type == BL_PET)
-						bl = (struct block_list*)((TBL_PET*)src)->master;
-					if (!bl) bl = src;
-					unit_skilluse_id(src, bl->id, improv_skill_id, improv_skill_lv);
-				} else {
-					int target_id = 0;
-					if (ud->target)
-						target_id = ud->target;
-					else switch (src->type) {
-						case BL_MOB: target_id = ((TBL_MOB*)src)->target_id; break;
-						case BL_PET: target_id = ((TBL_PET*)src)->target_id; break;
-					}
-					if (!target_id)
-						break;
-					if (skill_get_casttype(improv_skill_id) == CAST_GROUND) {
-						bl = map_id2bl(target_id);
-						if (!bl) bl = src;
-						unit_skilluse_pos(src, bl->x, bl->y, improv_skill_id, improv_skill_lv);
-					} else
-						unit_skilluse_id(src, target_id, improv_skill_id, improv_skill_lv);
-				}
-			}
+			clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
 		}
 		break;
 
@@ -10976,7 +10886,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			sc_start(src, bl, type, rate, skill_lv, duration);
 		} else {
 			clif_skill_nodamage(src, bl, skill_id, skill_lv, 1);
-			map_foreachinallrange(skill_area_sub, bl, skill_get_splash(skill_id, skill_lv), BL_CHAR, src, skill_id, skill_lv, tick, flag|BCT_ALL|BCT_WOS|1, skill_castend_nodamage_id);
+			map_foreachinallrange(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_nodamage_id);
 		}
 		break;
 
@@ -12099,7 +12009,7 @@ TIMER_FUNC(skill_castend_id){
 #endif
 		}
 
-		if (sd && ud->skill_id != SA_ABRACADABRA && ud->skill_id != WM_RANDOMIZESPELL) // they just set the data so leave it as it is.[Inkfish]
+		if (sd && ud->skill_id != SA_ABRACADABRA) // they just set the data so leave it as it is.[Inkfish]
 			sd->skillitem = sd->skillitemlv = sd->skillitem_keep_requirement = 0;
 
 		if (ud->skilltimer == INVALID_TIMER) {
@@ -12487,7 +12397,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
 	case SC_CHAOSPANIC:
 	case SC_MAELSTROM:
 	case SC_BLOODYLUST:
-	case WM_REVERBERATION:
 	case WM_POEMOFNETHERWORLD:
 	case SO_PSYCHIC_WAVE:
 	case SO_VACUUM_EXTREME:
@@ -12964,7 +12873,6 @@ int skill_castend_pos2(struct block_list* src, int x, int y, uint16 skill_id, ui
 		break;
 
 	case WM_GREAT_ECHO:
-	case WM_SOUND_OF_DESTRUCTION:
 		i = skill_get_splash(skill_id,skill_lv);
 		map_foreachinarea(skill_area_sub,src->m,x-i,y-i,x+i,y+i,BL_CHAR,src,skill_id,skill_lv,tick,flag|BCT_ENEMY|1,skill_castend_damage_id);
 		break;
@@ -13863,7 +13771,6 @@ struct skill_unit_group *skill_unitsetting(struct block_list *src, uint16 skill_
 				unit_val2 = 0;
 				break;
 			case NPC_REVERBERATION:
-			case WM_REVERBERATION:
 				unit_val1 = 1 + skill_lv;
 				break;
 			case WM_POEMOFNETHERWORLD:
@@ -15424,9 +15331,10 @@ int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16
 		struct map_session_data* tsd;
 		switch (skill_id) {
 			case PR_BENEDICTIO:
+			case WM_GREAT_ECHO:
 				for (i = 0; i < c; i++) {
 					if ((tsd = map_id2sd(p_sd[i])) != NULL)
-						status_charge(&tsd->bl, 0, 10);
+						status_charge(&tsd->bl, 0, (skill_id == PR_BENEDICTIO) ? 10 : skill_get_sp(skill_id, *skill_lv) / 2);
 				}
 				return c;
 			case AB_ADORAMUS:
@@ -15456,7 +15364,7 @@ int skill_check_pc_partner(struct map_session_data *sd, uint16 skill_id, uint16
 	memset (p_sd, 0, sizeof(p_sd));
 	i = map_foreachinallrange(skill_check_condition_char_sub, &sd->bl, range, BL_PC, &sd->bl, &c, &p_sd, skill_id);
 
-	if ( skill_id != PR_BENEDICTIO && skill_id != AB_ADORAMUS && skill_id != WL_COMET ) //Apply the average lv to encore skills.
+	if ( skill_id != PR_BENEDICTIO && skill_id != AB_ADORAMUS && skill_id != WL_COMET && skill_id != WM_GREAT_ECHO ) //Apply the average lv to encore skills.
 		*skill_lv = (i+(*skill_lv))/(c+1); //I know c should be one, but this shows how it could be used for the average of n partners.
 	return c;
 }
@@ -15680,7 +15588,7 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 	sd->state.arrow_atk = require.ammo?1:0;
 
 	// perform skill-group checks
-	if(inf2[INF2_ISCHORUS]) {
+	if(skill_id != WM_GREAT_ECHO && inf2[INF2_ISCHORUS]) {
 		if (skill_check_pc_partner(sd, skill_id, &skill_lv, AREA_SIZE, 0) < 1) {
 		    clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
 		    return false;
@@ -16247,13 +16155,10 @@ bool skill_check_condition_castbegin(struct map_session_data* sd, uint16 skill_i
 			}
 			break;
 		case WM_GREAT_ECHO: {
-				int count;
-				count = skill_check_pc_partner(sd, skill_id, &skill_lv, AREA_SIZE, 0);
-				if( count < 1 ) {
-					clif_skill_fail(sd,skill_id,USESKILL_FAIL_NEED_HELPER,0);
-					return false;
-				} else
-					require.sp -= require.sp * 20 * count / 100; //  -20% each W/M in the party.
+				int count = skill_check_pc_partner(sd, skill_id, &skill_lv, AREA_SIZE, 1);
+
+				if (count > 0)
+					require.sp -= require.sp * 20 * count / 100; // -20% each W/M in the party.
 			}
 			break;
 		case SO_FIREWALK:
@@ -16981,8 +16886,6 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint
 	if( sc ) {
 		if( sc->data[SC__LAZINESS] )
 			req.sp += req.sp + sc->data[SC__LAZINESS]->val1 * 10;
-		if (sc->data[SC_UNLIMITEDHUMMINGVOICE])
-			req.sp += req.sp * sc->data[SC_UNLIMITEDHUMMINGVOICE]->val3 / 100;
 		if( sc->data[SC_RECOGNIZEDSPELL] )
 			req.sp += req.sp / 4;
 		if( sc->data[SC_OFFERTORIUM])
@@ -16995,6 +16898,8 @@ struct s_skill_condition skill_get_requirement(struct map_session_data* sd, uint
 		if (sc->data[SC_NIBELUNGEN] && sc->data[SC_NIBELUNGEN]->val2 == RINGNBL_SPCONSUM)
 			req.sp -= req.sp * 30 / 100;
 #endif
+		if (sc->data[SC_GLOOMYDAY])
+			req.sp += req.sp * (skill_lv * 10) / 100;
 	}
 
 	req.zeny = skill->require.zeny[skill_lv-1];
@@ -17472,6 +17377,8 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
 			fixcast_r = max(fixcast_r, sc->data[SC_HEAT_BARREL]->val2);
 		if (sc->data[SC_FREEZING])
 			fixcast_r -= 50;
+		if (sc->data[SC_SWINGDANCE])
+			fixcast_r = max(fixcast_r, skill_lv * 6);
 		// Additive Fixed CastTime values
 		if (sc->data[SC_MANDRAGORA])
 			fixed += sc->data[SC_MANDRAGORA]->val1 * 500;
@@ -17479,6 +17386,8 @@ int skill_vfcastfix(struct block_list *bl, double time, uint16 skill_id, uint16
 			fixed -= 1000;
 		if (sc->data[SC_IZAYOI])
 			fixed = 0;
+		if (sc->data[SC_GLOOMYDAY])
+			fixed += skill_lv * 500;
 	}
 	if (sc && sc->data[SC_SECRAMENT] && skill_id == HW_MAGICPOWER && (flag&2)) // Sacrament lowers Mystical Amplification cast time
 		fixcast_r = max(fixcast_r, sc->data[SC_SECRAMENT]->val2);
@@ -17510,7 +17419,7 @@ int skill_delayfix(struct block_list *bl, uint16 skill_id, uint16 skill_lv)
 	nullpo_ret(bl);
 	sd = BL_CAST(BL_PC, bl);
 
-	if (skill_id == SA_ABRACADABRA || skill_id == WM_RANDOMIZESPELL)
+	if (skill_id == SA_ABRACADABRA)
 		return 0; //Will use picked skill's delay.
 
 	if (bl->type&battle_config.no_skill_delay)
@@ -18460,12 +18369,7 @@ static int skill_trap_splash(struct block_list *bl, va_list ap)
 			}
 			break;
 		case UNT_REVERBERATION: // For proper skill delay animation when used with Dominion Impulse
-			if (ss->type != BL_PC)
-				skill_addtimerskill(ss, tick + 50, bl->id, 0, 0, NPC_REVERBERATION_ATK, sg->skill_lv, BF_WEAPON, 0);
-			else {
-				skill_addtimerskill(ss, tick + status_get_amotion(ss), bl->id, 0, 0, WM_REVERBERATION_MELEE, sg->skill_lv, BF_WEAPON, 0);
-				skill_addtimerskill(ss, tick + status_get_amotion(ss) * 2, bl->id, 0, 0, WM_REVERBERATION_MAGIC, sg->skill_lv, BF_MAGIC, 0);
-			}
+			skill_addtimerskill(ss, tick + 50, bl->id, 0, 0, NPC_REVERBERATION_ATK, sg->skill_lv, BF_WEAPON, 0);
 			break;
 		case UNT_FIRINGTRAP:
 		case UNT_ICEBOUNDTRAP:
@@ -22804,60 +22708,6 @@ std::shared_ptr<s_skill_spellbook_db> ReadingSpellbookDatabase::findBook(int32 n
 	return nullptr;
 }
 
-
-const std::string ImprovisedSongDatabase::getDefaultLocation() {
-	return std::string(db_path) + "/improvise_db.yml";
-}
-
-/**
-* Reads and parses an entry from the improvise_db.
-* @param node: YAML node containing the entry.
-* @return count of successfully parsed rows
-*/
-uint64 ImprovisedSongDatabase::parseBodyNode(const YAML::Node &node) {
-	std::string skill_name;
-
-	if (!this->asString(node, "Skill", skill_name))
-		return 0;
-
-	uint16 skill_id = skill_name2id(skill_name.c_str());
-
-	if (!skill_id) {
-		this->invalidWarning(node["Skill"], "Invalid Improvised Song skill name \"%s\", skipping.\n", skill_name.c_str());
-		return 0;
-	}
-
-	if (!skill_get_inf(skill_id)) {
-		this->invalidWarning(node["Skill"], "Passive skill %s cannot be casted by Improvised Song.\n", skill_name.c_str());
-		return 0;
-	}
-
-	std::shared_ptr<s_skill_improvise_db> improvise = this->find(skill_id);
-	bool exists = improvise != nullptr;
-
-	if (!exists) {
-		if (!this->nodesExist(node, { "Probability" }))
-			return 0;
-
-		improvise = std::make_shared<s_skill_improvise_db>();
-		improvise->skill_id = skill_id;
-	}
-
-	if (this->nodeExists(node, "Probability")) {
-		uint16 probability;
-
-		if (!this->asUInt16Rate(node, "Probability", probability))
-			return 0;
-
-		improvise->per = probability;
-	}
-
-	if (!exists)
-		this->put(skill_id, improvise);
-
-	return 1;
-}
-
 const std::string MagicMushroomDatabase::getDefaultLocation() {
 	return std::string(db_path) + "/magicmushroom_db.yml";
 }
@@ -23247,7 +23097,6 @@ static void skill_readdb(void)
 	}
 
 	abra_db.load();
-	improvised_song_db.load();
 	magic_mushroom_db.load();
 	reading_spellbook_db.load();
 

+ 2 - 3
src/map/skill.hpp

@@ -101,7 +101,6 @@ enum e_skill_inf2 : uint8 {
 	INF2_ALLOWONMADO, // Skill that can be used while on Madogear
 	INF2_TARGETMANHOLE, // Skill that can be used to target while under SC__MANHOLE effect
 	INF2_TARGETHIDDEN, // Skill that affects hidden targets
-	INF2_INCREASEGLOOMYDAYDAMAGE, // Skill that affects SC_GLOOMYDAY_SK
 	INF2_INCREASEDANCEWITHWUGDAMAGE, // Skill that is affected by SC_DANCEWITHWUG
 	INF2_IGNOREWUGBITE, // Skill blocked by RA_WUGBITE
 	INF2_IGNOREAUTOGUARD , // Skill is not blocked by SC_AUTOGUARD (physical-skill only)
@@ -1693,9 +1692,9 @@ enum e_skill {
 	WM_LESSON = 2412,
 	WM_METALICSOUND,
 	WM_REVERBERATION,
-	WM_REVERBERATION_MELEE,
+	WM_REVERBERATION_MELEE, // Removed on kRO
 	WM_REVERBERATION_MAGIC,
-	WM_DOMINION_IMPULSE,
+	WM_DOMINION_IMPULSE, // Removed on kRO
 	WM_SEVERE_RAINSTORM,
 	WM_POEMOFNETHERWORLD,
 	WM_VOICEOFSIREN,

+ 50 - 71
src/map/status.cpp

@@ -927,20 +927,21 @@ void initChangeTables(void)
 	set_sc( WA_SWING_DANCE			, SC_SWINGDANCE			, EFST_SWING, SCB_SPEED|SCB_ASPD );
 	set_sc( WA_SYMPHONY_OF_LOVER		, SC_SYMPHONYOFLOVER		, EFST_SYMPHONY_LOVE, SCB_MDEF );
 	set_sc( WA_MOONLIT_SERENADE		, SC_MOONLITSERENADE		, EFST_MOONLIT_SERENADE, SCB_MATK );
-	set_sc( MI_RUSH_WINDMILL		, SC_RUSHWINDMILL		, EFST_RUSH_WINDMILL, SCB_WATK  );
+	set_sc( MI_RUSH_WINDMILL		, SC_RUSHWINDMILL		, EFST_RUSH_WINDMILL, SCB_WATK|SCB_SPEED );
 	set_sc( MI_ECHOSONG			, SC_ECHOSONG			, EFST_ECHOSONG			, SCB_DEF  );
 	set_sc( MI_HARMONIZE			, SC_HARMONIZE			, EFST_HARMONIZE			, SCB_STR|SCB_AGI|SCB_VIT|SCB_INT|SCB_DEX|SCB_LUK );
 	set_sc_with_vfx( WM_POEMOFNETHERWORLD	, SC_NETHERWORLD		, EFST_NETHERWORLD		, SCB_NONE );
 	set_sc_with_vfx( WM_VOICEOFSIREN	, SC_VOICEOFSIREN		, EFST_SIREN, SCB_NONE );
 	set_sc_with_vfx( WM_LULLABY_DEEPSLEEP	, SC_DEEPSLEEP			, EFST_HANDICAPSTATE_DEEP_SLEEP, SCB_NONE );
-	set_sc( WM_SIRCLEOFNATURE		, SC_SIRCLEOFNATURE		, EFST_SIRCLEOFNATURE		, SCB_NONE );
+	set_sc( WM_SIRCLEOFNATURE		, SC_SIRCLEOFNATURE		, EFST_SIRCLEOFNATURE		, SCB_REGEN );
 	set_sc( WM_GLOOMYDAY			, SC_GLOOMYDAY			, EFST_GLOOMYDAY			, SCB_FLEE|SCB_SPEED|SCB_ASPD );
-	set_sc( WM_SONG_OF_MANA			, SC_SONGOFMANA			, EFST_SONG_OF_MANA, SCB_NONE );
+	set_sc( WM_SONG_OF_MANA			, SC_SONGOFMANA			, EFST_SONG_OF_MANA, SCB_REGEN );
 	set_sc( WM_DANCE_WITH_WUG		, SC_DANCEWITHWUG		, EFST_DANCE_WITH_WUG, SCB_ASPD );
-	set_sc( WM_SATURDAY_NIGHT_FEVER		, SC_SATURDAYNIGHTFEVER		, EFST_SATURDAY_NIGHT_FEVER, SCB_BATK|SCB_DEF|SCB_FLEE|SCB_REGEN );
+	set_sc( WM_SOUND_OF_DESTRUCTION	, SC_SOUNDOFDESTRUCTION	, EFST_SOUND_OF_DESTRUCTION, SCB_NONE );
+	set_sc( WM_SATURDAY_NIGHT_FEVER		, SC_SATURDAYNIGHTFEVER		, EFST_SATURDAY_NIGHT_FEVER, SCB_HIT|SCB_FLEE|SCB_REGEN );
 	set_sc( WM_LERADS_DEW			, SC_LERADSDEW			, EFST_LERADS_DEW, SCB_MAXHP );
-	set_sc( WM_MELODYOFSINK			, SC_MELODYOFSINK		, EFST_MELODYOFSINK		, SCB_INT );
-	set_sc( WM_BEYOND_OF_WARCRY		, SC_BEYONDOFWARCRY		, EFST_BEYOND_OF_WARCRY, SCB_STR|SCB_CRI|SCB_MAXHP );
+	set_sc( WM_MELODYOFSINK			, SC_MELODYOFSINK		, EFST_MELODYOFSINK		, SCB_INT|SCB_MAXSP );
+	set_sc( WM_BEYOND_OF_WARCRY		, SC_BEYONDOFWARCRY		, EFST_BEYOND_OF_WARCRY, SCB_STR|SCB_MAXHP );
 	set_sc( WM_UNLIMITED_HUMMING_VOICE	, SC_UNLIMITEDHUMMINGVOICE	, EFST_UNLIMITED_HUMMING_VOICE, SCB_NONE );
 	set_sc( WM_FRIGG_SONG			, SC_FRIGG_SONG			, EFST_FRIGG_SONG			, SCB_MAXHP );
 
@@ -1560,6 +1561,8 @@ void initChangeTables(void)
 	StatusIconChangeTable[SC_USE_SKILL_SP_SPA] = EFST_USE_SKILL_SP_SPA;
 	StatusIconChangeTable[SC_USE_SKILL_SP_SHA] = EFST_USE_SKILL_SP_SHA;
 
+	StatusChangeFlagTable[SC_ANCILLA] |= SCB_REGEN;
+
 #ifdef RENEWAL
 	// renewal EDP increases your weapon atk
 	StatusChangeFlagTable[SC_EDP] |= SCB_WATK;
@@ -3337,8 +3340,6 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
 				bonus += sc->data[SC_INCMHP]->val1;
 			if(sc->data[SC_EARTH_INSIGNIA] && sc->data[SC_EARTH_INSIGNIA]->val1 == 2)
 				bonus += 500;
-			if(sc->data[SC_LERADSDEW])
-				bonus += sc->data[SC_LERADSDEW]->val3;
 			if (sc->data[SC_PROMOTE_HEALTH_RESERCH])
 				bonus += sc->data[SC_PROMOTE_HEALTH_RESERCH]->val3;
 			if(sc->data[SC_INSPIRATION])
@@ -3384,6 +3385,8 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
 				bonus += sc->data[SC_EPICLESIS]->val2;
 			if(sc->data[SC_FRIGG_SONG])
 				bonus += sc->data[SC_FRIGG_SONG]->val2;
+			if(sc->data[SC_LERADSDEW])
+				bonus += sc->data[SC_LERADSDEW]->val3;
 			if(sc->data[SC_FORCEOFVANGUARD])
 				bonus += (3 * sc->data[SC_FORCEOFVANGUARD]->val1);
 			if(sc->data[SC_INSPIRATION])
@@ -3415,7 +3418,7 @@ static int status_get_hpbonus(struct block_list *bl, enum e_status_bonus type) {
 			if(sc->data[SC_VENOMBLEED])
 				bonus -= 15;
 			if(sc->data[SC_BEYONDOFWARCRY])
-				bonus -= sc->data[SC_BEYONDOFWARCRY]->val4;
+				bonus -= sc->data[SC_BEYONDOFWARCRY]->val3;
 			if(sc->data[SC__WEAKNESS])
 				bonus -= sc->data[SC__WEAKNESS]->val2;
 			if(sc->data[SC_EQC])
@@ -3542,6 +3545,7 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
 
 		//Bonus by SC
 		if (sc) {
+			//Increasing
 			if(sc->data[SC_INCMSPRATE])
 				bonus += sc->data[SC_INCMSPRATE]->val1;
 			if(sc->data[SC_RAISINGDRAGON])
@@ -3550,6 +3554,10 @@ static int status_get_spbonus(struct block_list *bl, enum e_status_bonus type) {
 				bonus += sc->data[SC_SERVICE4U]->val2;
 			if(sc->data[SC_MERC_SPUP])
 				bonus += sc->data[SC_MERC_SPUP]->val2;
+
+			//Decreasing
+			if (sc->data[SC_MELODYOFSINK])
+				bonus -= sc->data[SC_MELODYOFSINK]->val3;
 		}
 		// Max rate reduce is -100%
 		bonus = cap_value(bonus,-100,INT_MAX);
@@ -4670,6 +4678,10 @@ int status_calc_pc_sub(struct map_session_data* sd, enum e_status_calc_opt opt)
 		if (sc->data[SC_FORTUNE])
 			sd->bonus.crit_atk_rate += 2 * sc->data[SC_FORTUNE]->val1;
 #endif
+		if (sc->data[SC_SYMPHONYOFLOVER]) {
+			sd->subele[ELE_GHOST] += sc->data[SC_SYMPHONYOFLOVER]->val1 * 3;
+			sd->subele[ELE_HOLY] += sc->data[SC_SYMPHONYOFLOVER]->val1 * 3;
+		}
 	}
 	status_cpy(&sd->battle_status, base_status);
 
@@ -5180,6 +5192,10 @@ void status_calc_regen_rate(struct block_list *bl, struct regen_data *regen, str
 			regen->rate.sp += 100;
 	}
 #endif
+	if (sc->data[SC_SIRCLEOFNATURE])
+		regen->rate.hp += sc->data[SC_SIRCLEOFNATURE]->val2;
+	if (sc->data[SC_SONGOFMANA])
+		regen->rate.sp += sc->data[SC_SONGOFMANA]->val3;
 }
 
 /**
@@ -5992,7 +6008,7 @@ static unsigned short status_calc_str(struct block_list *bl, struct status_chang
 	if(sc->data[SC_GIANTGROWTH])
 		str += 30;
 	if(sc->data[SC_BEYONDOFWARCRY])
-		str -= sc->data[SC_BEYONDOFWARCRY]->val3;
+		str -= sc->data[SC_BEYONDOFWARCRY]->val2;
 	if(sc->data[SC_SAVAGE_STEAK])
 		str += sc->data[SC_SAVAGE_STEAK]->val1;
 	if(sc->data[SC_INSPIRATION])
@@ -6226,7 +6242,7 @@ static unsigned short status_calc_int(struct block_list *bl, struct status_chang
 	if(sc->data[SC_INSPIRATION])
 		int_ += sc->data[SC_INSPIRATION]->val3;
 	if(sc->data[SC_MELODYOFSINK])
-		int_ -= sc->data[SC_MELODYOFSINK]->val3;
+		int_ -= sc->data[SC_MELODYOFSINK]->val2;
 	if(sc->data[SC_MANDRAGORA])
 		int_ -= 4 * sc->data[SC_MANDRAGORA]->val1;
 	if(sc->data[SC_COCKTAIL_WARG_BLOOD])
@@ -6473,8 +6489,6 @@ static unsigned short status_calc_batk(struct block_list *bl, struct status_chan
 		batk += batk * sc->data[SC_FLEET]->val3/100;
 	if(sc->data[SC__ENERVATION])
 		batk -= batk * sc->data[SC__ENERVATION]->val2 / 100;
-	if(sc->data[SC_SATURDAYNIGHTFEVER])
-		batk += 100 * sc->data[SC_SATURDAYNIGHTFEVER]->val1;
 	if( sc->data[SC_ZANGETSU] )
 		batk += sc->data[SC_ZANGETSU]->val2;
 	if(sc->data[SC_QUEST_BUFF1])
@@ -6765,10 +6779,10 @@ static signed short status_calc_critical(struct block_list *bl, struct status_ch
 		critical += sc->data[SC__INVISIBILITY]->val3 * 10;
 	if (sc->data[SC__UNLUCKY])
 		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;
+	if(sc->data[SC_BEYONDOFWARCRY])
+		critical += sc->data[SC_BEYONDOFWARCRY]->val3;
 
 	return (short)cap_value(critical,10,SHRT_MAX);
 }
@@ -6835,6 +6849,8 @@ static signed short status_calc_hit(struct block_list *bl, struct status_change
 #endif
 	if (sc->data[SC_SOULFALCON])
 		hit += sc->data[SC_SOULFALCON]->val3;
+	if (sc->data[SC_SATURDAYNIGHTFEVER])
+		hit -= 50 + 50 * sc->data[SC_SATURDAYNIGHTFEVER]->val1;
 
 	return (short)cap_value(hit,1,SHRT_MAX);
 }
@@ -6924,7 +6940,7 @@ static signed short status_calc_flee(struct block_list *bl, struct status_change
 	if( sc->data[SC_GLOOMYDAY] )
 		flee -= flee * sc->data[SC_GLOOMYDAY]->val2 / 100;
 	if( sc->data[SC_SATURDAYNIGHTFEVER] )
-		flee -= flee * (40 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
+		flee -= 20 + 30 * sc->data[SC_SATURDAYNIGHTFEVER]->val1;
 	if( sc->data[SC_WIND_STEP_OPTION] )
 		flee += flee * sc->data[SC_WIND_STEP_OPTION]->val2 / 100;
 	if( sc->data[SC_TINDER_BREAKER] || sc->data[SC_TINDER_BREAKER2] )
@@ -7052,9 +7068,7 @@ static defType status_calc_def(struct block_list *bl, struct status_change *sc,
 	if( sc->data[SC_BANDING] && sc->data[SC_BANDING]->val2 > 1 )
 		def += (5 + sc->data[SC_BANDING]->val1) * sc->data[SC_BANDING]->val2 / 10;
 	if( sc->data[SC_ECHOSONG] )
-		def += def * sc->data[SC_ECHOSONG]->val3 / 100;
-	if( sc->data[SC_SATURDAYNIGHTFEVER] )
-		def -= def * (10 + 10 * sc->data[SC_SATURDAYNIGHTFEVER]->val1) / 100;
+		def += sc->data[SC_ECHOSONG]->val3;
 	if( sc->data[SC_EARTHDRIVE] )
 		def -= def * 25 / 100;
 	if( sc->data[SC_CAMOUFLAGE] )
@@ -7409,6 +7423,8 @@ static unsigned short status_calc_speed(struct block_list *bl, struct status_cha
 			val = max(val, sc->data[SC_ARCLOUSEDASH]->val3);
 		if( sc->data[SC_DORAM_WALKSPEED] )
 			val = max(val, sc->data[SC_DORAM_WALKSPEED]->val1);
+		if (sc->data[SC_RUSHWINDMILL])
+			val = max(val, 25); // !TODO: Confirm bonus movement speed
 
 		// !FIXME: official items use a single bonus for this [ultramage]
 		if( sc->data[SC_SPEEDUP0] ) // Temporary item-based speedup
@@ -11325,17 +11341,17 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			tick_time = 1000; // [GodLesZ] tick time
 			break;
 		case SC_SWINGDANCE:
-			val3 = 5 * val1 + val2; // Walk speed and aspd reduction.
+			val3 = 3 * val1 + val2; // Walk speed and aspd reduction.
 			break;
 		case SC_SYMPHONYOFLOVER:
-			val3 = 12 * val1 + val2 + (sd?sd->status.job_level:50) / 4; // MDEF Increase in %
+			val3 = 2 * val1 + val2 + (sd?sd->status.job_level:50) / 4; // MDEF Increase
 			break;
 		case SC_MOONLITSERENADE: // MATK Increase
 		case SC_RUSHWINDMILL: // ATK Increase
-			val3 = 6 * val1 + val2 + (sd?sd->status.job_level:50) / 5;
+			val3 = 4 + val1 * 3 + val2 + (sd?sd->status.job_level:50) / 5;
 			break;
 		case SC_ECHOSONG:
-			val3 = 6 * val1 + val2 + (sd?sd->status.job_level:50) / 4; // DEF Increase in %
+			val3 = 6 * val1 + val2 + (sd?sd->status.job_level:50) / 4; // DEF Increase
 			break;
 		case SC_HARMONIZE:
 			val2 = 5 + 5 * val1;
@@ -11349,15 +11365,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			tick_time = 2000; // [GodLesZ] tick time
 			break;
 		case SC_SIRCLEOFNATURE:
-			val2 = 40 * val1; // HP recovery
-			val3 = 4 * val1;	// SP consume
-			val4 = tick / 1000;
-			tick_time = 1000; // [GodLesZ] tick time
+			val2 = 50 * val1; // HP recovery rate
 			break;
 		case SC_SONGOFMANA:
-			val3 = 10 + min(5 * val2, 35);
-			val4 = tick/5000;
-			tick_time = 5000; // [GodLesZ] tick time
+			status_heal(bl, 0, status->max_sp * (val1 <= 2 ? 10 : val1 <= 4 ? 15 : 20) / 100, 1);
+			val3 = 50 * val1;
 			break;
 		case SC_SATURDAYNIGHTFEVER:
 			if (!val4) val4 = skill_get_time2(status_sc2skill(type),val1);
@@ -11387,28 +11399,22 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
 			}
 			break;
 		case SC_DANCEWITHWUG:
-			val3 = 5 + 5 * val2; // ASPD Increase
-			val4 = 20 + 10 * val2; // Fixed Cast Time Reduction
+			val3 = 5 * val1; // ASPD Increase
+			val4 = 20 + 10 * val1; // Fixed Cast Time Reduction
 			break;
 		case SC_LERADSDEW:
-			val3 = 200 * val1 + min(300 * val2, 2500); // MaxHP Increase
+			val3 = 2 + 3 * val1 + min(3 * val2, 25); // MaxHP Increase
 			break;
 		case SC_MELODYOFSINK:
-			val3 = val1 * val2; // INT Reduction.
-			val4 = tick/1000;
-			tick_time = 1000;
+			val2 = 10 * val1; // INT Reduction.
+			val3 = 2 + 2 * val1; // MaxSP reduction
 			break;
 		case SC_BEYONDOFWARCRY:
-			val3 = val1 * val2; // STR and CRIT Reduction
-			val4 = 4 * val1 + min(4 * (val2 - 2), 40); // MaxHP Reduction
+			val2 = 10 + 10 * val1; // STR Reduction
+			val3 = 4 * val1; // MaxHP Reduction
 			break;
 		case SC_UNLIMITEDHUMMINGVOICE:
-			{
-				struct unit_data *ud = unit_bl2ud(bl);
-				if( ud == NULL ) return 0;
-				ud->state.skillcastcancel = 0;
-				val3 = 15 - min(3 * val2, 15);
-			}
+			val3 = 4 * val1 + min(3 * val2, 15); // !TODO: What's the Lesson bonus?
 			break;
 		case SC_REFLECTDAMAGE:
 			val2 = 15 + 5 * val1; // Reflect amount
@@ -14268,25 +14274,6 @@ TIMER_FUNC(status_change_timer){
 		}
 		break;
 
-	case SC_SIRCLEOFNATURE:
-		if( --(sce->val4) >= 0 ) {
-			if( !status_charge(bl,0,sce->val3) )
-				break;
-			status_heal(bl, sce->val2, 0, 1);
-			sc_timer_next(1000 + tick);
-			return 0;
-		}
-		break;
-
-	case SC_SONGOFMANA:
-		if( --(sce->val4) >= 0 ) {
-			status_heal(bl,0,sce->val3,3);
-			sc_timer_next(5000 + tick);
-			return 0;
-		}
-		break;
-
-
 	case SC_SATURDAYNIGHTFEVER:
 		// 1% HP/SP drain every val4 seconds [Jobbie]
 		if( --(sce->val3) >= 0 ) {
@@ -14297,14 +14284,6 @@ TIMER_FUNC(status_change_timer){
 		}
 		break;
 
-	case SC_MELODYOFSINK:
-		if( --(sce->val4) >= 0 ) {
-			status_charge(bl, 0, status->max_sp * ( 2 * sce->val1 + 2 * sce->val2 ) / 100);
-			sc_timer_next(1000+tick);
-			return 0;
-		}
-		break;
-
 	case SC_CRYSTALIZE:
 		if( --(sce->val4) >= 0 ) { // Drains 2% of HP and 1% of SP every seconds.
 			if (!status_charge(bl, status->max_hp * 2 / 100, status->max_sp / 100))

+ 1 - 0
src/map/status.hpp

@@ -928,6 +928,7 @@ enum sc_type : int16 {
 	SC_ADD_MATK_DAMAGE,
 
 	SC_HELPANGEL,
+	SC_SOUNDOFDESTRUCTION,
 
 #ifdef RENEWAL
 	SC_EXTREMITYFIST2, //! NOTE: This SC should be right before SC_MAX, so it doesn't disturb if RENEWAL is disabled

+ 0 - 28
src/tool/csv2yaml.cpp

@@ -91,7 +91,6 @@ static bool guild_read_guildskill_tree_db( char* split[], int columns, int curre
 static bool pet_read_db( const char* file );
 static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current);
 static bool skill_parse_row_abradb(char* split[], int columns, int current);
-static bool skill_parse_row_improvisedb(char* split[], int columns, int current);
 static bool skill_parse_row_spellbookdb(char* split[], int columns, int current);
 static bool mob_readdb_mobavail(char *str[], int columns, int current);
 static bool skill_parse_row_requiredb(char* split[], int columns, int current);
@@ -325,12 +324,6 @@ int do_init( int argc, char** argv ){
 		return 0;
 	}
 
-	if (!process("IMPROVISED_SONG_DB", 1, root_paths, "skill_improvise_db", [](const std::string& path, const std::string& name_ext) -> bool {
-		return sv_readdb(path.c_str(), name_ext.c_str(), ',', 2, 2, -1, &skill_parse_row_improvisedb, false);
-	}, "improvise_db")) {
-		return 0;
-	}
-
 	if (!process("READING_SPELLBOOK_DB", 1, root_paths, "spellbook_db", [](const std::string& path, const std::string& name_ext) -> bool {
 		return sv_readdb(path.c_str(), name_ext.c_str(), ',', 3, 3, -1, &skill_parse_row_spellbookdb, false);
 	})) {
@@ -930,25 +923,6 @@ static bool skill_parse_row_abradb(char* split[], int columns, int current)
 	return true;
 }
 
-// Copied and adjusted from skill.cpp
-static bool skill_parse_row_improvisedb(char* split[], int columns, int current)
-{
-	uint16 skill_id = atoi(split[0]);
-	std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
-
-	if (skill_name == nullptr) {
-		ShowError("Skill name for Improvised Song skill ID %hu is not known.\n", skill_id);
-		return false;
-	}
-
-	body << YAML::BeginMap;
-	body << YAML::Key << "Skill" << YAML::Value << *skill_name;
-	body << YAML::Key << "Probability" << YAML::Value << atoi(split[1]) / 10;
-	body << YAML::EndMap;
-
-	return true;
-}
-
 // Copied and adjusted from skill.cpp
 static bool skill_parse_row_spellbookdb(char* split[], int columns, int current)
 {
@@ -1591,8 +1565,6 @@ static bool skill_parse_row_skilldb(char* split[], int columns, int current) {
 			body << YAML::Key << "TargetManHole" << YAML::Value << "true";
 		if (inf3_val & 0x10000)
 			body << YAML::Key << "TargetHidden" << YAML::Value << "true";
-		if (inf3_val & 0x20000)
-			body << YAML::Key << "IncreaseGloomyDayDamage" << YAML::Value << "true";
 		if (inf3_val & 0x40000)
 			body << YAML::Key << "IncreaseDanceWithWugDamage" << YAML::Value << "true";
 		if (inf3_val & 0x80000)