瀏覽代碼

Merge remote-tracking branch 'upstream/master' into refactor/cmake

Vincent Stumpf 1 年之前
父節點
當前提交
c789cdbadd
共有 60 個文件被更改,包括 3684 次插入1945 次删除
  1. 1 1
      CMakeLists.txt
  2. 1 1
      README.md
  3. 4 4
      configure
  4. 4 4
      configure.ac
  5. 8 1
      db/job_stats.yml
  6. 340 0
      db/pre-re/job_aspd.yml
  7. 0 450
      db/pre-re/job_stats.yml
  8. 2 2
      db/pre-re/produce_db.txt
  9. 1 1
      db/re/item_db_equip.yml
  10. 28 0
      db/re/item_db_etc.yml
  11. 20 0
      db/re/item_db_usable.yml
  12. 616 0
      db/re/job_aspd.yml
  13. 0 565
      db/re/job_stats.yml
  14. 4 4
      db/re/produce_db.txt
  15. 140 0
      db/re/quest_db.yml
  16. 57 0
      db/re/skill_db.yml
  17. 1559 0
      npc/re/quests/illusion_investigation.txt
  18. 1 0
      npc/re/scripts_athena.conf
  19. 4 0
      npc/re/warps/cities/prontera.txt
  20. 4 4
      src/char/char-server.vcxproj
  21. 227 229
      src/char/int_guild.cpp
  22. 8 1
      src/char/int_guild.hpp
  23. 4 4
      src/common/common-minicore.vcxproj
  24. 4 4
      src/common/common.vcxproj
  25. 3 3
      src/common/core.cpp
  26. 6 0
      src/common/database.cpp
  27. 2 0
      src/common/mapindex.hpp
  28. 1 8
      src/common/mmo.hpp
  29. 4 4
      src/login/login-server.vcxproj
  30. 45 55
      src/map/atcommand.cpp
  31. 4 4
      src/map/battle.cpp
  32. 4 4
      src/map/battleground.cpp
  33. 19 19
      src/map/channel.cpp
  34. 2 2
      src/map/channel.hpp
  35. 119 136
      src/map/clif.cpp
  36. 7 7
      src/map/clif.hpp
  37. 1 2
      src/map/elemental.cpp
  38. 217 232
      src/map/guild.cpp
  39. 20 11
      src/map/guild.hpp
  40. 11 11
      src/map/instance.cpp
  41. 17 18
      src/map/intif.cpp
  42. 9 2
      src/map/itemdb.cpp
  43. 9 3
      src/map/itemdb.hpp
  44. 4 4
      src/map/map-server-generator.vcxproj
  45. 4 4
      src/map/map-server.vcxproj
  46. 16 18
      src/map/mob.cpp
  47. 1 1
      src/map/navi.cpp
  48. 1 1
      src/map/path.cpp
  49. 9 11
      src/map/pc.cpp
  50. 3 1
      src/map/pc.hpp
  51. 44 52
      src/map/script.cpp
  52. 37 32
      src/map/skill.cpp
  53. 3 0
      src/map/skill.hpp
  54. 2 2
      src/map/status.cpp
  55. 3 3
      src/map/storage.cpp
  56. 4 4
      src/tool/csv2yaml.vcxproj
  57. 4 4
      src/tool/mapcache.vcxproj
  58. 4 4
      src/tool/yaml2sql.vcxproj
  59. 4 4
      src/tool/yamlupgrade.vcxproj
  60. 4 4
      src/web/web-server.vcxproj

+ 1 - 1
CMakeLists.txt

@@ -52,7 +52,7 @@ if(WIN32)
 endif()
 
 # Configure C++ Standard
-set(CMAKE_CXX_STANDARD 14)
+set(CMAKE_CXX_STANDARD 17)
 set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
 

+ 1 - 1
README.md

@@ -29,7 +29,7 @@ Disk Space | 300 MB | 500 MB
 ### Operating System & Preferred Compiler
 Operating System | Compiler
 ------|------
-Linux  | [gcc-5 or newer](https://www.gnu.org/software/gcc/gcc-5/) / [Make](https://www.gnu.org/software/make/)
+Linux  | [gcc-6 or newer](https://www.gnu.org/software/gcc/gcc-6/) / [Make](https://www.gnu.org/software/make/)
 Windows | [MS Visual Studio 2017 or newer](https://www.visualstudio.com/downloads/)
 
 ### Required Applications

+ 4 - 4
configure

@@ -4538,9 +4538,9 @@ ac_compiler_gnu=$ac_cv_cxx_compiler_gnu
 
 CFLAGS="$CFLAGS -pipe -ffast-math -Wall"
 CPPFLAGS="$CPPFLAGS -I../common"
-CXXFLAGS="$CXXFLAGS -std=c++14"
-#CXXFLAGS="$CXXFLAGS -std=gnu++14"
-CXXFLAG_CLEARS="-std=c++14"
+CXXFLAGS="$CXXFLAGS -std=c++17"
+#CXXFLAGS="$CXXFLAGS -std=gnu++17"
+CXXFLAG_CLEARS="-std=c++17"
 
  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether byte ordering is bigendian" >&5
 $as_echo_n "checking whether byte ordering is bigendian... " >&6; }
@@ -7109,7 +7109,7 @@ else
 $as_echo "no" >&6; }
 fi
 
-CXXFLAG_CLEARS="-std=c++14 $CPPFLAGS"
+CXXFLAG_CLEARS="-std=c++17 $CPPFLAGS"
 CFLAGS="$OPT_LTO $CFLAGS"
 CFLAGS_AR="$OPT_LTO_AR $CFLAGS"
 

+ 4 - 4
configure.ac

@@ -483,9 +483,9 @@ AC_LANG([C++])
 
 CFLAGS="$CFLAGS -pipe -ffast-math -Wall"
 CPPFLAGS="$CPPFLAGS -I../common"
-CXXFLAGS="$CXXFLAGS -std=c++14"
-#CXXFLAGS="$CXXFLAGS -std=gnu++14"
-CXXFLAG_CLEARS="-std=c++14"
+CXXFLAGS="$CXXFLAGS -std=c++17"
+#CXXFLAGS="$CXXFLAGS -std=gnu++17"
+CXXFLAG_CLEARS="-std=c++17"
 
 AC_C_BIGENDIAN(
 	[AC_MSG_ERROR([[bigendian is not supported... stopping]])],
@@ -1355,7 +1355,7 @@ else
 	AC_MSG_RESULT([no])
 fi
 
-CXXFLAG_CLEARS="-std=c++14 $CPPFLAGS"
+CXXFLAG_CLEARS="-std=c++17 $CPPFLAGS"
 CFLAGS="$OPT_LTO $CFLAGS" 
 CFLAGS_AR="$OPT_LTO_AR $CFLAGS"
 AC_SUBST([CFLAGS_AR])

+ 8 - 1
db/job_stats.yml

@@ -82,12 +82,19 @@ Header:
 
 Footer:
   Imports:
-  # Import base information first
+  # Load base information first
   - Path: db/pre-re/job_stats.yml
     Mode: Prerenewal
   - Path: db/re/job_stats.yml
     Mode: Renewal
 
+  # Next, populate with ASPD information
+  # If RENEWAL is defined and RENEWAL_ASPD is not defined then the pre-renewal file is loaded
+  - Path: db/pre-re/job_aspd.yml
+    Mode: Prerenewal
+  - Path: db/re/job_aspd.yml
+    Mode: Renewal
+
   # Next, populate with experience information
   - Path: db/pre-re/job_exp.yml
     Mode: Prerenewal

+ 340 - 0
db/pre-re/job_aspd.yml

@@ -0,0 +1,340 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2021 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/>.
+#
+###########################################################################
+# Job Database
+###########################################################################
+#
+# Job Settings
+#
+###########################################################################
+# - Jobs:                    List of jobs associated to group.
+#     Job                    Job name.
+#   MaxWeight                Base maximum weight. (Default: 20000)
+#   HpFactor                 Exponential HP increase. Per base level: [HpFactor * BaseLv / 100]. Used when macro HP_SP_TABLES is disabled. (Default: 0)
+#   HpIncrease               Linear HP increase. Per base level: [HpIncrease / 100]. Used when macro HP_SP_TABLES is disabled. (Default: 500)
+#   SpIncrease               Linear SP increase. Per base level: [SpIncrease / 100]. Used when macro HP_SP_TABLES is disabled. (Default: 100)
+#   BaseASPD:                Base ASPD for each weapon type. (Default: 2000)
+#     Weapon                 Weapon type with associated ASPD.
+#   BonusStats:              Job level bonus stats/traits.
+#     - Level                Job level.
+#       Str                  Stength increase amount. (Default: 0)
+#       Agi                  Agility increase amount. (Default: 0)
+#       Vit                  Vitality increase amount. (Default: 0)
+#       Int                  Intelligence increase amount. (Default: 0)
+#       Dex                  Dexterity increase amount. (Default: 0)
+#       Luk                  Luck increase amount. (Default: 0)
+#       Pow                  Power increase amount. (Default: 0)
+#       Sta                  Stamina increase amount. (Default: 0)
+#       Wis                  Wisdom increase amount. (Default: 0)
+#       Spl                  Spell increase amount. (Default: 0)
+#       Con                  Concentration increase amount. (Default: 0)
+#       Crt                  Creative increase amount. (Default: 0)
+#   MaxStats:                Maximum stats/traits applicable. (Default: battle_config::max_*_parameter)
+#     Str                    Strength.
+#     Agi                    Agility.
+#     Vit                    Vitality.
+#     Int                    Intelligence.
+#     Dex                    Dexterity.
+#     Luk                    Luck.
+#     Pow                    Power.
+#     Sta                    Stamina.
+#     Wis                    Wisdom.
+#     Spl                    Spell.
+#     Con                    Concentration.
+#     Crt                    Creative.
+#   MaxBaseLevel             Maximum base level. (Default: MAX_LEVEL)
+#   BaseExp:                 Base experience per level.
+#     - Level                Base level.
+#       Exp                  Base experience.
+#   MaxJobLevel              Maximum job level. (Default: MAX_LEVEL)
+#   JobExp:                  Job experience per level.
+#     - Level                Job level.
+#       Exp                  Job experience.
+#   BaseHp:                  Base HP per base level.
+#     - Level                Base level.
+#       Hp                   Base HP.
+#   BaseSp:                  Base SP per base level.
+#     - Level                Base level.
+#       Sp                   Base SP.
+#   BaseAp:                  Base AP per base level.
+#     - Level                Base level.
+#       Ap                   Base AP.
+###########################################################################
+
+Header:
+  Type: JOB_STATS
+  Version: 2
+
+Body:
+  - Jobs:
+      Novice: true
+      Super_Novice: true
+      Novice_High: true
+      Baby: true
+      Super_Baby: true
+    BaseASPD:
+      Fist: 500
+      Dagger: 650
+      1hSword: 700
+      1hAxe: 800
+      Mace: 700
+      2hMace: 700
+      Staff: 650
+      2hStaff: 650
+  - Jobs:
+      Swordman: true
+      Swordman_High: true
+      Baby_Swordman: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 500
+      1hSword: 550
+      2hSword: 600
+      1hSpear: 650
+      2hSpear: 700
+      1hAxe: 700
+      2hAxe: 750
+      Mace: 650
+      2hMace: 700
+  - Jobs:
+      Mage: true
+      Mage_High: true
+      Baby_Mage: true
+    BaseASPD:
+      Fist: 500
+      Dagger: 600
+      Staff: 700
+      2hStaff: 700
+  - Jobs:
+      Archer: true
+      Archer_High: true
+      Baby_Archer: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 600
+      Bow: 700
+  - Jobs:
+      Acolyte: true
+      Acolyte_High: true
+      Baby_Acolyte: true
+    BaseASPD:
+      Fist: 400
+      Mace: 600
+      2hMace: 600
+      Staff: 600
+      2hStaff: 600
+  - Jobs:
+      Merchant: true
+      Merchant_High: true
+      Baby_Merchant: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 600
+      1hSword: 700
+      1hAxe: 700
+      2hAxe: 750
+      Mace: 700
+      2hMace: 700
+  - Jobs:
+      Thief: true
+      Thief_High: true
+      Baby_Thief: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 500
+      1hSword: 650
+      1hAxe: 800
+      Bow: 800
+  - Jobs:
+      Knight: true
+      Knight2: true
+      Lord_Knight: true
+      Lord_Knight2: true
+      Baby_Knight: true
+      Baby_Knight2: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 500
+      1hSword: 500
+      2hSword: 550
+      1hSpear: 600
+      2hSpear: 600
+      1hAxe: 700
+      2hAxe: 700
+      Mace: 650
+      2hMace: 700
+  - Jobs:
+      Priest: true
+      High_Priest: true
+      Baby_Priest: true
+    BaseASPD:
+      Fist: 400
+      Mace: 600
+      2hMace: 600
+      Staff: 600
+      Book: 600
+      2hStaff: 600
+  - Jobs:
+      Wizard: true
+      High_Wizard: true
+      Baby_Wizard: true
+    BaseASPD:
+      Fist: 500
+      Dagger: 575
+      Staff: 625
+      2hStaff: 625
+  - Jobs:
+      Blacksmith: true
+      Whitesmith: true
+      Baby_Blacksmith: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 600
+      1hSword: 650
+      1hAxe: 650
+      2hAxe: 650
+      Mace: 675
+      2hMace: 675
+  - Jobs:
+      Hunter: true
+      Sniper: true
+      Baby_Hunter: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 600
+      Bow: 600
+  - Jobs:
+      Assassin: true
+      Assassin_Cross: true
+      Baby_Assassin: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 500
+      1hSword: 650
+      1hAxe: 800
+      Katar: 500
+  - Jobs:
+      Crusader: true
+      Crusader2: true
+      Paladin: true
+      Paladin2: true
+      Baby_Crusader: true
+      Baby_Crusader2: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 500
+      1hSword: 500
+      2hSword: 550
+      1hSpear: 600
+      2hSpear: 600
+      1hAxe: 700
+      2hAxe: 700
+      Mace: 650
+      2hMace: 700
+  - Jobs:
+      Monk: true
+      Champion: true
+      Baby_Monk: true
+    BaseASPD:
+      Fist: 400
+      Mace: 575
+      2hMace: 575
+      Staff: 575
+      Knuckle: 475
+      2hStaff: 575
+  - Jobs:
+      Sage: true
+      Professor: true
+      Baby_Sage: true
+    BaseASPD:
+      Fist: 450
+      Dagger: 525
+      Staff: 625
+      Book: 550
+      2hStaff: 625
+  - Jobs:
+      Rogue: true
+      Stalker: true
+      Baby_Rogue: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 500
+      1hSword: 550
+      Bow: 650
+  - Jobs:
+      Alchemist: true
+      Creator: true
+      Baby_Alchemist: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 550
+      1hSword: 575
+      1hAxe: 675
+      2hAxe: 700
+      Mace: 650
+      2hMace: 650
+  - Jobs:
+      Bard: true
+      Clown: true
+      Baby_Bard: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 550
+      Bow: 650
+      Musical: 575
+  - Jobs:
+      Dancer: true
+      Gypsy: true
+      Baby_Dancer: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 550
+      Bow: 650
+      Whip: 575
+  - Jobs:
+      Gunslinger: true
+    BaseASPD:
+      Fist: 500
+      Revolver: 700
+      Rifle: 750
+      Gatling: 700
+      Shotgun: 1500
+      Grenade: 1500
+  - Jobs:
+      Ninja: true
+    BaseASPD:
+      Fist: 400
+      Dagger: 500
+      Huuma: 750
+  - Jobs:
+      Taekwon: true
+    BaseASPD:
+      Fist: 400
+  - Jobs:
+      Star_Gladiator: true
+      Star_Gladiator2: true
+    BaseASPD:
+      Fist: 400
+      Book: 500
+  - Jobs:
+      Soul_Linker: true
+    BaseASPD:
+      Fist: 500
+      Dagger: 575
+      Staff: 625
+      2hStaff: 625

+ 0 - 450
db/pre-re/job_stats.yml

@@ -83,15 +83,6 @@ Header:
 Body:
   - Jobs:
       Novice: true
-    BaseASPD:
-      Fist: 500
-      Dagger: 650
-      1hSword: 700
-      1hAxe: 800
-      Mace: 700
-      2hMace: 700
-      Staff: 650
-      2hStaff: 650
     BonusStats:
       - Level: 2
         Luk: 1
@@ -110,17 +101,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 70
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 550
-      2hSword: 600
-      1hSpear: 650
-      2hSpear: 700
-      1hAxe: 700
-      2hAxe: 750
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 2
         Str: 1
@@ -163,11 +143,6 @@ Body:
     MaxWeight: 22000
     HpFactor: 30
     SpIncrease: 600
-    BaseASPD:
-      Fist: 500
-      Dagger: 600
-      Staff: 700
-      2hStaff: 700
     BonusStats:
       - Level: 2
         Int: 1
@@ -210,10 +185,6 @@ Body:
     MaxWeight: 26000
     HpFactor: 50
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      Bow: 700
     BonusStats:
       - Level: 2
         Dex: 1
@@ -256,12 +227,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 40
     SpIncrease: 500
-    BaseASPD:
-      Fist: 400
-      Mace: 600
-      2hMace: 600
-      Staff: 600
-      2hStaff: 600
     BonusStats:
       - Level: 2
         Luk: 1
@@ -304,14 +269,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 40
     SpIncrease: 300
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      1hSword: 700
-      1hAxe: 700
-      2hAxe: 750
-      Mace: 700
-      2hMace: 700
     BonusStats:
       - Level: 2
         Vit: 1
@@ -354,12 +311,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 50
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 650
-      1hAxe: 800
-      Bow: 800
     BonusStats:
       - Level: 2
         Agi: 1
@@ -403,17 +354,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 150
     SpIncrease: 300
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 500
-      2hSword: 550
-      1hSpear: 600
-      2hSpear: 600
-      1hAxe: 700
-      2hAxe: 700
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 1
         Vit: 1
@@ -480,13 +420,6 @@ Body:
     MaxWeight: 26000
     HpFactor: 75
     SpIncrease: 800
-    BaseASPD:
-      Fist: 400
-      Mace: 600
-      2hMace: 600
-      Staff: 600
-      Book: 600
-      2hStaff: 600
     BonusStats:
       - Level: 1
         Luk: 1
@@ -553,11 +486,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 55
     SpIncrease: 900
-    BaseASPD:
-      Fist: 500
-      Dagger: 575
-      Staff: 625
-      2hStaff: 625
     BonusStats:
       - Level: 1
         Int: 1
@@ -624,14 +552,6 @@ Body:
     MaxWeight: 30000
     HpFactor: 90
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      1hSword: 650
-      1hAxe: 650
-      2hAxe: 650
-      Mace: 675
-      2hMace: 675
     BonusStats:
       - Level: 1
         Dex: 1
@@ -698,10 +618,6 @@ Body:
     MaxWeight: 27000
     HpFactor: 85
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      Bow: 600
     BonusStats:
       - Level: 1
         Dex: 1
@@ -768,12 +684,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 110
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 650
-      1hAxe: 800
-      Katar: 500
     BonusStats:
       - Level: 1
         Agi: 1
@@ -842,17 +752,6 @@ Body:
     HpFactor: 110
     HpIncrease: 700
     SpIncrease: 470
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 500
-      2hSword: 550
-      1hSpear: 600
-      2hSpear: 600
-      1hAxe: 700
-      2hAxe: 700
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 1
         Luk: 1
@@ -920,13 +819,6 @@ Body:
     HpFactor: 90
     HpIncrease: 650
     SpIncrease: 470
-    BaseASPD:
-      Fist: 400
-      Mace: 575
-      2hMace: 575
-      Staff: 575
-      Knuckle: 475
-      2hStaff: 575
     BonusStats:
       - Level: 1
         Str: 1
@@ -993,12 +885,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 75
     SpIncrease: 700
-    BaseASPD:
-      Fist: 450
-      Dagger: 525
-      Staff: 625
-      Book: 550
-      2hStaff: 625
     BonusStats:
       - Level: 1
         Int: 1
@@ -1065,11 +951,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 85
     SpIncrease: 500
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 550
-      Bow: 650
     BonusStats:
       - Level: 1
         Agi: 1
@@ -1136,14 +1017,6 @@ Body:
     MaxWeight: 30000
     HpFactor: 90
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      1hSword: 575
-      1hAxe: 675
-      2hAxe: 700
-      Mace: 650
-      2hMace: 650
     BonusStats:
       - Level: 1
         Int: 1
@@ -1211,11 +1084,6 @@ Body:
     HpFactor: 75
     HpIncrease: 300
     SpIncrease: 600
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      Bow: 650
-      Musical: 575
     BonusStats:
       - Level: 1
         Dex: 1
@@ -1283,11 +1151,6 @@ Body:
     HpFactor: 75
     HpIncrease: 300
     SpIncrease: 600
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      Bow: 650
-      Whip: 575
     BonusStats:
       - Level: 1
         Luk: 1
@@ -1351,15 +1214,6 @@ Body:
         Luk: 1
   - Jobs:
       Supernovice: true
-    BaseASPD:
-      Fist: 500
-      Dagger: 650
-      1hSword: 700
-      1hAxe: 800
-      Mace: 700
-      2hMace: 700
-      Staff: 650
-      2hStaff: 650
     BonusStats:
       - Level: 1
         Str: 1
@@ -1427,13 +1281,6 @@ Body:
     HpFactor: 89
     HpIncrease: 0
     SpIncrease: 469
-    BaseASPD:
-      Fist: 500
-      Revolver: 700
-      Rifle: 750
-      Gatling: 700
-      Shotgun: 1500
-      Grenade: 1500
     BonusStats:
       - Level: 1
         Dex: 1
@@ -1489,10 +1336,6 @@ Body:
     HpFactor: 80
     HpIncrease: 0
     SpIncrease: 540
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      Huuma: 750
     BonusStats:
       - Level: 1
         Agi: 1
@@ -1546,15 +1389,6 @@ Body:
         Luk: 1
   - Jobs:
       Novice_High: true
-    BaseASPD:
-      Fist: 500
-      Dagger: 650
-      1hSword: 700
-      1hAxe: 800
-      Mace: 700
-      2hMace: 700
-      Staff: 650
-      2hStaff: 650
     BonusStats:
       - Level: 2
         Luk: 1
@@ -1573,17 +1407,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 70
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 550
-      2hSword: 600
-      1hSpear: 650
-      2hSpear: 700
-      1hAxe: 700
-      2hAxe: 750
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 2
         Str: 1
@@ -1626,11 +1449,6 @@ Body:
     MaxWeight: 22000
     HpFactor: 30
     SpIncrease: 600
-    BaseASPD:
-      Fist: 500
-      Dagger: 600
-      Staff: 700
-      2hStaff: 700
     BonusStats:
       - Level: 2
         Int: 1
@@ -1673,10 +1491,6 @@ Body:
     MaxWeight: 26000
     HpFactor: 50
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      Bow: 700
     BonusStats:
       - Level: 2
         Dex: 1
@@ -1719,12 +1533,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 40
     SpIncrease: 500
-    BaseASPD:
-      Fist: 400
-      Mace: 600
-      2hMace: 600
-      Staff: 600
-      2hStaff: 600
     BonusStats:
       - Level: 2
         Luk: 1
@@ -1767,14 +1575,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 40
     SpIncrease: 300
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      1hSword: 700
-      1hAxe: 700
-      2hAxe: 750
-      Mace: 700
-      2hMace: 700
     BonusStats:
       - Level: 2
         Vit: 1
@@ -1817,12 +1617,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 50
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 650
-      1hAxe: 800
-      Bow: 800
     BonusStats:
       - Level: 2
         Agi: 1
@@ -1866,17 +1660,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 150
     SpIncrease: 300
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 500
-      2hSword: 550
-      1hSpear: 600
-      2hSpear: 600
-      1hAxe: 700
-      2hAxe: 700
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 1
         Str: 1
@@ -1973,13 +1756,6 @@ Body:
     MaxWeight: 26000
     HpFactor: 75
     SpIncrease: 800
-    BaseASPD:
-      Fist: 400
-      Mace: 600
-      2hMace: 600
-      Staff: 600
-      Book: 600
-      2hStaff: 600
     BonusStats:
       - Level: 1
         Int: 1
@@ -2076,11 +1852,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 55
     SpIncrease: 900
-    BaseASPD:
-      Fist: 500
-      Dagger: 575
-      Staff: 625
-      2hStaff: 625
     BonusStats:
       - Level: 1
         Int: 1
@@ -2177,14 +1948,6 @@ Body:
     MaxWeight: 30000
     HpFactor: 90
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      1hSword: 650
-      1hAxe: 650
-      2hAxe: 650
-      Mace: 675
-      2hMace: 675
     BonusStats:
       - Level: 1
         Dex: 1
@@ -2281,10 +2044,6 @@ Body:
     MaxWeight: 27000
     HpFactor: 85
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      Bow: 600
     BonusStats:
       - Level: 1
         Dex: 1
@@ -2381,12 +2140,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 110
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 650
-      1hAxe: 800
-      Katar: 500
     BonusStats:
       - Level: 1
         Agi: 1
@@ -2485,17 +2238,6 @@ Body:
     HpFactor: 110
     HpIncrease: 700
     SpIncrease: 470
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 500
-      2hSword: 550
-      1hSpear: 600
-      2hSpear: 600
-      1hAxe: 700
-      2hAxe: 700
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 1
         Vit: 1
@@ -2593,13 +2335,6 @@ Body:
     HpFactor: 90
     HpIncrease: 650
     SpIncrease: 470
-    BaseASPD:
-      Fist: 400
-      Mace: 575
-      2hMace: 575
-      Staff: 575
-      Knuckle: 475
-      2hStaff: 575
     BonusStats:
       - Level: 1
         Str: 1
@@ -2696,12 +2431,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 75
     SpIncrease: 700
-    BaseASPD:
-      Fist: 450
-      Dagger: 525
-      Staff: 625
-      Book: 550
-      2hStaff: 625
     BonusStats:
       - Level: 1
         Int: 1
@@ -2798,11 +2527,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 85
     SpIncrease: 500
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 550
-      Bow: 650
     BonusStats:
       - Level: 1
         Str: 1
@@ -2899,14 +2623,6 @@ Body:
     MaxWeight: 30000
     HpFactor: 90
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      1hSword: 575
-      1hAxe: 675
-      2hAxe: 700
-      Mace: 650
-      2hMace: 650
     BonusStats:
       - Level: 1
         Dex: 1
@@ -3004,11 +2720,6 @@ Body:
     HpFactor: 75
     HpIncrease: 300
     SpIncrease: 600
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      Bow: 650
-      Musical: 575
     BonusStats:
       - Level: 1
         Agi: 1
@@ -3106,11 +2817,6 @@ Body:
     HpFactor: 75
     HpIncrease: 300
     SpIncrease: 600
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      Bow: 650
-      Whip: 575
     BonusStats:
       - Level: 1
         Dex: 1
@@ -3204,31 +2910,11 @@ Body:
         Agi: 1
   - Jobs:
       Baby: true
-    BaseASPD:
-      Fist: 500
-      Dagger: 650
-      1hSword: 700
-      1hAxe: 800
-      Mace: 700
-      2hMace: 700
-      Staff: 650
-      2hStaff: 650
   - Jobs:
       Baby_Swordman: true
     MaxWeight: 28000
     HpFactor: 70
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 550
-      2hSword: 600
-      1hSpear: 650
-      2hSpear: 700
-      1hAxe: 700
-      2hAxe: 750
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 2
         Str: 1
@@ -3271,11 +2957,6 @@ Body:
     MaxWeight: 22000
     HpFactor: 30
     SpIncrease: 600
-    BaseASPD:
-      Fist: 500
-      Dagger: 600
-      Staff: 700
-      2hStaff: 700
     BonusStats:
       - Level: 2
         Int: 1
@@ -3318,10 +2999,6 @@ Body:
     MaxWeight: 26000
     HpFactor: 50
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      Bow: 700
     BonusStats:
       - Level: 2
         Dex: 1
@@ -3364,12 +3041,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 40
     SpIncrease: 500
-    BaseASPD:
-      Fist: 400
-      Mace: 600
-      2hMace: 600
-      Staff: 600
-      2hStaff: 600
     BonusStats:
       - Level: 2
         Luk: 1
@@ -3412,14 +3083,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 40
     SpIncrease: 300
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      1hSword: 700
-      1hAxe: 700
-      2hAxe: 750
-      Mace: 700
-      2hMace: 700
     BonusStats:
       - Level: 2
         Vit: 1
@@ -3462,12 +3125,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 50
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 650
-      1hAxe: 800
-      Bow: 800
     BonusStats:
       - Level: 2
         Agi: 1
@@ -3511,17 +3168,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 150
     SpIncrease: 300
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 500
-      2hSword: 550
-      1hSpear: 600
-      2hSpear: 600
-      1hAxe: 700
-      2hAxe: 700
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 1
         Vit: 1
@@ -3588,13 +3234,6 @@ Body:
     MaxWeight: 26000
     HpFactor: 75
     SpIncrease: 800
-    BaseASPD:
-      Fist: 400
-      Mace: 600
-      2hMace: 600
-      Staff: 600
-      Book: 600
-      2hStaff: 600
     BonusStats:
       - Level: 1
         Luk: 1
@@ -3661,11 +3300,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 55
     SpIncrease: 900
-    BaseASPD:
-      Fist: 500
-      Dagger: 575
-      Staff: 625
-      2hStaff: 625
     BonusStats:
       - Level: 1
         Int: 1
@@ -3732,14 +3366,6 @@ Body:
     MaxWeight: 30000
     HpFactor: 90
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      1hSword: 650
-      1hAxe: 650
-      2hAxe: 650
-      Mace: 675
-      2hMace: 675
     BonusStats:
       - Level: 1
         Dex: 1
@@ -3806,10 +3432,6 @@ Body:
     MaxWeight: 27000
     HpFactor: 85
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 600
-      Bow: 600
     BonusStats:
       - Level: 1
         Dex: 1
@@ -3876,12 +3498,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 110
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 650
-      1hAxe: 800
-      Katar: 500
     BonusStats:
       - Level: 1
         Agi: 1
@@ -3950,17 +3566,6 @@ Body:
     HpFactor: 110
     HpIncrease: 700
     SpIncrease: 470
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 500
-      2hSword: 550
-      1hSpear: 600
-      2hSpear: 600
-      1hAxe: 700
-      2hAxe: 700
-      Mace: 650
-      2hMace: 700
     BonusStats:
       - Level: 1
         Luk: 1
@@ -4028,13 +3633,6 @@ Body:
     HpFactor: 90
     HpIncrease: 650
     SpIncrease: 470
-    BaseASPD:
-      Fist: 400
-      Mace: 575
-      2hMace: 575
-      Staff: 575
-      Knuckle: 475
-      2hStaff: 575
     BonusStats:
       - Level: 1
         Str: 1
@@ -4101,12 +3699,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 75
     SpIncrease: 700
-    BaseASPD:
-      Fist: 450
-      Dagger: 525
-      Staff: 625
-      Book: 550
-      2hStaff: 625
     BonusStats:
       - Level: 1
         Int: 1
@@ -4173,11 +3765,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 85
     SpIncrease: 500
-    BaseASPD:
-      Fist: 400
-      Dagger: 500
-      1hSword: 550
-      Bow: 650
     BonusStats:
       - Level: 1
         Agi: 1
@@ -4244,14 +3831,6 @@ Body:
     MaxWeight: 30000
     HpFactor: 90
     SpIncrease: 400
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      1hSword: 575
-      1hAxe: 675
-      2hAxe: 700
-      Mace: 650
-      2hMace: 650
     BonusStats:
       - Level: 1
         Int: 1
@@ -4319,11 +3898,6 @@ Body:
     HpFactor: 75
     HpIncrease: 300
     SpIncrease: 600
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      Bow: 650
-      Musical: 575
     BonusStats:
       - Level: 1
         Dex: 1
@@ -4391,11 +3965,6 @@ Body:
     HpFactor: 75
     HpIncrease: 300
     SpIncrease: 600
-    BaseASPD:
-      Fist: 400
-      Dagger: 550
-      Bow: 650
-      Whip: 575
     BonusStats:
       - Level: 1
         Luk: 1
@@ -4459,15 +4028,6 @@ Body:
         Luk: 1
   - Jobs:
       Super_Baby: true
-    BaseASPD:
-      Fist: 500
-      Dagger: 650
-      1hSword: 700
-      1hAxe: 800
-      Mace: 700
-      2hMace: 700
-      Staff: 650
-      2hStaff: 650
     BonusStats:
       - Level: 1
         Str: 1
@@ -4534,8 +4094,6 @@ Body:
     MaxWeight: 28000
     HpFactor: 70
     SpIncrease: 200
-    BaseASPD:
-      Fist: 400
     BonusStats:
       - Level: 1
         Str: 1
@@ -4580,9 +4138,6 @@ Body:
     HpFactor: 90
     HpIncrease: 650
     SpIncrease: 470
-    BaseASPD:
-      Fist: 400
-      Book: 500
     BonusStats:
       - Level: 1
         Str: 1
@@ -4649,11 +4204,6 @@ Body:
     MaxWeight: 24000
     HpFactor: 75
     SpIncrease: 900
-    BaseASPD:
-      Fist: 500
-      Dagger: 575
-      Staff: 625
-      2hStaff: 625
     BonusStats:
       - Level: 1
         Int: 1

+ 2 - 2
db/pre-re/produce_db.txt

@@ -315,9 +315,9 @@
 //-- Mystic Frozen <-- BS_ENCHANTSTONE & 10 Crystal Blue
 116,995,21,96,1,991,10
 //-- Rough Wind <-- BS_ENCHANTSTONE & 10 Wind of Verdure
-117,997,21,96,1,993,10
+117,996,21,96,1,992,10
 //-- Great Nature <-- BS_ENCHANTSTONE & 10 Green Live
-118,996,21,96,1,992,10
+118,997,21,96,1,993,10
 //----------------------------------------------
 
 //==============================================

+ 1 - 1
db/re/item_db_equip.yml

@@ -85397,7 +85397,7 @@ Body:
          bonus2 bSubRace2,RC2_THANATOS,20;
          bonus2 bMagicAddRace2,RC2_THANATOS,20;
       }
-      /* skill 3044,1; */
+      skill "ALL_THANATOS_RECALL",1;
   - Id: 19104
     AegisName: YDragon_SkyWing
     Name: Dragon Emperor's Wing

+ 28 - 0
db/re/item_db_etc.yml

@@ -1880,6 +1880,7 @@ Body:
     Name: Trap
     Type: Etc
     Buy: 75
+    Sell: 0
     Weight: 2
     Flags:
       BuyingStore: true
@@ -2098,6 +2099,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 1
+    Sell: 0
     Weight: 1
     Attack: 25
     Jobs:
@@ -2116,6 +2118,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 5
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2136,6 +2139,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 5
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2156,6 +2160,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 4
+    Sell: 0
     Weight: 1
     Attack: 40
     Jobs:
@@ -2174,6 +2179,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 5
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2194,6 +2200,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 5
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2214,6 +2221,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 5
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2234,6 +2242,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 5
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2254,6 +2263,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 1
     Jobs:
@@ -2274,6 +2284,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 1
     Jobs:
@@ -2295,6 +2306,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 1
     Jobs:
@@ -2315,6 +2327,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 1
     Jobs:
@@ -2335,6 +2348,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 5
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2355,6 +2369,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 1
     Jobs:
@@ -2376,6 +2391,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 20
+    Sell: 0
     Weight: 1
     Attack: 10
     Jobs:
@@ -2396,6 +2412,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 30
+    Sell: 0
     Weight: 1
     Attack: 50
     Jobs:
@@ -2414,6 +2431,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 40
+    Sell: 0
     Weight: 3
     Attack: 50
     Jobs:
@@ -2434,6 +2452,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 5
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2454,6 +2473,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 1
     Jobs:
@@ -2474,6 +2494,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 1
     Jobs:
@@ -2494,6 +2515,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 3
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -2525,6 +2547,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 3
+    Sell: 0
     Weight: 1
     Attack: 50
     Jobs:
@@ -2546,6 +2569,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 45
     Jobs:
@@ -2564,6 +2588,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 35
     Jobs:
@@ -2582,6 +2607,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 45
     Jobs:
@@ -2600,6 +2626,7 @@ Body:
     Type: Ammo
     SubType: Arrow
     Buy: 10
+    Sell: 0
     Weight: 1
     Attack: 30
     Jobs:
@@ -31291,6 +31318,7 @@ Body:
     Name: Special Alloy Trap
     Type: Etc
     Buy: 300
+    Sell: 0
     Weight: 2
     Flags:
       BuyingStore: true

+ 20 - 0
db/re/item_db_usable.yml

@@ -4299,6 +4299,7 @@ Body:
     Name: Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4309,6 +4310,7 @@ Body:
     Name: Iron Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4319,6 +4321,7 @@ Body:
     Name: Steel Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4329,6 +4332,7 @@ Body:
     Name: Oridecon Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4339,6 +4343,7 @@ Body:
     Name: Fire Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4349,6 +4354,7 @@ Body:
     Name: Silver Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4359,6 +4365,7 @@ Body:
     Name: Wind Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4369,6 +4376,7 @@ Body:
     Name: Stone Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4379,6 +4387,7 @@ Body:
     Name: Crystal Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4389,6 +4398,7 @@ Body:
     Name: Shadow Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4399,6 +4409,7 @@ Body:
     Name: Immaterial Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -4409,6 +4420,7 @@ Body:
     Name: Rusty Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -6317,6 +6329,7 @@ Body:
     Name: Holy Arrow Quiver
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -8312,6 +8325,7 @@ Body:
     Name: Special Alloy Trap Box
     Type: Usable
     Buy: 30000
+    Sell: 0
     Weight: 100
     Flags:
       BuyingStore: true
@@ -10918,6 +10932,7 @@ Body:
     Name: Arrow Of Elf Cntr
     Type: Usable
     Buy: 500
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -10928,6 +10943,7 @@ Body:
     Name: Hunting Arrow Cntr
     Type: Usable
     Buy: 500
+    Sell: 0
     Weight: 250
     Flags:
       BuyingStore: true
@@ -12128,6 +12144,7 @@ Body:
     Name: Siege Arrow Quiver S
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 100
     EquipLevelMin: 130
     Flags:
@@ -12139,6 +12156,7 @@ Body:
     Name: Siege Arrow Quiver A
     Type: Usable
     Buy: 2
+    Sell: 0
     Weight: 100
     EquipLevelMin: 95
     Flags:
@@ -57584,6 +57602,7 @@ Body:
     Name: Trap Box
     Type: Usable
     Buy: 20
+    Sell: 0
     Weight: 250
     Script: |
       getitem "Booby_Trap",500;
@@ -60179,6 +60198,7 @@ Body:
     Name: Poison Arrow Quiver
     Type: Usable
     Buy: 20
+    Sell: 0
     Weight: 250
     Script: |
       getitem "Poison_Arrow",500;

+ 616 - 0
db/re/job_aspd.yml

@@ -0,0 +1,616 @@
+# This file is a part of rAthena.
+#   Copyright(C) 2021 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/>.
+#
+###########################################################################
+# Job Database
+###########################################################################
+#
+# Job Settings
+#
+###########################################################################
+# - Jobs:                    List of jobs associated to group.
+#     Job                    Job name.
+#   MaxWeight                Base maximum weight. (Default: 20000)
+#   HpFactor                 Exponential HP increase. Per base level: [HpFactor * BaseLv / 100]. Used when macro HP_SP_TABLES is disabled. (Default: 0)
+#   HpIncrease               Linear HP increase. Per base level: [HpIncrease / 100]. Used when macro HP_SP_TABLES is disabled. (Default: 500)
+#   SpIncrease               Linear SP increase. Per base level: [SpIncrease / 100]. Used when macro HP_SP_TABLES is disabled. (Default: 100)
+#   BaseASPD:                Base ASPD for each weapon type. (Default: 2000)
+#     Weapon                 Weapon type with associated ASPD.
+#   BonusStats:              Job level bonus stats/traits.
+#     - Level                Job level.
+#       Str                  Stength increase amount. (Default: 0)
+#       Agi                  Agility increase amount. (Default: 0)
+#       Vit                  Vitality increase amount. (Default: 0)
+#       Int                  Intelligence increase amount. (Default: 0)
+#       Dex                  Dexterity increase amount. (Default: 0)
+#       Luk                  Luck increase amount. (Default: 0)
+#       Pow                  Power increase amount. (Default: 0)
+#       Sta                  Stamina increase amount. (Default: 0)
+#       Wis                  Wisdom increase amount. (Default: 0)
+#       Spl                  Spell increase amount. (Default: 0)
+#       Con                  Concentration increase amount. (Default: 0)
+#       Crt                  Creative increase amount. (Default: 0)
+#   MaxStats:                Maximum stats/traits applicable. (Default: battle_config::max_*_parameter)
+#     Str                    Strength.
+#     Agi                    Agility.
+#     Vit                    Vitality.
+#     Int                    Intelligence.
+#     Dex                    Dexterity.
+#     Luk                    Luck.
+#     Pow                    Power.
+#     Sta                    Stamina.
+#     Wis                    Wisdom.
+#     Spl                    Spell.
+#     Con                    Concentration.
+#     Crt                    Creative.
+#   MaxBaseLevel             Maximum base level. (Default: MAX_LEVEL)
+#   BaseExp:                 Base experience per level.
+#     - Level                Base level.
+#       Exp                  Base experience.
+#   MaxJobLevel              Maximum job level. (Default: MAX_LEVEL)
+#   JobExp:                  Job experience per level.
+#     - Level                Job level.
+#       Exp                  Job experience.
+#   BaseHp:                  Base HP per base level.
+#     - Level                Base level.
+#       Hp                   Base HP.
+#   BaseSp:                  Base SP per base level.
+#     - Level                Base level.
+#       Sp                   Base SP.
+#   BaseAp:                  Base AP per base level.
+#     - Level                Base level.
+#       Ap                   Base AP.
+###########################################################################
+
+Header:
+  Type: JOB_STATS
+  Version: 2
+
+Body:
+  - Jobs:
+      Novice: true
+      Super_Novice: true
+      Novice_High: true
+      Baby: true
+      Super_Baby: true
+      Super_Novice_E: true
+      Super_Baby_E: true
+      Hyper_Novice: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 55
+      1hSword: 57
+      1hAxe: 50
+      Mace: 50
+      2hMace: 55
+      Staff: 65
+      2hStaff: 65
+      Shield: 10
+  - Jobs:
+      Swordman: true
+      Swordman_High: true
+      Baby_Swordman: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 47
+      1hSword: 47
+      2hSword: 54
+      1hSpear: 57
+      2hSpear: 65
+      1hAxe: 55
+      2hAxe: 60
+      Mace: 50
+      2hMace: 55
+      Shield: 5
+  - Jobs:
+      Mage: true
+      Mage_High: true
+      Baby_Mage: true
+    BaseASPD:
+      Fist: 50
+      Dagger: 50
+      Staff: 55
+      2hStaff: 55
+      Shield: 10
+  - Jobs:
+      Archer: true
+      Archer_High: true
+      Baby_Archer: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 55
+      Bow: 50
+      Shield: 9
+  - Jobs:
+      Acolyte: true
+      Acolyte_High: true
+      Baby_Acolyte: true
+    BaseASPD:
+      Fist: 40
+      Mace: 45
+      2hMace: 50
+      Staff: 60
+      2hStaff: 60
+      Shield: 7
+  - Jobs:
+      Merchant: true
+      Merchant_High: true
+      Baby_Merchant: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 52
+      1hSword: 52
+      1hAxe: 48
+      2hAxe: 55
+      Mace: 50
+      2hMace: 55
+      Shield: 5
+  - Jobs:
+      Thief: true
+      Thief_High: true
+      Baby_Thief: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 48
+      1hSword: 50
+      1hAxe: 60
+      Bow: 53
+      Shield: 6
+  - Jobs:
+      Knight: true
+      Knight2: true
+      Lord_Knight: true
+      Lord_Knight2: true
+      Baby_Knight: true
+      Baby_Knight2: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 49
+      1hSword: 45
+      2hSword: 52
+      1hSpear: 55
+      2hSpear: 60
+      1hAxe: 50
+      2hAxe: 55
+      Mace: 45
+      2hMace: 50
+      Shield: 5
+  - Jobs:
+      Priest: true
+      High_Priest: true
+      Baby_Priest: true
+    BaseASPD:
+      Fist: 40
+      Mace: 43
+      2hMace: 48
+      Staff: 60
+      Knuckle: 60
+      Book: 44
+      2hStaff: 60
+      Shield: 5
+  - Jobs:
+      Wizard: true
+      High_Wizard: true
+      Baby_Wizard: true
+    BaseASPD:
+      Fist: 50
+      Dagger: 54
+      Staff: 53
+      2hStaff: 53
+      Shield: 8
+  - Jobs:
+      Blacksmith: true
+      Whitesmith: true
+      Baby_Blacksmith: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 50
+      1hSword: 50
+      1hAxe: 46
+      2hAxe: 53
+      Mace: 48
+      2hMace: 53
+      Shield: 5
+  - Jobs:
+      Hunter: true
+      Sniper: true
+      Baby_Hunter: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 53
+      Bow: 48
+      Shield: 9
+  - Jobs:
+      Assassin: true
+      Assassin_Cross: true
+      Baby_Assassin: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 42
+      1hSword: 50
+      1hAxe: 51
+      Katar: 42
+      Huuma: 110
+      Shield: 6
+  - Jobs:
+      Crusader: true
+      Crusader2: true
+      Paladin: true
+      Paladin2: true
+      Baby_Crusader: true
+      Baby_Crusader2: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 48
+      1hSword: 43
+      2hSword: 55
+      1hSpear: 53
+      2hSpear: 52
+      1hAxe: 50
+      2hAxe: 55
+      Mace: 45
+      2hMace: 50
+      Shield: 5
+  - Jobs:
+      Monk: true
+      Champion: true
+      Baby_Monk: true
+    BaseASPD:
+      Fist: 40
+      Mace: 43
+      2hMace: 48
+      Staff: 60
+      Knuckle: 40
+      2hStaff: 58
+      Shield: 5
+  - Jobs:
+      Sage: true
+      Professor: true
+      Baby_Sage: true
+    BaseASPD:
+      Fist: 45
+      Dagger: 53
+      1hSword: 60
+      Staff: 55
+      Book: 43
+      2hStaff: 55
+      Shield: 5
+  - Jobs:
+      Rogue: true
+      Stalker: true
+      Baby_Rogue: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 45
+      1hSword: 50
+      Bow: 50
+      Shield: 5
+  - Jobs:
+      Alchemist: true
+      Creator: true
+      Baby_Alchemist: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 50
+      1hSword: 45
+      1hAxe: 45
+      2hAxe: 52
+      Mace: 45
+      2hMace: 50
+      Shield: 4
+  - Jobs:
+      Bard: true
+      Clown: true
+      Baby_Bard: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 53
+      Bow: 48
+      Musical: 45
+      Shield: 7
+  - Jobs:
+      Dancer: true
+      Gypsy: true
+      Baby_Dancer: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 53
+      Bow: 48
+      Whip: 45
+      Shield: 7
+  - Jobs:
+      Gunslinger: true
+      Rebellion: true
+      Baby_Gunslinger: true
+      Baby_Rebellion: true
+      Night_Watch: true
+    BaseASPD:
+      Fist: 54
+      Revolver: 49
+      Rifle: 59
+      Gatling: 54
+      Shotgun: 94
+      Grenade: 104
+      Shield: 6
+  - Jobs:
+      Ninja: true
+      Baby_Ninja: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 43
+      Huuma: 55
+      Shield: 6
+  - Jobs:
+      Taekwon: true
+      Star_Gladiator: true
+      Star_Gladiator2: true
+      Baby_Taekwon: true
+      Baby_Star_Gladiator: true
+      Baby_Star_Gladiator2: true
+      Star_Emperor: true
+      Star_Emperor2: true
+      Baby_Star_Emperor: true
+      Baby_Star_Emperor2: true
+      Sky_Emperor: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 50
+      1hSword: 50
+      2hSword: 50
+      1hSpear: 50
+      2hSpear: 50
+      1hAxe: 50
+      2hAxe: 50
+      Mace: 50
+      2hMace: 50
+      Staff: 50
+      Bow: 50
+      Knuckle: 50
+      Musical: 50
+      Whip: 50
+      Book: 50
+      Katar: 50
+      Revolver: 50
+      Rifle: 50
+      Gatling: 50
+      Shotgun: 50
+      Grenade: 50
+      Huuma: 50
+      2hStaff: 50
+      Shield: 6
+  - Jobs:
+      Soul_Linker: true
+      Baby_Soul_Linker: true
+      Soul_Reaper: true
+      Baby_Soul_Reaper: true
+      Soul_Ascetic: true
+    BaseASPD:
+      Fist: 50
+      Dagger: 50
+      Staff: 53
+      2hStaff: 55
+      Shield: 8
+  - Jobs:
+      Rune_Knight: true
+      Rune_Knight2: true
+      Rune_Knight_T: true
+      Rune_Knight_T2: true
+      Baby_Rune_Knight: true
+      Baby_Rune_Knight2: true
+      Dragon_Knight: true
+      Dragon_Knight2: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 50
+      1hSword: 52
+      2hSword: 55
+      1hSpear: 60
+      2hSpear: 58
+      1hAxe: 48
+      2hAxe: 52
+      Mace: 45
+      2hMace: 52
+      Shield: 5
+  - Jobs:
+      Warlock: true
+      Warlock_T: true
+      Baby_Warlock: true
+      Arch_Mage: true
+    BaseASPD:
+      Fist: 45
+      Dagger: 52
+      1hSword: 60
+      Staff: 50
+      2hStaff: 56
+      Shield: 5
+  - Jobs:
+      Ranger: true
+      Ranger2: true
+      Ranger_T: true
+      Ranger_T2: true
+      Baby_Ranger: true
+      Baby_Ranger2: true
+      Windhawk: true
+      Windhawk2: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 50
+      Bow: 49
+      Shield: 8
+  - Jobs:
+      Arch_Bishop: true
+      Arch_Bishop_T: true
+      Baby_Arch_Bishop: true
+      Cardinal: true
+    BaseASPD:
+      Fist: 45
+      Mace: 45
+      2hMace: 45
+      Staff: 60
+      Knuckle: 50
+      Book: 44
+      2hStaff: 55
+      Shield: 5
+  - Jobs:
+      Mechanic: true
+      Mechanic2: true
+      Mechanic_T: true
+      Mechanic_T2: true
+      Baby_Mechanic: true
+      Baby_Mechanic2: true
+      Meister: true
+      Meister2: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 60
+      1hSword: 65
+      1hAxe: 45
+      2hAxe: 48
+      Mace: 48
+      2hMace: 50
+      Shield: 6
+  - Jobs:
+      Guillotine_Cross: true
+      Guillotine_Cross_T: true
+      Baby_Guillotine_Cross: true
+      Shadow_Cross: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 42
+      1hSword: 65
+      1hAxe: 80
+      Katar: 42
+      Rifle: 95
+      Gatling: 120
+      Shotgun: 90
+      Grenade: 100
+      Huuma: 110
+      Shield: 9
+  - Jobs:
+      Royal_Guard: true
+      Royal_Guard2: true
+      Royal_Guard_T: true
+      Royal_Guard_T2: true
+      Baby_Royal_Guard: true
+      Baby_Royal_Guard2: true
+      Imperial_Guard: true
+      Imperial_Guard2: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 47
+      1hSword: 45
+      2hSword: 53
+      1hSpear: 50
+      2hSpear: 50
+      1hAxe: 48
+      2hAxe: 52
+      Mace: 44
+      2hMace: 50
+      Shield: 5
+  - Jobs:
+      Sorcerer: true
+      Sorcerer_T: true
+      Baby_Sorcerer: true
+      Elemental_Master: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 50
+      1hSword: 50
+      Staff: 45
+      Book: 45
+      2hStaff: 55
+      Shield: 5
+  - Jobs:
+      Minstrel: true
+      Minstrel_T: true
+      Baby_Minstrel: true
+      Troubadour: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 52
+      Bow: 49
+      Musical: 44
+      Shield: 7
+  - Jobs:
+      Wanderer: true
+      Wanderer_T: true
+      Baby_Wanderer: true
+      Trouvere: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 52
+      Bow: 49
+      Whip: 44
+      Shield: 7
+  - Jobs:
+      Sura: true
+      Sura_T: true
+      Baby_Sura: true
+      Inquisitor: true
+    BaseASPD:
+      Fist: 38
+      Mace: 43
+      2hMace: 45
+      Staff: 48
+      Knuckle: 39
+      2hStaff: 50
+      Shield: 5
+  - Jobs:
+      Genetic: true
+      Genetic_T: true
+      Baby_Genetic: true
+      Biolo: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 50
+      1hSword: 44
+      1hAxe: 48
+      2hAxe: 51
+      Mace: 44
+      2hMace: 48
+      Shield: 4
+  - Jobs:
+      Shadow_Chaser: true
+      Shadow_Chaser_T: true
+      Baby_Shadow_Chaser: true
+      Abyss_Chaser: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 43
+      1hSword: 47
+      Bow: 47
+      Shield: 4
+  - Jobs:
+      Kagerou: true
+      Oboro: true
+      Baby_Kagerou: true
+      Baby_Oboro: true
+      Shinkiro: true
+      Shiranui: true
+    BaseASPD:
+      Fist: 40
+      Dagger: 45
+      Huuma: 50
+      Shield: 3
+  - Jobs:
+      Summoner: true
+      Baby_Summoner: true
+      Spirit_Handler: true
+    BaseASPD:
+      Fist: 40
+      Staff: 60
+      Shield: 7

文件差異過大導致無法顯示
+ 0 - 565
db/re/job_stats.yml


+ 4 - 4
db/re/produce_db.txt

@@ -315,9 +315,9 @@
 //-- Mystic Frozen <-- BS_ENCHANTEDSTONE & 10 Crystal Blue
 116,995,21,96,1,991,10
 //-- Rough Wind <-- BS_ENCHANTEDSTONE & 10 Wind of Verdure
-117,997,21,96,1,993,10
+117,996,21,96,1,992,10
 //-- Great Nature <-- BS_ENCHANTEDSTONE & 10 Green Live
-118,996,21,96,1,992,10
+118,997,21,96,1,993,10
 //----------------------------------------------
 
 //==============================================
@@ -393,9 +393,9 @@
 //-- Water Elemental Converter <-- SA_CREATECON & 1 Blank Scroll, 1 Crystal Blue
 143,12115,23,1007,1,7433,1,991,1
 //-- Earth Elemental Converter <-- SA_CREATECON & 1 Blank Scroll, 1 Green Live
-144,12116,23,1007,1,7433,1,992,1
+144,12116,23,1007,1,7433,1,993,1
 //-- Wind Elemental Converter <-- SA_CREATECON & 1 Blank Scroll, 1 Wind of Verdure
-145,12117,23,1007,1,7433,1,993,1
+145,12117,23,1007,1,7433,1,992,1
 
 //==============================================
 

+ 140 - 0
db/re/quest_db.yml

@@ -1350,30 +1350,152 @@ Body:
   - Id: 3420
     Title: Defeat Deep Sea fishmen in the Lower Layers - Standby
     TimeLimit: 4h
+  - Id: 3446
+    Title: Illusion Investigation Team - Jiroker
+  - Id: 3447
+    Title: Illusion of Moonlight 100 Kills
+    Targets:
+      - Id: 1
+        Count: 100
+        Location: pay_d03_i
+        MapMobTargets:
+          ILL_MUNAK: true
+          ILL_BON_GUN: true
+          ILL_SOHEE: true
+          ILL_ARCHER_SKELETON: true
+          ILL_NINE_TAIL: true
+          ILL_FURY_HERO: true
   - Id: 3448
     Title: Illusion of Moonlight 100 Kills - Standby
     TimeLimit: 4h
+  - Id: 3449
+    Title: Illusion Investigation Team - Elysia
+  - Id: 3450
+    Title: Illusion of Frozen 100 Kills
+    Targets:
+      - Id: 1
+        Count: 100
+        Location: ice_d03_i
+        MapMobTargets:
+          ILL_GAZETI: true
+          ILL_SNOWIER: true
+          ILL_ICE_TITAN: true
+          ILL_ICEICLE: true
   - Id: 3451
     Title: Illusion of Frozen 100 Kills - Standby
     TimeLimit: 4h
+  - Id: 3452
+    Title: Illusion Investigation Team - Radimir
+  - Id: 3453
+    Title: Illusion of Vampire 100 Kills
+    Targets:
+      - Id: 1
+        Count: 100
+        Location: gef_d01_i
+        MapMobTargets:
+          ILL_ZOMBIE: true
+          ILL_BLACK_MUSHROOM: true
+          ILL_DRAINLIAR: true
+          ILL_ZOMBIE_C: true
+          ILL_NIGHTMARE: true
+          ILL_GHOUL: true
   - Id: 3454
     Title: Illusion of Vampire 100 Kills - Standby
     TimeLimit: 4h
+  - Id: 3455
+    Title: Illusion Investigation Team - Machoko
+  # - Id: 3456
+    # Title: Illusion of Teddy Bear 100 Kills
+    # Targets:
+      # - Id: 1
+        # Count: 100
+        # Location: ein_d02_i
+        # MapMobTargets:
+          # ILL_TEDDY_BEAR_B: true
+          # ILL_MINERAL: true
+          # ILL_PITMAN: true
+          # ILL_TEDDY_BEAR_R: true
+          # ILL_TEDDY_BEAR_Y: true
+          # ILL_TEDDY_BEAR_W: true
+          # ILL_OBSIDIAN: true
+          # ILL_TEDDY_BEAR_G: true
   - Id: 3457
     Title: Illusion of Teddy Bear 100 Kills - Standby
     TimeLimit: 4h
+  - Id: 3458
+    Title: Illusion Investigation Team - Orian
+  - Id: 3459
+    Title: Illusion of Abyss 100 Kills
+    Targets:
+      - Id: 1
+        Count: 100
+        Location: tur_d04_i
+        MapMobTargets:
+          ILL_PERMETER: true
+          ILL_FREEZER: true
+          ILL_ASSULTER: true
+          ILL_SOLIDER: true
+          ILL_HEATER: true
   - Id: 3460
     Title: Illusion of Abyss 100 Kills - Standby
     TimeLimit: 4h
+  - Id: 3461
+    Title: Illusion Investigation Team - Cassis
+  - Id: 3462
+    Title: Illusion of Luanda 100 Kills
+    Targets:
+      - Id: 1
+        Count: 100
+        Location: com_d02_i
+        MapMobTargets:
+          ILL_TRI_JOINT: true
+          ILL_WOOTAN_SHOOTER: true
+          ILL_MEGALITH: true
+          ILL_STONE_SHOOTER: true
+          ILL_STALACTIC_GOLEM: true
+          ILL_WOOTAN_FIGHTER: true
   - Id: 3463
     Title: Illusion of Luanda 100 Kills - Standby
     TimeLimit: 4h
+  - Id: 3464
+    Title: Illusion Investigation Team - Terrian
+  # - Id: 3465
+    # Title: Illusion of Labyrinth 100 Kills
+    # Targets:
+      # - Id: 1
+        # Count: 100
+        # Location: prt_mz03_i
+        # MapMobTargets:
+          # ILL_STEM_WORM: true
+          # ILL_GHOSTRING: true
+          # ILL_POPORING: true
+          # ILL_MANTIS: true
+          # ILL_HUNTER_FLY: true
+          # ILL_SIDE_WINDER: true
+          # ILL_BAPHOMET_J: true
+          # ILL_KILLER_MANTIS: true
   - Id: 3466
     Title: Illusion of Labyrinth 100 Kills - Standby
     TimeLimit: 4h
+  - Id: 3467
+    Title: Illusion Investigation Team - Lister
+  - Id: 3468
+    Title: Illusion of Underwater 100 Kills
+    Targets:
+      - Id: 1
+        Count: 100
+        Location: iz_d05_i
+        MapMobTargets:
+          ILL_SEDORA: true
+          ILL_SWORD_FISH: true
+          ILL_PHEN: true
+          ILL_STROUF: true
+          ILL_KING_DRAMOH: true
   - Id: 3469
     Title: Illusion of Underwater 100 Kills - Standby
     TimeLimit: 4h
+  - Id: 3470
+    Title: Join the Illusion Investigation Team
   - Id: 3471
     Title: Subjugation-Einbroch Field-2
     Targets:
@@ -1452,6 +1574,24 @@ Body:
   - Id: 3504
     Title: Look at the Sky - Standby
     TimeLimit: 4h
+  - Id: 3507
+    Title: Illusion Investigation Team - Sheshin
+  # - Id: 3508
+    # Title: Illusion of Twins 100 Kills
+    # Targets:
+      # - Id: 1
+        # Count: 100
+        # Location: ant_d02_i
+        # MapMobTargets:
+          # ILL_ANDRE_LARVA: true
+          # ILL_ANT_EGG: true
+          # ILL_FARMILIAR: true
+          # ILL_ANDRE: true
+          # ILL_DENIRO: true
+          # ILL_PIERE: true
+          # ILL_GIEARTH: true
+          # ILL_SOLDIER_ANDR: true
+          # ILL_VITATA: true
   - Id: 3509
     Title: Illusion of Twins 100 Kills - Standby
     TimeLimit: 4h

+ 57 - 0
db/re/skill_db.yml

@@ -32937,6 +32937,63 @@ Body:
       IgnoreItemBonus: true
     Requires:
       SpCost: 1
+  - Id: 3043
+    Name: ALL_GLASTHEIM_RECALL
+    Description: Return To Glast Heim
+    MaxLevel: 1
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+    Cooldown: 300000
+    FixedCastTime: 1000
+    CastTimeFlags:
+      IgnoreDex: true
+      IgnoreStatus: true
+      IgnoreItemBonus: true
+    CastDelayFlags:
+      IgnoreDex: true
+      IgnoreStatus: true
+      IgnoreItemBonus: true
+    Requires:
+      SpCost: 1
+  - Id: 3044
+    Name: ALL_THANATOS_RECALL
+    Description: Return To Thanatos
+    MaxLevel: 1
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+    Cooldown: 300000
+    FixedCastTime: 1000
+    CastTimeFlags:
+      IgnoreDex: true
+      IgnoreStatus: true
+      IgnoreItemBonus: true
+    CastDelayFlags:
+      IgnoreDex: true
+      IgnoreStatus: true
+      IgnoreItemBonus: true
+    Requires:
+      SpCost: 1
+  - Id: 3045
+    Name: ALL_LIGHTHALZEN_RECALL
+    Description: Return To Lighthalzen
+    MaxLevel: 1
+    TargetType: Self
+    DamageFlags:
+      NoDamage: true
+    Cooldown: 300000
+    FixedCastTime: 1000
+    CastTimeFlags:
+      IgnoreDex: true
+      IgnoreStatus: true
+      IgnoreItemBonus: true
+    CastDelayFlags:
+      IgnoreDex: true
+      IgnoreStatus: true
+      IgnoreItemBonus: true
+    Requires:
+      SpCost: 1
   - Id: 5001
     Name: GC_DARKCROW
     Description: Dark Claw

+ 1559 - 0
npc/re/quests/illusion_investigation.txt

@@ -0,0 +1,1559 @@
+//===== rAthena Script =======================================
+//= Illusion Investigation
+//===== Description: =========================================
+//= [Walkthrough Conversion]
+//= NPCs that give hunting quests in Illusion dungeons in exchange for experience.
+//===== Changelog: ===========================================
+//= 1.0 First version. [Capuche]
+//============================================================
+
+prt_in,136,34,3	script	Leader Joel#joel	1_M_ORIENT01,{
+	if (BaseLevel < 100) {
+		mes "[Director Joel]";
+		mes "Hello, what business are you here for?";
+		next;
+		mes "[Director Joel]";
+		mes "If you wish to join the Illusion Investigation Corps, you're lacking in skills yet.";
+		next;
+		mes "[Director Joel]";
+		mes "Please visit again when you have reached a certain level.";
+		next;
+		mes "^4d4dff== You must be level 100 or higher to join. ==^000000";
+		close;
+	}
+	if (isbegin_quest(3470) == 0) {
+		mes "[Director Joel]";
+		mes "Hello, I'm Joel, the leader of the Illusion Investigation Corps.";
+		next;
+		mes "[Director Joel]";
+		mes "Have you ever heard of or experienced illusions?";
+		next;
+		mes "[Director Joel]";
+		mes "Until now, illusions have been discovered all over the world and are somewhat known to the public.";
+		next;
+		mes "[Director Joel]";
+		mes "It is also used as a hunting ground for many adventurers because it is easy to obtain rare materials.";
+		next;
+		mes "[Director Joel]";
+		mes "Also, the monsters in Illusion are new monsters that have never been discovered before, and the monsters in Illusion are multiplying abnormally.";
+		next;
+		mes "[Director Joel]";
+		mes "Despite many adventurers hunting the monsters that exist in Illusion to obtain materials, the reason for the very rapid recovery of the population has not been identified.";
+		next;
+		mes "[Director Joel]";
+		mes "Our Illusion Investigation Team was organized to uncover the mystery of the Illusion, and first we decided to figure out the ecology of the monsters inside the Illusion.";
+		next;
+		mes "[Director Joel]";
+		mes "What we found was that all illusions are affected by dimensional rifts.";
+		next;
+		mes "[Director Joel]";
+		mes "I've been speculating that it might be related to the dimensional rift for a long time, but with the results of this investigation, it's clear.";
+		next;
+		mes "[Director Joel]";
+		mes "There are still many adventurers visiting Illusion with a purpose, so the monster population is fortunately maintained.";
+		next;
+		mes "[Director Joel]";
+		mes "If no one sets foot there, it's very dangerous because the monsters can go beyond saturation and invade other areas.";
+		next;
+		mes "[Director Joel]";
+		mes "For that reason, the number of individuals is still being investigated, and one investigator is currently assigned to each illusion.";
+		next;
+		mes "[Director Joel]";
+		mes "And we're recruiting members with the ability to control the number of monsters inside Illusion.";
+		next;
+		mes "[Director Joel]";
+		mes "And if you're an adventurer, you seem to be strong enough for that role...";
+		next;
+		mes "[Director Joel]";
+		mes "Would you like to join the Illusion Investigation Team and join us in investigating illusions?";
+		next;
+		if (select( "I'm joining", "I'll think about it" ) == 2) {
+			mes "[Director Joel]";
+			mes "It's very meaningful.";
+			next;
+			mes "[Director Joel]";
+			mes "Please think about it before you tell me.";
+			close;
+		}
+		mes "[Director Joel]";
+		mes "Okay, you're welcome!!";
+		next;
+		mes "[Director Joel]";
+		mes "The procedure is simple, please fill out the pledge here...";
+		next;
+		mes "[Director Joel]";
+		mes "Here... please sign this.";
+		next;
+		mes "[Director Joel]";
+		mes ".";
+		next;
+		mes "[Director Joel]";
+		mes "..";
+		next;
+		mes "[Director Joel]";
+		mes "...";
+		next;
+		mes "[Director Joel]";
+		mes "Yes, with this you have become a member of the Illusionary Survey Corps, welcome again!";
+		next;
+		mes "[Director Joel]";
+		mes "If you have time during your adventure, I would like you to stop by the Illusions located in various places and help me with the investigation.";
+		next;
+		mes "[Director Joel]";
+		mes "A dispatched investigator will guide you.";
+		next;
+		mes "[Director Joel]";
+		mes "Then I hope you have a nice day";
+		close2;
+		setquest 3470;
+		completequest 3470;
+		end;
+	}
+	mes "[Director Joel]";
+	mes "I think the investigation will be much easier thanks to you, adventurer.";
+	next;
+	mes "[Director Joel]";
+	mes "New illusions will appear again.";
+	next;
+	mes "[Director Joel]";
+	mes "Every new discovery takes a lot of time for us to adapt to it";
+	next;
+	mes "[Director Joel]";
+	mes "This investigation will at least help reduce that time.";
+	next;
+	mes "[Director Joel]";
+	mes "Thank you and look forward to many more activities in the future.";
+	close;
+
+OnInit:
+	questinfo( QTYPE_EVENT, QMARK_YELLOW, "isbegin_quest(3470) == 0" );
+	end;
+}
+
+prt_in,136,29,3	script	Unit Zenhi#zenhi	4_F_KHELLY,{
+	mes "[Unit good]";
+	mes "Hello~~!!";
+	next;
+	mes "[Unit good]";
+	mes "The Illusion Investigation Corps is getting bigger little by little.";
+	next;
+	mes "[Unit good]";
+	mes "The more members, the more things we can do, right?";
+	close;
+}
+
+prt_in,121,36,6	script	Unit Zenian#zenian	4_F_HUWOMAN,{
+	mes "[Unit Xenian]";
+	mes "Hello, I'm Xenian, a new member of the team.";
+	next;
+	mes "[Unit Xenian]";
+	mes "I've been paying attention to the phenomenon of dimensional rifts for a long time. Clearly, despite many subjugations, monsters are constantly appearing.";
+	next;
+	mes "[Unit Xenian]";
+	mes "It has been proven that this phenomenon also occurs in illusions, so I decided to join the Illusion Investigation Team.";
+	next;
+	mes "[Unit Xenian]";
+	mes "Good luck in the future!!";
+	close;
+}
+
+prt_in,124,21,1	script	 Unit link#yeonsu	4_M_DEWWOMAN,{
+	mes "[Unit link]";
+	mes "Nice to meet you, this is the Welcome Survey Team.";
+	next;
+	mes "[Unit link]";
+	mes "Investigate the ecosystem of monsters in Illusion...";
+	next;
+	mes "[Unit link]";
+	mes "Also... I thought it might have something to do with the dimensional rift.";
+	next;
+	mes "[Unit link]";
+	mes "I hope that everyone who is working hard at this time will return safely without any incident.";
+	close;
+}
+
+pay_d03_i,149,34,5	script	Jiroker#ziroker	4_M_ORIENT02,{
+	if (BaseLevel < 100)
+		end;
+	if (isbegin_quest(3470) == 0) {
+		mes "[Jiroker]";
+		mes "Hello!!";
+		next;
+		mes "[Jiroker]";
+		mes "I am J-Jiroker from the Illusion Investigation Corps.";
+		next;
+		mes "[Jiroker]";
+		mes "Ugh... to really come to a place like this... I wish adventurers would help me too...";
+		next;
+		mes "[Jiroker]";
+		mes "You haven't joined the investigation team yet.";
+		next;
+		mes "[Jiroker]";
+		mes "Would you like to investigate the monsters here with me? It will definitely be meaningful!!";
+		next;
+		mes "[Jiroker]";
+		mes "Please apply for membership to <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI>, the investigator in Prontera, and come!!";
+		close;
+	}
+	if (isbegin_quest(3446) == 0) {
+		mes "[Jiroker]";
+		mes "Hello!!";
+		next;
+		mes "[Jiroker]";
+		mes "I am J-Jiroker from the Illusion Investigation Corps.";
+		next;
+		mes "[Jiroker]";
+		mes "Ugh... To come to a place like this...";
+		next;
+		mes "[Jiroker]";
+		mes "I usually pretended to be brave, but I think I was conscious of Elysia, the member I have a crush on.";
+		next;
+		mes "[Jiroker]";
+		mes "Actually, I'm the one who's more timid than anyone else... heck";
+		next;
+		mes "[Jiroker]";
+		mes "Anyway... I'm in charge of investigating this place.";
+		next;
+		mes "[Jiroker]";
+		mes "Have you heard about the investigation from Captain Joel? Adventurer, you have to completely hunt 100 monsters by yourself.";
+		next;
+		mes "[Jiroker]";
+		mes "Would you like to participate in the investigation of this place?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Jiroker]";
+			mes "Then should I ask another adventurer...";
+			close;
+		}
+		mes "[Jiroker]";
+		mes "I like it!!";
+		next;
+		mes "[Jiroker]";
+		mes "Just kill 100 monsters of any type here.";
+		next;
+		mes "[Jiroker]";
+		mes "Then be careful!";
+		close2;
+		setquest 3446;
+		completequest 3446;
+		setquest 3447;
+		end;
+	}
+	switch( checkquest(3448,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Jiroker]";
+		mes "Ah, that's enough for today's investigation.";
+		next;
+		mes "[Jiroker]";
+		mes "It will be restored tomorrow, so if you can afford it, I would appreciate it if you could come and help me with the investigation!!";
+		close;
+	case 2:
+		erasequest 3448;
+		break;
+	}
+	switch( checkquest(3447,HUNTING) ) {
+	case -1:
+		mes "[Jiroker]";
+		mes "Hello, are you here today to help with the investigation?";
+		next;
+		mes "[Jiroker]";
+		mes "The content is the same as last time.";
+		next;
+		mes "[Jiroker]";
+		mes "If you kill 100 monsters of any type, would you like to participate?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Jiroker]";
+			mes "It would be nice if you could help me today...";
+			close;
+		}
+		mes "[Jiroker]";
+		mes "I like it!!";
+		next;
+		mes "[Jiroker]";
+		mes "Just kill 100 monsters of any type here.";
+		next;
+		mes "[Jiroker]";
+		mes "Then be careful!";
+		close2;
+		setquest 3447;
+		end;
+	case 0:
+	case 1:
+		mes "[Jiroker]";
+		mes "Kill 100 monsters of any type.";
+		close;
+	case 2:
+		mes "[Jiroker]";
+		mes "You're back safely!";
+		next;
+		mes "[Jiroker]";
+		mes "Okay... Then hmm... I'll have to wait and see how much monsters spawn for a while.";
+		next;
+		mes "[Jiroker]";
+		mes "Leave the rest to me!! Thanks!!";
+		close2;
+		erasequest 3447;
+		setquest 3448;
+		getexp 2500000,2500000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 100 && isbegin_quest(3470) == 2 && isbegin_quest(3446) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3447,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3446) == 2 && checkquest(3448,PLAYTIME) == -1 && checkquest(3447,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3448,PLAYTIME) == 2" );
+	end;
+}
+
+ice_dun02,142,18,5	script	Elysia#elisia	4_F_OPERATION,{
+	if (BaseLevel < 120) {
+		mes "[Elysia]";
+		mes "Oh, must you have a hard time enduring the cold here?";
+		next;
+		mes "[Elysia]";
+		mes "Come back when you're a little hotter.";
+		next;
+		mes "^4d4dff== This is a level 120 or higher quest. ==^000000";
+		close;
+	}
+	if (isbegin_quest(3470) == 0) {
+		mes "[Elysia]";
+		mes "Hello~";
+		next;
+		mes "[Elysia]";
+		mes "I'm Elysia from the Illusion Investigation Team~";
+		next;
+		mes "[Elysia]";
+		mes "It's really cold here...";
+		next;
+		mes "[Elysia]";
+		mes "I'd like to ask the adventurer for help...";
+		next;
+		mes "[Elysia]";
+		mes "You haven't joined the investigation team yet.";
+		next;
+		mes "[Elysia]";
+		mes "If you don't mind, why don't you join the Illusionary Survey Corps? Then you can help me!!!";
+		next;
+		mes "[Elysia]";
+		mes "Please apply for membership to <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI>, the investigator in Prontera, and come!!";
+		close;
+	}
+	if (isbegin_quest(3449) == 0) {
+		mes "[Elysia]";
+		mes "Hello~";
+		next;
+		mes "[Elysia]";
+		mes "I'm Elysia from the Illusion Investigation Team~";
+		next;
+		mes "[Elysia]";
+		mes "It's really cold here...";
+		next;
+		mes "[Elysia]";
+		mes "I never thought I would be sent to such a dangerous place alone... I wanted to come with G-Locker...";
+		next;
+		mes "[Elysia]";
+		mes "Well, even if there was a G-Locker, he's a coward, so I'd be in a position to protect him...";
+		next;
+		mes "[Elysia]";
+		mes "You pretended to be brave... but I already noticed";
+		next;
+		mes "[Elysia]";
+		mes "Is Jirocker doing his investigation safely in the abandoned village? I'm worried.";
+		next;
+		mes "[Elysia]";
+		mes "Hmm... Actually, now is not the time to worry about G-Locker, Adventurer. Can you help me?";
+		next;
+		mes "[Elysia]";
+		mes "Did you hear that this is an investigation into how the monster population is maintained? Many adventurers come here to hunt, but it's a bit lacking.";
+		next;
+		mes "[Elysia]";
+		mes "It's easy to figure out the number of monsters when you deal with them hotly. How about you? Would you like to participate in the investigation of this place?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Elysia]";
+			mes "Yeah, that's right...";
+			next;
+			mes "[Elysia]";
+			mes "Then I'll be shivering a little longer...";
+			close;
+		}
+		mes "[Elysia]";
+		mes "Oh yes!! Thanks!!";
+		next;
+		mes "[Elysia]";
+		mes "After entering, kill 100 monsters of any type.";
+		next;
+		mes "[Elysia]";
+		mes "I look forward to your hot hunting skills~~!!";
+		close2;
+		setquest 3449;
+		completequest 3449;
+		setquest 3450;
+		end;
+	}
+	switch( checkquest(3451,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Elysia]";
+		mes "Ah, I think this should be enough for today!!";
+		next;
+		mes "[Elysia]";
+		mes "If you come after tomorrow, you'll have something else to do~";
+		close;
+	case 2:
+		erasequest 3451;
+		break;
+	}
+	switch( checkquest(3450,HUNTING) ) {
+	case -1:
+		mes "[Elysia]";
+		mes "Ah, nice to meet you!! Are you here today to help with the investigation??";
+		next;
+		mes "[Elysia]";
+		mes "Your help is the same as last time~";
+		next;
+		mes "[Elysia]";
+		mes "If you kill 100 monsters of any type, would you like to participate?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Elysia]";
+			mes "Okay... I'll keep shivering in the cold...";
+			close;
+		}
+		mes "[Elysia]";
+		mes "Thank you";
+		next;
+		mes "[Elysia]";
+		mes "After entering, kill 100 monsters of any type.";
+		next;
+		mes "[Elysia]";
+		mes "Then be careful!";
+		close2;
+		setquest 3450;
+		end;
+	case 0:
+	case 1:
+		mes "[Elysia]";
+		mes "Kill 100 monsters regardless of type.";
+		close;
+	case 2:
+		mes "[Elysia]";
+		mes "Have you finished already? You've done it hotly as expected~";
+		next;
+		mes "[Elysia]";
+		mes "Then I'll do the rest of the research for you~";
+		next;
+		mes "[Elysia]";
+		mes "Thank you for your hard work. I hope we can meet again!!";
+		close2;
+		erasequest 3450;
+		setquest 3451;
+		getexp 6000000,6000000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 120 && isbegin_quest(3470) == 2 && isbegin_quest(3449) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3450,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3449) == 2 && checkquest(3451,PLAYTIME) == -1 && checkquest(3450,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3451,PLAYTIME) == 2" );
+	end;
+}
+
+gef_d01_i,122,237,3	script	Radimir#ridimir	8_F,{
+	if (BaseLevel < 130)
+		end;
+	if (isbegin_quest(3470) == 0) {
+		mes "[Radimir]";
+		mes "Hello, Adventurer";
+		next;
+		mes "[Radimir]";
+		mes "I am Radimir from the Illusion Investigation.";
+		next;
+		mes "[Radimir]";
+		mes "I'm sent to such a dreary place, and honestly, I'm very afraid";
+		next;
+		mes "[Radimir]";
+		mes "I'd like you to conduct the investigation together, but... you haven't joined the investigation team yet.";
+		next;
+		mes "[Radimir]";
+		mes "Would you like to do something meaningful with me?";
+		next;
+		mes "[Radimir]";
+		mes "If you are interested, please meet <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI>, the Investigator in Prontera, and join the Investigation Team and come back.";
+		close;
+	}
+	if (isbegin_quest(3452) == 0) {
+		mes "[Radimir]";
+		mes "Hello, Adventurer";
+		next;
+		mes "[Radimir]";
+		mes "I am Radimir from the Illusion Investigation.";
+		next;
+		mes "[Radimir]";
+		mes "I'm sent to such a dreary place, and honestly, I'm very afraid";
+		next;
+		mes "[Radimir]";
+		mes "But I've always been interested in the phenomenon of illusion, and when the investigation team was founded, I actively applied for membership.";
+		next;
+		mes "[Radimir]";
+		mes "Because nobody has figured it out yet";
+		next;
+		mes "[Radimir]";
+		mes "It's just the beginning of the current investigation, but it's sure to be a great first step";
+		next;
+		mes "[Radimir]";
+		mes "Therefore, fear can be overcome by will.";
+		next;
+		mes "[Radimir]";
+		mes "Investigation preparations are complete, now I'm waiting for someone who can adjust the monsters' levels.";
+		next;
+		mes "[Radimir]";
+		mes "How about you, why don't you participate in the investigation? You joined the investigation team for that, right?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Radimir]";
+			mes "I'll stay here";
+			close;
+		}
+		mes "[Radimir]";
+		mes "Good.";
+		next;
+		mes "[Radimir]";
+		mes "Just kill 100 monsters of any type here.";
+		next;
+		mes "[Radimir]";
+		mes "The sooner the better.";
+		next;
+		mes "[Radimir]";
+		mes "Then I'll be waiting for you.";
+		close2;
+		setquest 3452;
+		completequest 3452;
+		setquest 3453;
+		end;
+	}
+	switch( checkquest(3454,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Radimir]";
+		mes "That's it for today.";
+		next;
+		mes "[Radimir]";
+		mes "If the current trend, I think we can resume the investigation in a day or so. Please come then.";
+		close;
+	case 2:
+		erasequest 3454;
+		break;
+	}
+	switch( checkquest(3453,HUNTING) ) {
+	case -1:
+		mes "[Radimir]";
+		mes "Hello, are you here today to help with the investigation?";
+		next;
+		mes "[Radimir]";
+		mes "Please execute the operation as it was then.";
+		next;
+		mes "[Radimir]";
+		mes "Would you like to participate in the task of killing 100 monsters of any type?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Radimir]";
+			mes "You acted meaninglessly, I'm disappointed.";
+			close;
+		}
+		mes "[Radimir]";
+		mes "Thank you";
+		next;
+		mes "[Radimir]";
+		mes "Kill 100 monsters of any type.";
+		next;
+		mes "[Radimir]";
+		mes "Then I'll be waiting for you.";
+		close2;
+		setquest 3453;
+		end;
+	case 0:
+	case 1:
+		mes "[Radimir]";
+		mes "Kill 100 monsters of any type.";
+		close;
+	case 2:
+		mes "[Radimir]";
+		mes "You came through quickly, thank you.";
+		next;
+		mes "[Radimir]";
+		mes "That makes it easier to work out the numbers.";
+		next;
+		mes "[Radimir]";
+		mes "I will finish the rest of the work soon and report it to the investigation team. Thank you for your hard work.";
+		close2;
+		erasequest 3453;
+		setquest 3454;
+		getexp 10000000,10000000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 130 && isbegin_quest(3470) == 2 && isbegin_quest(3452) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3453,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3452) == 2 && checkquest(3454,PLAYTIME) == -1 && checkquest(3453,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3454,PLAYTIME) == 2" );
+	end;
+}
+
+/*
+ein_d02_i,161,180,5	script	Machoko#machoco	8_F_GIRL,{
+	if (BaseLevel < 150)
+		end;
+	if (isbegin_quest(3470) == 0) {
+		mes "[Machoko]";
+		mes "Hello!!!";
+		next;
+		mes "[Machoko]";
+		mes "I'm Machoko from the Illusion Investigation Team~";
+		next;
+		mes "[Machoko]";
+		mes "I really wanted to be dispatched to this place, but I was lucky.";
+		next;
+		mes "[Machoko]";
+		mes "These damn teddy bears~~ The teddy bears...";
+		next;
+		mes "[Machoko]";
+		mes "But it's impossible for me... I don't have enough strength... But you haven't joined the investigation team yet...";
+		next;
+		mes "[Machoko]";
+		mes "You can sign up by going to <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI>, the investigation leader in Prontera. Sign up and come here~";
+		close;
+	}
+	if (isbegin_quest(3455) == 0) {
+		mes "[Machoko]";
+		mes "Hello!!!";
+		next;
+		mes "[Machoko]";
+		mes "I'm Machoko from the Illusion Investigation Team~";
+		next;
+		mes "[Machoko]";
+		mes "I really wanted to be dispatched to this place, but I was lucky.";
+		next;
+		mes "[Machoko]";
+		mes "These damn teddy bears~~ The teddy bears...";
+		next;
+		mes "[Machoko]";
+		mes "But it's impossible for me... I don't have enough strength... He looks easy... but he's so strong...";
+		next;
+		mes "[Machoko]";
+		mes "I thought I could do it all by myself... I took it too lightly... Huh...";
+		next;
+		mes "[Machoko]";
+		mes "I unknowingly and vigorously attacked and came back with a lot of beating... I almost died...";
+		next;
+		mes "[Machoko]";
+		mes "I barely recovered... I think it's possible to investigate, but you look a little strong?";
+		next;
+		mes "[Machoko]";
+		mes "Then help me... I need someone to take control of those vicious teddy bears...";
+		next;
+		mes "[Machoko]";
+		mes "How about it? Do you want to join the investigation??";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Machoko]";
+			mes "Yes... I'm about to collapse after I've been here... Like a man without blood or tears...";
+			close;
+		}
+		mes "[Machoko]";
+		mes "Okay! Let's go!!";
+		next;
+		mes "[Machoko]";
+		mes "Go and beat up about 100 of them, and come, it doesn't matter what type, blow them up as you see them!!";
+		next;
+		mes "[Machoko]";
+		mes "I... can't even move... Here... I'll wait...";
+		close2;
+		setquest 3455;
+		completequest 3455;
+		setquest 3456;
+		end;
+	}
+	switch( checkquest(3457,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Machoko]";
+		mes "Well, no more today";
+		next;
+		mes "[Machoko]";
+		mes "Come back after a day!!";
+		close;
+	case 2:
+		erasequest 3457;
+		break;
+	}
+	switch( checkquest(3456,HUNTING) ) {
+	case -1:
+		mes "[Machoko]";
+		mes "Oh, nice to meet you! Welcome back!";
+		next;
+		mes "[Machoko]";
+		mes "You must have come here because your body itches.";
+		next;
+		mes "[Machoko]";
+		mes "Would you like to participate in the investigation work here again today??";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Machoko]";
+			mes "What...then why did you come??";
+			close;
+		}
+		mes "[Machoko]";
+		mes "Sure, that's how it should be";
+		next;
+		mes "[Machoko]";
+		mes "Regardless of the type, just beat 100 of them and bring them back.";
+		next;
+		mes "[Machoko]";
+		mes "I'll be waiting for you, so hurry up!!";
+		close2;
+		setquest 3456;
+		end;
+	case 0:
+	case 1:
+		mes "[Machoko]";
+		mes "Go and beat up about 100 of them, and come, it doesn't matter what type, blow them up as you see them!!";
+		close;
+	case 2:
+		mes "[Machoko]";
+		mes "I've been waiting for you... finish quickly and come back...";
+		next;
+		mes "[Machoko]";
+		mes "Um...but that's about it... um...yeah!! good!!";
+		next;
+		mes "[Machoko]";
+		mes "Leave the rest to me!! I'll report the results to the investigation team, now you can go and rest.";
+		next;
+		mes "[Machoko]";
+		mes "Thank you~~";
+		close2;
+		erasequest 3456;
+		setquest 3457;
+		getexp 17500000,12500000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 150 && isbegin_quest(3470) == 2 && isbegin_quest(3455) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3456,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3455) == 2 && checkquest(3457,PLAYTIME) == -1 && checkquest(3456,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3457,PLAYTIME) == 2" );
+	end;
+}
+*/
+
+tur_d03_i,125,186,5	script	Orian#orian	4_M_LGTPOOR,{
+	if (BaseLevel < 150)
+		end;
+	if (isbegin_quest(3470) == 0) {
+		mes "[Orian]";
+		mes "Hello!";
+		next;
+		mes "[Orian]";
+		mes "I'm Orian, a contract worker in the Illusion Investigation Corps.";
+		next;
+		mes "[Orian]";
+		mes "Actually, it's not something I'm keen on...but I need the money...";
+		next;
+		mes "[Orian]";
+		mes "It would be nice if you could help me... is that possible?";
+		next;
+		mes "[Orian]";
+		mes "Uh, but you haven't joined the investigation team yet.";
+		next;
+		mes "[Orian]";
+		mes "Please apply for membership to <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI>, the investigator in Prontera, and come!!";
+		close;
+	}
+	if (isbegin_quest(3458) == 0) {
+		mes "[Orian]";
+		mes "Hello!";
+		next;
+		mes "[Orian]";
+		mes "I'm Orian, a contract worker in the Illusion Investigation Corps.";
+		next;
+		mes "[Orian]";
+		mes "The Illumination Investigation Team is a newly formed organization, so it must have been a little understaffed. I saw an announcement that they would hire part-time contract workers.";
+		next;
+		mes "[Orian]";
+		mes "Actually, I'm not interested in illusions... I'm busy making a living.";
+		next;
+		mes "[Orian]";
+		mes "Huh... It's all about money, I'm going to buy a new set of clothes when I get paid.";
+		next;
+		mes "[Orian]";
+		mes "But even that isn't easy... I've been waiting for an investigator like you to come because I think it's going to be very difficult on my own.";
+		next;
+		mes "[Orian]";
+		mes "It would be nice if you could help me... is that possible?";
+		next;
+		mes "[Orian]";
+		mes "Would you like to participate in this Illusion Investigation?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Orian]";
+			mes "Ah... I finally found an investigator... Ah... I want money...";
+			close;
+		}
+		mes "[Orian]";
+		mes "Oh, thank you";
+		next;
+		mes "[Orian]";
+		mes "Please go up one floor from here and go to the bleak Guyang Palace.";
+		next;
+		mes "[Orian]";
+		mes "And please kill 100 monsters there, regardless of type.";
+		next;
+		mes "[Orian]";
+		mes "I'll be waiting for you here. Have a safe trip!!";
+		close2;
+		setquest 3458;
+		completequest 3458;
+		setquest 3459;
+		end;
+	}
+	switch( checkquest(3460,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Orian]";
+		mes "You're not fit to do research right now.";
+		next;
+		mes "[Orian]";
+		mes "I think it will be fine by tomorrow, can you come back after tomorrow?";
+		close;
+	case 2:
+		erasequest 3460;
+		break;
+	}
+	switch( checkquest(3459,HUNTING) ) {
+	case -1:
+		mes "[Orian]";
+		mes "Hello, you are the only one who can help me...";
+		next;
+		mes "[Orian]";
+		mes "What we need to do is the same as last time...";
+		next;
+		mes "[Orian]";
+		mes "Are you going to help me with the illusion investigation again?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Orian]";
+			mes "Aigoo...";
+			next;
+			mes "[Orian]";
+			mes "Sob.....";
+			close;
+		}
+		mes "[Orian]";
+		mes "Oops... Thank you...";
+		next;
+		mes "[Orian]";
+		mes "Go to the bleak archery and kill 100 monsters of any type.";
+		next;
+		mes "[Orian]";
+		mes "Then be careful...";
+		close2;
+		setquest 3459;
+		end;
+	case 0:
+	case 1:
+		mes "[Orian]";
+		mes "Destroy 100 monsters of any type in the bleak Archery.";
+		close;
+	case 2:
+		mes "[Orian]";
+		mes "You came home safely.";
+		next;
+		mes "[Orian]";
+		mes "Uh... You took it down a lot faster than I expected.. You... you were a master??";
+		next;
+		mes "[Orian]";
+		mes "That should make the rest of the work easier.";
+		next;
+		mes "[Orian]";
+		mes "Thank you~ Thank you for your hard work!!";
+		close2;
+		erasequest 3459;
+		setquest 3460;
+		getexp 22500000,16000000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 150 && isbegin_quest(3470) == 2 && isbegin_quest(3458) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3459,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3458) == 2 && checkquest(3460,PLAYTIME) == -1 && checkquest(3459,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3460,PLAYTIME) == 2" );
+	end;
+}
+
+/*
+ant_d02_i,167,184,5	script	Sheshin#sesin	1_M_MOC_LORD,{
+	if (BaseLevel < 160)
+		end;
+	if (isbegin_quest(3470) == 0) {
+		mes "[Sheshin]";
+		mes "Nice to meet you.";
+		next;
+		mes "[Sheshin]";
+		mes "I am Sheshin belonging to the Illusion Investigation Corps.";
+		next;
+		mes "[Sheshin]";
+		mes "I thought my fighting power would be enough to investigate here... but I guess I made a mistake.";
+		next;
+		mes "[Sheshin]";
+		mes "The monsters here are much stronger than I expected.";
+		next;
+		mes "[Sheshin]";
+		mes "Ah... I'm really proud of myself... but I need help... Hmm...";
+		next;
+		mes "[Sheshin]";
+		mes "Adventurer hasn't joined the Illusion Investigation Team yet.";
+		next;
+		mes "[Sheshin]";
+		mes "Would you like to join the Illusionary Investigation Team? Wouldn't it be exciting to explore unknown phenomena?";
+		next;
+		mes "[Sheshin]";
+		mes "If you would like to sign up, please go see Director <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI> in Prontera.";
+		close;
+	}
+	if (isbegin_quest(3507) == 0) {
+		mes "[Sheshin]";
+		mes "Nice to meet you.";
+		next;
+		mes "[Sheshin]";
+		mes "I am Sheshin belonging to the Illusion Investigation Corps.";
+		next;
+		mes "[Sheshin]";
+		mes "I was active as a member of the Continental Guard in the past. At that time, I was tasked with exploring the dimensional rift created by the power of the demon king Morocc.";
+		next;
+		mes "[Sheshin]";
+		mes "I was guessing to some extent that the illusions appearing everywhere had something to do with the power of the dimensional rift.";
+		next;
+		mes "[Sheshin]";
+		mes "It has been officially announced by Director Joel that the Illusion is a phenomenon caused by a dimensional rift.";
+		next;
+		mes "[Sheshin]";
+		mes "And soon a new illusion was discovered, yes... right here";
+		next;
+		mes "[Sheshin]";
+		mes "I joined the Illusion Investigation Team because I wanted to see it with my own eyes, and now I am here.";
+		next;
+		mes "[Sheshin]";
+		mes "But I ran into a little problem...";
+		next;
+		mes "[Sheshin]";
+		mes "I thought my fighting power would be enough to investigate here... but I guess I made a mistake.";
+		next;
+		mes "[Sheshin]";
+		mes "The monsters here are much stronger than I expected.";
+		next;
+		mes "[Sheshin]";
+		mes "Ah... I really hurt my pride... but I need help...";
+		next;
+		mes "[Sheshin]";
+		mes "Hmm... I think it's possible enough for you as an adventurer...";
+		next;
+		mes "[Sheshin]";
+		mes "I feel that you have much more power than me.";
+		next;
+		mes "[Sheshin]";
+		mes "Would you like to help me investigate the illusions in this sector?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Sheshin]";
+			mes "This must be a good opportunity for adventurers...";
+			close;
+		}
+		mes "[Sheshin]";
+		mes "Good.";
+		next;
+		mes "[Sheshin]";
+		mes "Please kill 100 monsters of any type located inside here.";
+		next;
+		mes "[Sheshin]";
+		mes "Then, please travel carefully without getting hurt.";
+		close2;
+		setquest 3507;
+		completequest 3507;
+		setquest 3508;
+		end;
+	}
+	switch( checkquest(3509,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Sheshin]";
+		mes "You don't have to do any more research today.";
+		next;
+		mes "[Sheshin]";
+		mes "Can you come back tomorrow if you want?";
+		close;
+	case 2:
+		erasequest 3509;
+		break;
+	}
+	switch( checkquest(3508,HUNTING) ) {
+	case -1:
+		mes "[Sheshin]";
+		mes "Welcome, you're here to help investigate the illusion, right?";
+		next;
+		mes "[Sheshin]";
+		mes "You can do the same thing as last time.";
+		next;
+		mes "[Sheshin]";
+		mes "If you kill 100 monsters of any type, would you like to participate?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Sheshin]";
+			mes "It's a pity, it's sad that I still lack strength.";
+			close;
+		}
+		mes "[Sheshin]";
+		mes "Good.";
+		next;
+		mes "[Sheshin]";
+		mes "Then, please travel carefully without getting hurt.";
+		close2;
+		setquest 3508;
+		end;
+	case 0:
+	case 1:
+		mes "[Sheshin]";
+		mes "Kill 100 monsters of any type.";
+		close;
+	case 2:
+		mes "[Sheshin]";
+		mes "I see... you finished quickly and came back.";
+		next;
+		mes "[Sheshin]";
+		mes "I need to investigate further to see if the phenomenon here is also affected by the dimensional rift.";
+		next;
+		mes "[Sheshin]";
+		mes "I'll do the work myself from now on.";
+		next;
+		mes "[Sheshin]";
+		mes "Thank you so much for your help";
+		close2;
+		erasequest 3508;
+		setquest 3509;
+		getexp 27000000,18000000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 160 && isbegin_quest(3470) == 2 && isbegin_quest(3507) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3508,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3507) == 2 && checkquest(3509,PLAYTIME) == -1 && checkquest(3508,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3509,PLAYTIME) == 2" );
+	end;
+}
+*/
+
+com_d02_i,253,232,3	script	Cassis#kesis	4_M_KHBOY,{
+	if (BaseLevel < 160)
+		end;
+	if (isbegin_quest(3470) == 0) {
+		mes "[Cassis]";
+		mes "Hello.";
+		next;
+		mes "[Cassis]";
+		mes "This is Cassis of the Illusion Investigation Corps.";
+		next;
+		mes "[Cassis]";
+		mes "Although this place is full of monsters, I still feel comfortable here.";
+		next;
+		mes "[Cassis]";
+		mes "I heard that one of the investigators is coming to help... is that you?";
+		next;
+		mes "[Cassis]";
+		mes "Oh, that's not true. You're not a member of the investigation team... Hmm.";
+		next;
+		mes "[Cassis]";
+		mes "Would you like to join the Illusionary Investigation Team too? Would you like to investigate strange phenomena?";
+		next;
+		mes "[Cassis]";
+		mes "If you don't mind, please apply for membership with the investigator <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI> in Prontera and come!";
+		close;
+	}
+	if (isbegin_quest(3461) == 0) {
+		mes "[Cassis]";
+		mes "Hello";
+		next;
+		mes "[Cassis]";
+		mes "This is Cassis of the Illusion Investigation Corps.";
+		next;
+		mes "[Cassis]";
+		mes "Although this place is full of monsters, I still feel comfortable here.";
+		next;
+		mes "[Cassis]";
+		mes "I don't like to get involved with people. Before I joined the investigation team, I ran a shop in Prontera...";
+		next;
+		mes "[Cassis]";
+		mes "I don't like the feeling of being crowded, so it was hard to bear... I guess meeting a lot of people was stressful for my personality.";
+		next;
+		mes "[Cassis]";
+		mes "Although this place is full of monsters, I still feel comfortable here, at least the monsters don't talk to me.";
+		next;
+		mes "[Cassis]";
+		mes "Ummm, by the way, I heard that one of the investigators is coming to help... I guess that's you?";
+		next;
+		mes "[Cassis]";
+		mes "Have you heard the general information from Captain Joel? You just need to display your fighting power without hesitation!!";
+		next;
+		mes "[Cassis]";
+		mes "Would you like to participate in the investigation of this place?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Cassis]";
+			mes "Uh, then who the hell is the investigative team coming...?";
+			close;
+		}
+		mes "[Cassis]";
+		mes "Okay, thank you";
+		next;
+		mes "[Cassis]";
+		mes "Just kill 100 monsters of any type that exist here.";
+		next;
+		mes "[Cassis]";
+		mes "Then good luck.";
+		close2;
+		setquest 3461;
+		completequest 3461;
+		setquest 3462;
+		end;
+	}
+	switch( checkquest(3463,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Cassis]";
+		mes "Today's investigation is complete.";
+		next;
+		mes "[Cassis]";
+		mes "It would be nice if you could come tomorrow too... Please stop by if you have time.";
+		close;
+	case 2:
+		erasequest 3463;
+		break;
+	}
+	switch( checkquest(3462,HUNTING) ) {
+	case -1:
+		mes "[Cassis]";
+		mes "Hello, are you here today to help with the investigation?";
+		next;
+		mes "[Cassis]";
+		mes "The content is the same as last time.";
+		next;
+		mes "[Cassis]";
+		mes "If you kill 100 monsters of any type, would you like to participate";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Cassis]";
+			mes "It would be nice if you could help me today...";
+			close;
+		}
+		mes "[Cassis]";
+		mes "I like it!!";
+		next;
+		mes "[Cassis]";
+		mes "After entering, kill 100 monsters of any type.";
+		next;
+		mes "[Cassis]";
+		mes "Then be careful!";
+		close2;
+		setquest 3462;
+		end;
+	case 0:
+	case 1:
+		mes "[Cassis]";
+		mes "Kill 100 monsters of any type.";
+		close;
+	case 2:
+		mes "[Cassis]";
+		mes "Welcome, you're done!!";
+		next;
+		mes "[Cassis]";
+		mes "You've worked really hard. Are there any injuries anywhere?";
+		next;
+		mes "[Cassis]";
+		mes "Leave the rest to me. Thanks";
+		close2;
+		erasequest 3462;
+		setquest 3463;
+		getexp 29000000,19600000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 160 && isbegin_quest(3470) == 2 && isbegin_quest(3461) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3462,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3461) == 2 && checkquest(3463,PLAYTIME) == -1 && checkquest(3462,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3463,PLAYTIME) == 2" );
+	end;
+}
+
+/*
+prt_fild01,131,364,5	script	Terrian#terian	4W_M_02,{
+	if (BaseLevel < 170) {
+		mes "[Terrian]";
+		mes "It's nice weather.";
+		next;
+		mes "[Terrian]";
+		mes "The weather is nice, but your level is low.";
+		next;
+		mes "^4d4dff== This is a level 170 or higher quest. ==^000000";
+		close;
+	}
+	if (isbegin_quest(3470) == 0) {
+		mes "[Terrian]";
+		mes "The weather is nice";
+		next;
+		mes "[Terrian]";
+		mes "I'm a Terrian from the Illusion Investigation Corps.";
+		next;
+		mes "[Terrian]";
+		mes "What do you think about the theory of reincarnation, adventurer?";
+		next;
+		mes "[Terrian]";
+		mes "It seems that a phenomenon very close to the theory of reincarnation I believe is appearing in illusions.";
+		next;
+		mes "[Terrian]";
+		mes "To investigate it, I became a member of the Illusion Investigation Team.";
+		next;
+		mes "[Terrian]";
+		mes "Would you like to join me too, adventurer? Uh... but you're not yet a member of the Illusion Investigation Corps.";
+		next;
+		mes "[Terrian]";
+		mes "If you don't mind, please apply for membership with the investigator <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI> in Prontera.";
+		close;
+	}
+	if (isbegin_quest(3467) == 0) {
+		mes "[Terrian]";
+		mes "The weather is nice";
+		next;
+		mes "[Terrian]";
+		mes "I'm a Terrian from the Illusion Investigation Corps.";
+		next;
+		mes "[Terrian]";
+		mes "What do you think about the theory of reincarnation, adventurer?";
+		next;
+		mes "[Terrian]";
+		mes "It seems that a phenomenon very close to the theory of reincarnation I believe is appearing in illusions.";
+		next;
+		mes "[Terrian]";
+		mes "To investigate it, I became a member of the Illusion Investigation Team.";
+		next;
+		mes "[Terrian]";
+		mes "After the flowers wither in winter, they will bloom again in spring. They always bloom in the place where the flowers withered and fell off.";
+		next;
+		mes "[Terrian]";
+		mes "It's the same with animals, the appearance of each of which varies innumerable, but for hundreds of years it has been discovered that there has always been a completely identical appearance";
+		next;
+		mes "[Terrian]";
+		mes "This is the core of the theory of reincarnation, and it takes a very long time to observe and investigate it.";
+		next;
+		mes "[Terrian]";
+		mes "But in places like Illusion, monsters are multiplying at an abnormal rate.";
+		next;
+		mes "[Terrian]";
+		mes "No, to be precise, when the number of monsters in Illusion decreases, the number of monsters recovers very quickly.";
+		next;
+		mes "[Terrian]";
+		mes "Because the speed at which monster objects recover is very fast, it is a good opportunity for me to check the 'object persistence' required by the Illusion Investigation Team and whether or not they are reincarnated.";
+		next;
+		mes "[Terrian]";
+		mes "Would you like to join us in this meaningful investigation?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Terrian]";
+			mes "We'll just have to wait for the other investigators to come...";
+			close;
+		}
+		mes "[Terrian]";
+		mes "Thank you";
+		next;
+		mes "[Terrian]";
+		mes "In order to determine the individual recovery rate, we need to reduce the number of monsters as quickly as possible.";
+		next;
+		mes "[Terrian]";
+		mes "Please return after defeating 100 monsters of any type in the Twisted Labyrinth Forest Dungeon accessible through the entrance in front of here.";
+		next;
+		mes "[Terrian]";
+		mes "Then I'll be waiting for you.";
+		close2;
+		setquest 3464;
+		completequest 3464;
+		setquest 3465;
+		end;
+	}
+	switch( checkquest(3466,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Terrian]";
+		mes "This is enough for today's investigation.";
+		next;
+		mes "[Terrian]";
+		mes "The population will be fully recovered tomorrow, so if you can afford it, I'd appreciate it if you could come and help me with the investigation.";
+		close;
+	case 2:
+		erasequest 3466;
+		break;
+	}
+	switch( checkquest(3465,HUNTING) ) {
+	case -1:
+		mes "[Terrian]";
+		mes "Hello, are you here today to help with your investigation?";
+		next;
+		mes "[Terrian]";
+		mes "The contents to be executed are the same as last time.";
+		next;
+		mes "[Terrian]";
+		mes "If you kill 100 monsters of any type, would you like to participate?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Terrian]";
+			mes "Sorry, maybe I should ask someone else for help...";
+			close;
+		}
+		mes "[Terrian]";
+		mes "Thank you";
+		next;
+		mes "[Terrian]";
+		mes "In order to determine the individual recovery rate, we need to reduce the number of monsters as quickly as possible.";
+		next;
+		mes "[Terrian]";
+		mes "Please return after defeating 100 monsters of any type in the Twisted Labyrinth Forest Dungeon accessible through the entrance in front of here.";
+		close2;
+		setquest 3465;
+		end;
+	case 0:
+	case 1:
+		mes "[Terrian]";
+		mes "Kill 100 monsters of any type.";
+		close;
+	case 2:
+		mes "[Terrian]";
+		mes "Thank you for coming back so quickly.";
+		next;
+		mes "[Terrian]";
+		mes "Thanks to your work, data collection has never been easier.";
+		next;
+		mes "[Terrian]";
+		mes "I'll send the results to the investigation team soon, thank you!!";
+		close2;
+		erasequest 3465;
+		setquest 3466;
+		getexp 35000000,22750000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 170 && isbegin_quest(3470) == 2 && isbegin_quest(3464) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3465,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3464) == 2 && checkquest(3466,PLAYTIME) == -1 && checkquest(3465,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3466,PLAYTIME) == 2" );
+	end;
+}
+*/
+
+iz_d04_i,127,224,5	script	Lister#ristar	4_F_01,{
+	if (BaseLevel < 180) {
+		mes "[Lister]";
+		mes "Hello";
+		next;
+		mes "[Lister]";
+		mes "I need help with my research work, so I'm looking for a suitable helper.";
+		next;
+		mes "[Lister]";
+		mes "You're not the right person yet, sorry.";
+		next;
+		mes "^4d4dff== This is a level 180 or higher quest. ==^000000";
+		close;
+	}
+	if (isbegin_quest(3470) == 0) {
+		mes "[Lister]";
+		mes "Hello~";
+		next;
+		mes "[Lister]";
+		mes "I am Lista who is active in the Illusion Investigation Team.";
+		next;
+		mes "[Lister]";
+		mes "It's been a while since I came down to the deep sea with Master.";
+		next;
+		mes "[Lister]";
+		mes "I'm always working hard, but I don't think Master still approves of me.";
+		next;
+		mes "[Lister]";
+		mes "Just in time, the Illusion Investigation Team said they needed to investigate the deep sea here, so I quickly applied.";
+		next;
+		mes "[Lister]";
+		mes "I'm sure Master would be happy if we could get even a little bit more information about the deep sea here as part of the investigation team!!!";
+		next;
+		mes "[Lister]";
+		mes "Would you like to come with me?";
+		next;
+		mes "[Lister]";
+		mes "Uh, but you haven't joined the investigation team yet.";
+		next;
+		mes "[Lister]";
+		mes "Please apply for membership to <NAVI>[Joel]<INFO>prt_in,136,34,</INFO></NAVI>, the investigator in Prontera, and come!!";
+		close;
+	}
+	if (isbegin_quest(3467) == 0) {
+		mes "[Lister]";
+		mes "Hello~";
+		next;
+		mes "[Lister]";
+		mes "I am Lista who is active in the Illusion Investigation Team.";
+		next;
+		mes "[Lister]";
+		mes "It's been a while since I came down to the deep sea with Master.";
+		next;
+		mes "[Lister]";
+		mes "I'm always working hard, but I don't think Master still approves of me.";
+		next;
+		mes "[Lister]";
+		mes "Just in time, the Illusion Investigation Team said they needed to investigate the deep sea here, so I quickly applied.";
+		next;
+		mes "[Lister]";
+		mes "I'm sure Master would be happy if we could get even a little bit more information about the deep sea here as part of the investigation team!!!";
+		next;
+		mes "[Lister]";
+		mes "I was anxiously waiting for a member to help me with the investigation, and it went really well~";
+		next;
+		mes "[Lister]";
+		mes "Would you like to participate in this deep sea investigation?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Lister]";
+			mes "I'm neglected like this... It's wrong to be acknowledged by Master...";
+			close;
+		}
+		mes "[Lister]";
+		mes "Oh, thank you!";
+		next;
+		mes "[Lister]";
+		mes "Go down to the lower level dungeon of the Abyssal Undersea Cave and defeat 100 monsters of any type.";
+		next;
+		mes "[Lister]";
+		mes "Then be careful!";
+		close2;
+		setquest 3467;
+		completequest 3467;
+		setquest 3468;
+		end;
+	}
+	switch( checkquest(3469,PLAYTIME) ) {
+	case -1:
+		break;
+	case 0:
+	case 1:
+		mes "[Lister]";
+		mes "Let's finish here for today.";
+		next;
+		mes "[Lister]";
+		mes "I should be able to get back to work tomorrow, could you talk to me again then??";
+		close;
+	case 2:
+		erasequest 3469;
+		break;
+	}
+	switch( checkquest(3468,HUNTING) ) {
+	case -1:
+		mes "[Lister]";
+		mes "Hello, would you like to do some research with me today??";
+		next;
+		mes "[Lister]";
+		mes "Just do what you did last time!";
+		next;
+		mes "[Lister]";
+		mes "If you kill 100 monsters of any type, would you like to participate?";
+		next;
+		if (select( "Participate", "Do not participate" ) == 2) {
+			mes "[Lister]";
+			mes "Today... I... incompetent... disciple...";
+			close;
+		}
+		mes "[Lister]";
+		mes "Good! Got it";
+		next;
+		mes "[Lister]";
+		mes "Go down to the lower level of the Abyssal Undersea Cave and kill 100 monsters of any type.";
+		next;
+		mes "[Lister]";
+		mes "Then be careful!";
+		close2;
+		setquest 3468;
+		end;
+	case 0:
+	case 1:
+		mes "[Lister]";
+		mes "Kill 100 monsters of any type.";
+		close;
+	case 2:
+		mes "[Lister]";
+		mes "How was it? Are the monsters on the lower levels really strong??";
+		next;
+		mes "[Lister]";
+		mes "You worked hard... Then I'll have to go down carefully.";
+		next;
+		mes "[Lister]";
+		mes "I'll do the rest, thank you so much!!";
+		close2;
+		erasequest 3468;
+		setquest 3469;
+		getexp 65000000,45000000;
+		end;
+	}
+	end;
+
+OnInit:
+	questinfo( QTYPE_QUEST, QMARK_YELLOW, "BaseLevel >= 180 && isbegin_quest(3470) == 2 && isbegin_quest(3467) == 0" );
+
+	questinfo( QTYPE_EVENT2, QMARK_YELLOW, "checkquest(3468,HUNTING) == 2" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(3467) == 2 && checkquest(3469,PLAYTIME) == -1 && checkquest(3468,HUNTING) == -1" );
+	questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(3469,PLAYTIME) == 2" );
+	end;
+}

+ 1 - 0
npc/re/scripts_athena.conf

@@ -219,6 +219,7 @@ npc: npc/re/quests/cooking_quest.txt
 //npc: npc/re/quests/cupet.txt
 npc: npc/re/quests/HelpMeShorty.txt
 npc: npc/re/quests/homun_s.txt
+npc: npc/re/quests/illusion_investigation.txt
 npc: npc/re/quests/juno_monster_society.txt
 npc: npc/re/quests/magic_books.txt
 npc: npc/re/quests/monstertamers.txt

+ 4 - 0
npc/re/warps/cities/prontera.txt

@@ -5,6 +5,7 @@
 //===== Changelogs: ==========================================
 //= 1.0 Prontera castle map changed in ep16.1 [Capuche]
 //= 1.1 Episode 17.2 Sage's Legacy update [crazyarashi]
+//= 1.2 Added warp to the Illusion Investigation room [Capuche]
 //============================================================
 
 prt_lib_q,9,25,0	script	lib_q_to_pprt	WARPNPC,1,1,{
@@ -169,3 +170,6 @@ prt_cas,254,347,0	warp	#ep172_prt_to_prt-6	1,1,prt_cas,96,18
 prt_cas,96,14,0	warp	#ep172_prt_to_prt-7	1,1,prt_cas,254,343
 prt_cas,174,342,0	warp	#ep172_prt_to_prt-8	1,1,prt_cas,322,336
 prt_cas,318,336,0	warp	#ep172_prt_to_prt-9	1,1,prt_cas,170,342
+
+prontera,50,228,0	warp	illusion123	2,2,prt_in,128,40
+prt_in,128,45,0	warp	illusion124	2,2,prontera,47,228

+ 4 - 4
src/char/char-server.vcxproj

@@ -111,7 +111,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -127,7 +127,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -146,7 +146,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -167,7 +167,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

文件差異過大導致無法顯示
+ 227 - 229
src/char/int_guild.cpp


+ 8 - 1
src/char/int_guild.hpp

@@ -8,6 +8,7 @@
 
 #include <common/cbasetypes.hpp>
 #include <common/database.hpp>
+#include <common/mmo.hpp>
 
 enum e_guild_action : uint32 {
 	GS_BASIC = 0x0001,
@@ -25,7 +26,7 @@ enum e_guild_action : uint32 {
 	GS_REMOVE = 0x8000,
 };
 
-struct guild;
+struct mmo_guild;
 struct guild_castle;
 
 struct s_guild_exp_db {
@@ -47,6 +48,12 @@ public:
 	t_exp get_nextexp(uint16 level);
 };
 
+class CharGuild {
+public:
+	struct mmo_guild guild;
+	unsigned short save_flag;
+};
+
 int inter_guild_parse_frommap(int fd);
 void inter_guild_sql_init(void);
 void inter_guild_sql_final(void);

+ 4 - 4
src/common/common-minicore.vcxproj

@@ -128,7 +128,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\zlib\include\;$(SolutionDir)3rdparty\libconfig\</AdditionalIncludeDirectories>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
@@ -143,7 +143,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;_DEBUG;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\zlib\include\;$(SolutionDir)3rdparty\libconfig\</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -161,7 +161,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\zlib\include\;$(SolutionDir)3rdparty\libconfig\</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -181,7 +181,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\zlib\include\;$(SolutionDir)3rdparty\libconfig\</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 4 - 4
src/common/common.vcxproj

@@ -161,7 +161,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Windows</SubSystem>
@@ -179,7 +179,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -200,7 +200,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -223,7 +223,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 3 - 3
src/common/core.cpp

@@ -28,12 +28,12 @@
 #include "strlib.hpp"
 
 #ifndef DEPRECATED_COMPILER_SUPPORT
-	#if defined( _MSC_VER ) && _MSC_VER < 1910
+	#if defined( _MSC_VER ) && _MSC_VER < 1914
 		#error "Visual Studio versions older than Visual Studio 2017 are not officially supported anymore"
 	#elif defined( __clang__ ) && __clang_major__ < 6
 		#error "clang versions older than clang 6.0 are not officially supported anymore"
-	#elif !defined( __clang__ ) && defined( __GNUC__ ) && __GNUC__ < 5
-		#error "GCC versions older than GCC 5 are not officially supported anymore"
+	#elif !defined( __clang__ ) && defined( __GNUC__ ) && __GNUC__ < 6
+		#error "GCC versions older than GCC 6 are not officially supported anymore"
 	#endif
 #endif
 

+ 6 - 0
src/common/database.cpp

@@ -196,6 +196,12 @@ void YamlDatabase::parseImports( const ryml::Tree& rootNode ){
 
 #ifdef RENEWAL
 					std::string compiledMode = "Renewal";
+
+					// RENEWAL mode with RENEWAL_ASPD off, load pre-re ASPD
+#ifndef RENEWAL_ASPD
+					if (importFile.find("job_aspd.yml") != std::string::npos)
+						compiledMode = "Prerenewal";
+#endif
 #else
 					std::string compiledMode = "Prerenewal";
 #endif

+ 2 - 0
src/common/mapindex.hpp

@@ -51,6 +51,8 @@
 #define MAP_ECLAGE "eclage"
 #define MAP_ECLAGE_IN "ecl_in01"
 #define MAP_LASAGNA "lasagna"
+#define MAP_GLASTHEIM "glast_01"
+#define MAP_THANATOS "hu_fild01"
 
 const char* mapindex_getmapname(const char* string, char* output);
 const char* mapindex_getmapname_ext(const char* string, char* output);

+ 1 - 8
src/common/mmo.hpp

@@ -743,7 +743,7 @@ struct guild_skill {
 };
 
 struct Channel;
-struct guild {
+struct mmo_guild {
 	int guild_id;
 	short guild_lv, connect_member, max_member, average_lv;
 	t_exp exp;
@@ -758,14 +758,7 @@ struct guild {
 	struct guild_alliance alliance[MAX_GUILDALLIANCE];
 	struct guild_expulsion expulsion[MAX_GUILDEXPULSION];
 	struct guild_skill skill[MAX_GUILDSKILL];
-	struct Channel *channel;
-	int instance_id;
 	time_t last_leader_change;
-
-	/* Used by char-server to save events for guilds */
-	unsigned short save_flag;
-
-	int32 chargeshout_flag_id;
 };
 
 enum e_woe_type{

+ 4 - 4
src/login/login-server.vcxproj

@@ -110,7 +110,7 @@
       <PreprocessorDefinitions>FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;WIN32;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -127,7 +127,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;WIN32;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -146,7 +146,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -167,7 +167,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;WIN32;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 45 - 55
src/map/atcommand.cpp

@@ -809,7 +809,7 @@ ACMD_FUNC(who) {
 				}
 				default: {
 					struct party_data *p = party_search(pl_sd->status.party_id);
-					struct guild *g = pl_sd->guild;
+					auto &g = pl_sd->guild;
 
 					StringBuf_Printf(&buf, msg_txt(sd,343), pl_sd->status.name); // "Name: %s "
 					if (pc_get_group_id(pl_sd) > 0) // Player title, if exists
@@ -817,7 +817,7 @@ ACMD_FUNC(who) {
 					if (p != NULL)
 						StringBuf_Printf(&buf, msg_txt(sd,345), p->party.name); // " | Party: '%s'"
 					if (g != NULL)
-						StringBuf_Printf(&buf, msg_txt(sd,346), g->name); // " | Guild: '%s'"
+						StringBuf_Printf(&buf, msg_txt(sd,346), g->guild.name); // " | Guild: '%s'"
 					break;
 				}
 			}
@@ -861,7 +861,6 @@ ACMD_FUNC(whogm)
 	int level;
 	char match_text[CHAT_SIZE_MAX];
 	char player_name[NAME_LENGTH];
-	struct guild *g;
 	struct party_data *p;
 
 	nullpo_retr(-1, sd);
@@ -914,10 +913,10 @@ ACMD_FUNC(whogm)
 		clif_displaymessage(fd, atcmd_output);
 
 		p = party_search(pl_sd->status.party_id);
-		g = pl_sd->guild;
+		auto &g = pl_sd->guild;
 
 		sprintf(atcmd_output,msg_txt(sd,916),	// Party: '%s' | Guild: '%s'
-			p?p->party.name:msg_txt(sd,917), g?g->name:msg_txt(sd,917));	// None.
+			p?p->party.name:msg_txt(sd,917), g?g->guild.name:msg_txt(sd,917));	// None.
 
 		clif_displaymessage(fd, atcmd_output);
 		count++;
@@ -3050,7 +3049,6 @@ ACMD_FUNC(trait_all) {
 ACMD_FUNC(guildlevelup) {
 	int level = 0;
 	short added_level;
-	struct guild *guild_info;
 	nullpo_retr(-1, sd);
 
 	if (!message || !*message || sscanf(message, "%11d", &level) < 1 || level == 0) {
@@ -3058,7 +3056,9 @@ ACMD_FUNC(guildlevelup) {
 		return -1;
 	}
 
-	if (sd->status.guild_id <= 0 || (guild_info = sd->guild) == NULL) {
+	auto &guild_info = sd->guild;
+
+	if (sd->status.guild_id <= 0 || guild_info == nullptr) {
 		clif_displaymessage(fd, msg_txt(sd,43)); // You're not in a guild.
 		return -1;
 	}
@@ -3068,13 +3068,13 @@ ACMD_FUNC(guildlevelup) {
 	//}
 
 	added_level = (short)level;
-	if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild_lv))) // fix positive overflow
-		added_level = (short)MAX_GUILDLEVEL - guild_info->guild_lv;
-	else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild_lv))) // fix negative overflow
-		added_level = 1 - guild_info->guild_lv;
+	if (level > 0 && (level > MAX_GUILDLEVEL || added_level > ((short)MAX_GUILDLEVEL - guild_info->guild.guild_lv))) // fix positive overflow
+		added_level = (short)MAX_GUILDLEVEL - guild_info->guild.guild_lv;
+	else if (level < 0 && (level < -MAX_GUILDLEVEL || added_level < (1 - guild_info->guild.guild_lv))) // fix negative overflow
+		added_level = 1 - guild_info->guild.guild_lv;
 
 	if (added_level != 0) {
-		intif_guild_change_basicinfo(guild_info->guild_id, GBI_GUILDLV, &added_level, sizeof(added_level));
+		intif_guild_change_basicinfo(guild_info->guild.guild_id, GBI_GUILDLV, &added_level, sizeof(added_level));
 		clif_displaymessage(fd, msg_txt(sd,179)); // Guild level changed.
 	} else {
 		clif_displaymessage(fd, msg_txt(sd,45)); // Guild level change failed.
@@ -3856,12 +3856,10 @@ ACMD_FUNC(breakguild)
 	nullpo_retr(-1, sd);
 
 	if (sd->status.guild_id) { // Check if the player has a guild
-		struct guild *g;
-		g = sd->guild; // Search the guild
-		if (g) { // Check if guild was found
+		if (sd->guild) { // Check if guild was found
 			if (sd->state.gmaster_flag) { // Check if player is guild master
 				int ret = 0;
-				ret = guild_break(sd, g->name); // Break guild
+				ret = guild_break(sd, sd->guild->guild.name); // Break guild
 				if (ret) { // Check if anything went wrong
 					return 0; // Guild was broken
 				} else {
@@ -4083,7 +4081,6 @@ ACMD_FUNC(guildrecall)
 	struct s_mapiterator* iter;
 	int count;
 	char guild_name[NAME_LENGTH];
-	struct guild *g;
 	nullpo_retr(-1, sd);
 
 	memset(guild_name, '\0', sizeof(guild_name));
@@ -4099,9 +4096,8 @@ ACMD_FUNC(guildrecall)
 		return -1;
 	}
 
-	if ((g = guild_searchname(guild_name)) == NULL && // name first to avoid error when name begin with a number
-	    (g = guild_search(atoi(message))) == NULL)
-	{
+	auto g = guild_searchnameid(guild_name);
+	if (!g) {
 		clif_displaymessage(fd, msg_txt(sd,94)); // Incorrect name/ID, or no one from the guild is online.
 		return -1;
 	}
@@ -4111,7 +4107,7 @@ ACMD_FUNC(guildrecall)
 	iter = mapit_getallusers();
 	for( pl_sd = (TBL_PC*)mapit_first(iter); mapit_exists(iter); pl_sd = (TBL_PC*)mapit_next(iter) )
 	{
-		if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.guild_id == g->guild_id)
+		if (sd->status.account_id != pl_sd->status.account_id && pl_sd->status.guild_id == g->guild.guild_id)
 		{
 			if (pc_get_group_level(pl_sd) > pc_get_group_level(sd) || (pl_sd->bl.m == sd->bl.m && pl_sd->bl.x == sd->bl.x && pl_sd->bl.y == sd->bl.y))
 				continue; // Skip GMs greater than you...             or chars already on the cell
@@ -4126,7 +4122,7 @@ ACMD_FUNC(guildrecall)
 	}
 	mapit_free(iter);
 
-	sprintf(atcmd_output, msg_txt(sd,93), g->name); // All online characters of the %s guild have been recalled to your position.
+	sprintf(atcmd_output, msg_txt(sd,93), g->guild.name); // All online characters of the %s guild have been recalled to your position.
 	clif_displaymessage(fd, atcmd_output);
 	if (count) {
 		sprintf(atcmd_output, msg_txt(sd,1033), count); // Because you are not authorized to warp from some maps, %d player(s) have not been recalled.
@@ -4791,7 +4787,6 @@ ACMD_FUNC(mount_peco)
 ACMD_FUNC(guildspy)
 {
 	char guild_name[NAME_LENGTH];
-	struct guild *g;
 	nullpo_retr(-1, sd);
 
 	memset(guild_name, '\0', sizeof(guild_name));
@@ -4807,22 +4802,22 @@ ACMD_FUNC(guildspy)
 		return -1;
 	}
 
-	if ((g = guild_searchname(guild_name)) != NULL || // name first to avoid error when name begin with a number
-	    (g = guild_search(atoi(message))) != NULL) {
-		if (sd->guildspy == g->guild_id) {
-			sd->guildspy = 0;
-			sprintf(atcmd_output, msg_txt(sd,103), g->name); // No longer spying on the %s guild.
-			clif_displaymessage(fd, atcmd_output);
-		} else {
-			sd->guildspy = g->guild_id;
-			sprintf(atcmd_output, msg_txt(sd,104), g->name); // Spying on the %s guild.
-			clif_displaymessage(fd, atcmd_output);
-		}
-	} else {
+	auto g = guild_searchnameid(guild_name);
+	if (!g) {
 		clif_displaymessage(fd, msg_txt(sd,94)); // Incorrect name/ID, or no one from the specified guild is online.
 		return -1;
 	}
 
+	if (sd->guildspy == g->guild.guild_id) {
+		sd->guildspy = 0;
+		sprintf(atcmd_output, msg_txt(sd,103), g->guild.name); // No longer spying on the %s guild.
+		clif_displaymessage(fd, atcmd_output);
+	} else {
+		sd->guildspy = g->guild.guild_id;
+		sprintf(atcmd_output, msg_txt(sd,104), g->guild.name); // Spying on the %s guild.
+		clif_displaymessage(fd, atcmd_output);
+	}
+
 	return 0;
 }
 
@@ -5506,8 +5501,6 @@ ACMD_FUNC(disguiseguild)
 {
 	int id = 0, i;
 	char monster[NAME_LENGTH], guild[NAME_LENGTH];
-	
-	struct guild *g;
 
 	memset(monster, '\0', sizeof(monster));
 	memset(guild, '\0', sizeof(guild));
@@ -5533,14 +5526,15 @@ ACMD_FUNC(disguiseguild)
 		return -1;
 	}
 
-	if( (g = guild_searchname(guild)) == NULL && (g = guild_search(atoi(guild))) == NULL ) {
+	auto g = guild_searchnameid(guild);
+	if (!g) {
 		clif_displaymessage(fd, msg_txt(sd,94)); // Incorrect name/ID, or no one from the guild is online.
 		return -1;
 	}
 
-	for( i = 0; i < g->max_member; i++ ){
+	for( i = 0; i < g->guild.max_member; i++ ){
 		map_session_data *pl_sd;
-		if( (pl_sd = g->member[i].sd) && !pc_isriding(pl_sd) )
+		if( (pl_sd = g->guild.member[i].sd) && !pc_isriding(pl_sd) )
 			pc_disguise(pl_sd, id);
 	}
 
@@ -5592,7 +5586,6 @@ ACMD_FUNC(undisguiseall)
 ACMD_FUNC(undisguiseguild)
 {
 	char guild_name[NAME_LENGTH];
-	struct guild *g;
 	int i;
 	nullpo_retr(-1, sd);
 
@@ -5603,14 +5596,15 @@ ACMD_FUNC(undisguiseguild)
 		return -1;
 	}
 
-	if( (g = guild_searchname(guild_name)) == NULL && (g = guild_search(atoi(message))) == NULL ) {
+	auto g = guild_searchnameid(guild_name);
+	if (!g) {
 		clif_displaymessage(fd, msg_txt(sd,94)); // Incorrect name/ID, or no one from the guild is online.
 		return -1;
 	}
 
-	for(i = 0; i < g->max_member; i++){
+	for(i = 0; i < g->guild.max_member; i++){
 		map_session_data *pl_sd;
-		if( (pl_sd = g->member[i].sd) && pl_sd->disguise )
+		if( (pl_sd = g->guild.member[i].sd) && pl_sd->disguise )
 			pc_disguise(pl_sd, 0);
 	}
 
@@ -6028,13 +6022,10 @@ ACMD_FUNC(clearstorage)
 ACMD_FUNC(cleargstorage)
 {
 	int i, j;
-	struct guild *g;
 	struct s_storage *gstorage;
 	nullpo_retr(-1, sd);
 
-	g = sd->guild;
-
-	if (g == NULL) {
+	if (!sd->guild) {
 		clif_displaymessage(fd, msg_txt(sd,43)); // You're not in a guild.
 		return -1;
 	}
@@ -6487,13 +6478,12 @@ ACMD_FUNC(autotrade) {
  *------------------------------------------*/
 ACMD_FUNC(changegm)
 {
-	struct guild *g;
 	map_session_data *pl_sd;
 	nullpo_retr(-1, sd);
 
 	memset(atcmd_player_name, '\0', sizeof(atcmd_player_name));
 
-	if (sd->status.guild_id == 0 || (g = sd->guild) == NULL || strcmp(g->master,sd->status.name)) {
+	if (sd->status.guild_id == 0 || sd->guild == NULL || strcmp(sd->guild->guild.master,sd->status.name)) {
 		clif_displaymessage(fd, msg_txt(sd,1181)); // You need to be a Guild Master to use this command.
 		return -1;
 	}
@@ -6522,7 +6512,7 @@ ACMD_FUNC(changegm)
 		return -1;
 	}
 
-	if( battle_config.guild_leaderchange_delay && DIFF_TICK(time(NULL),sd->guild->last_leader_change) < battle_config.guild_leaderchange_delay ){
+	if( battle_config.guild_leaderchange_delay && DIFF_TICK(time(NULL),sd->guild->guild.last_leader_change) < battle_config.guild_leaderchange_delay ){
 #if PACKETVER >= 20151001
 		clif_msg(sd, GUILD_MASTER_DELAY);
 #else
@@ -8588,7 +8578,6 @@ ACMD_FUNC(sizeguild)
 	int size = SZ_SMALL, i;
 	char guild[NAME_LENGTH];
 	map_session_data *pl_sd;
-	struct guild *g;
 	nullpo_retr(-1, sd);
 
 	memset(guild, '\0', sizeof(guild));
@@ -8598,15 +8587,16 @@ ACMD_FUNC(sizeguild)
 		return -1;
 	}
 
-	if( (g = guild_searchname(guild)) == NULL && (g = guild_search(atoi(guild))) == NULL ) {
+	auto g = guild_searchnameid(guild);
+	if (!g) {
 		clif_displaymessage(fd, msg_txt(sd,94)); // Incorrect name/ID, or no one from the guild is online.
 		return -1;
 	}
 
 	size = cap_value(size,SZ_SMALL,SZ_BIG);
 
-	for( i = 0; i < g->max_member; i++ ) {
-		if( (pl_sd = g->member[i].sd) && pl_sd->state.size != size ) {
+	for( i = 0; i < g->guild.max_member; i++ ) {
+		if( (pl_sd = g->guild.member[i].sd) && pl_sd->state.size != size ) {
 			if( pl_sd->state.size ) {
 				pl_sd->state.size = SZ_SMALL;
 				pc_setpos(pl_sd, pl_sd->mapindex, pl_sd->bl.x, pl_sd->bl.y, CLR_TELEPORT);

+ 4 - 4
src/map/battle.cpp

@@ -2044,16 +2044,16 @@ bool battle_can_hit_gvg_target(struct block_list *src,struct block_list *bl,uint
 		if ((status_bl_has_mode(bl,MD_SKILLIMMUNE) || (class_ == MOBID_EMPERIUM && !skill_get_inf2(skill_id, INF2_TARGETEMPERIUM))) && flag&BF_SKILL) //Skill immunity.
 			return false;
 		if( src->type != BL_MOB || mob_is_clone( ((struct mob_data*)src)->mob_id ) ){
-			struct guild *g = src->type == BL_PC ? ((TBL_PC *)src)->guild : guild_search(status_get_guild_id(src));
+			auto g = src->type == BL_PC ? ((TBL_PC *)src)->guild : guild_search(status_get_guild_id(src));
 
-			if (class_ == MOBID_EMPERIUM && (!g || guild_checkskill(g,GD_APPROVAL) <= 0 ))
+			if (class_ == MOBID_EMPERIUM && (!g || guild_checkskill(g->guild, GD_APPROVAL) <= 0 ))
 				return false;
 
 			if (g != nullptr) {
-				if (battle_config.guild_max_castles && guild_checkcastles(g)>=battle_config.guild_max_castles)
+				if (battle_config.guild_max_castles && guild_checkcastles(g->guild)>=battle_config.guild_max_castles)
 					return false; // [MouseJstr]
 
-				if (md->special_state.ai == AI_GUILD && g->guild_id == md->master_id)
+				if (md->special_state.ai == AI_GUILD && g->guild.guild_id == md->master_id)
 					return false;
 			}
 		}

+ 4 - 4
src/map/battleground.cpp

@@ -1097,7 +1097,7 @@ void bg_queue_join_guild(const char *name, map_session_data *sd)
 		return; // Someone has bypassed the client check for being in a guild
 	}
 	
-	if (strcmp(sd->status.name, sd->guild->master) != 0) {
+	if (strcmp(sd->status.name, sd->guild->guild.master) != 0) {
 		clif_bg_queue_apply_result(BG_APPLY_PARTYGUILD_LEADER, name, sd);
 		return; // Not the guild leader
 	}
@@ -1110,16 +1110,16 @@ void bg_queue_join_guild(const char *name, map_session_data *sd)
 			return;
 		}
 
-		struct guild* g = sd->guild;
+		auto &g = sd->guild;
 
-		if (g->connect_member > bg->max_players) {
+		if (g->guild.connect_member > bg->max_players) {
 			clif_bg_queue_apply_result(BG_APPLY_PLAYER_COUNT, name, sd);
 			return; // Too many guild members online
 		}
 
 		std::vector<map_session_data *> list;
 
-		for (const auto &it : g->member) {
+		for (const auto &it : g->guild.member) {
 			if (list.size() == bg->max_players)
 				break;
 

+ 19 - 19
src/map/channel.cpp

@@ -171,7 +171,7 @@ int channel_delete(struct Channel *channel, bool force) {
 		aFree(channel);
 		break;
 	case CHAN_TYPE_ALLY: {
-		struct guild *g = guild_search(channel->gid);
+		auto g = guild_search(channel->gid);
 		if(g) g->channel = NULL;
 		aFree(channel);
 		break;
@@ -277,19 +277,20 @@ int channel_mjoin(map_session_data *sd) {
  *   0: Success
  *  -1: Invalid guild or no channel for guild
  */
-int channel_ajoin(struct guild *g){
+int channel_ajoin(MapGuild &g) {
 	int i, j;
 	map_session_data *pl_sd;
 
-	if(!g || !g->channel) return -1;
+	if (!g.channel)
+		return -1;
 	for (i = 0; i < MAX_GUILDALLIANCE; i++){
-		struct guild *ag; //allied guld
-		struct guild_alliance *ga = &g->alliance[i]; //guild alliance
+		std::shared_ptr<MapGuild> ag; //allied guild
+		struct guild_alliance *ga = &g.guild.alliance[i]; //guild alliance
 		if(ga->guild_id && (ga->opposition==0) && (ag=guild_search(ga->guild_id))){
-			for (j = 0; j < ag->max_member; j++){ //load all guildmember
-				pl_sd = ag->member[j].sd;
+			for (j = 0; j < ag->guild.max_member; j++){ //load all guildmember
+				pl_sd = ag->guild.member[j].sd;
 				if(channel_haspc(ag->channel,pl_sd)==1)  //only if they are in their own guildchan
-					channel_join(g->channel,pl_sd);
+					channel_join(g.channel,pl_sd);
 			}
 		}
 	}
@@ -308,17 +309,16 @@ int channel_ajoin(struct guild *g){
  */
 int channel_gjoin(map_session_data *sd, int flag){
 	struct Channel *channel;
-	struct guild *g;
 
 	if(!sd || sd->state.autotrade) return -1;
-	g = sd->guild;
+	auto &g = sd->guild;
 	if(!g) return -2;
 
 	channel = g->channel;
 	if(!channel){
-		channel = channel_create_simple(NULL,NULL,CHAN_TYPE_ALLY,g->guild_id);
+		channel = channel_create_simple(NULL,NULL,CHAN_TYPE_ALLY,g->guild.guild_id);
 		g->channel = channel;
-		channel_ajoin(g);
+		channel_ajoin(*g);
 	}
 	if(flag&1) {
 		channel_join(channel,sd);	//join our guild chat
@@ -326,8 +326,8 @@ int channel_gjoin(map_session_data *sd, int flag){
 	if(flag&2){
 		int i;
 		for (i = 0; i < MAX_GUILDALLIANCE; i++){
-			struct guild *ag; //allied guld
-			struct guild_alliance *ga = &g->alliance[i]; //guild alliance
+			std::shared_ptr<MapGuild> ag; //allied guild
+			struct guild_alliance *ga = &g->guild.alliance[i]; //guild alliance
 			if(ga->guild_id && (ga->opposition==0) && (ag=guild_search(ga->guild_id)) ) //only join allies
 				channel_join(ag->channel,sd);
 		}
@@ -401,14 +401,14 @@ int channel_pcquit(map_session_data *sd, int type){
 
 	// Leave all chat channels.
 	if(type&(1|2) && channel_config.ally_tmpl.name[0] && sd->guild){ //quit guild and ally chan
-		struct guild *g = sd->guild;
+		auto &g = sd->guild;
 		if(type&1 && channel_haspc(g->channel,sd)==1){
 			channel_clean(g->channel,sd,0); //leave guild chan
 		}
 		if(type&2){
 			for (i = 0; i < MAX_GUILDALLIANCE; i++) { //leave all alliance chan
-				struct guild *ag; //allied guild
-				if( g->alliance[i].guild_id && (ag = guild_search(g->alliance[i].guild_id) ) ) {
+				std::shared_ptr<MapGuild> ag; //allied guild
+				if( g->guild.alliance[i].guild_id && (ag = guild_search(g->guild.alliance[i].guild_id) ) ) {
 					if(channel_haspc(ag->channel,sd) == 1)
 						channel_clean(ag->channel,sd,0);
 					break;
@@ -519,7 +519,7 @@ struct Channel* channel_name2channel(char *chname, map_session_data *sd, int fla
 	}
 	else if(sd && (strcmpi(chname + 1,channel_config.ally_tmpl.name) == 0) && sd->guild){
 		if(flag&1 && !sd->guild->channel)
-			sd->guild->channel = channel_create_simple(NULL,NULL,CHAN_TYPE_ALLY,sd->guild->guild_id);
+			sd->guild->channel = channel_create_simple(NULL,NULL,CHAN_TYPE_ALLY,sd->guild->guild.guild_id);
 		if(flag&2 && channel_pc_haschan(sd,mapdata->channel) < 1)
 			channel_gjoin(sd,3);
 		return sd->guild->channel;
@@ -630,7 +630,7 @@ int channel_display_list(map_session_data *sd, const char *options){
 			clif_displaymessage(sd->fd, output);
 		}
 		if( channel_config.ally_tmpl.name[0] && sd->status.guild_id ) {
-			struct guild *g = sd->guild;
+			auto &g = sd->guild;
 			if (g && g->channel) {
 				sprintf(output, msg_txt(sd,1409), g->channel->name, db_size(((struct Channel *)g->channel)->users));// - #%s (%d users)
 				clif_displaymessage(sd->fd, output);

+ 2 - 2
src/map/channel.hpp

@@ -10,7 +10,7 @@
 //namespace rA {
 
 class map_session_data;
-struct guild;
+struct mmo_guild;
 struct DBMap;
 
 #define CHAN_NAME_LENGTH 20
@@ -95,7 +95,7 @@ int channel_delete(struct Channel *channel, bool force);
 int channel_join(struct Channel *channel, map_session_data *sd);
 int channel_mjoin(map_session_data *sd);
 int channel_gjoin(map_session_data *sd, int flag);
-int channel_ajoin(struct guild *g);
+int channel_ajoin(struct mmo_guild &g);
 int channel_clean(struct Channel *channel, map_session_data *sd, int flag);
 int channel_pcquit(map_session_data *sd, int type);
 

+ 119 - 136
src/map/clif.cpp

@@ -488,7 +488,6 @@ int clif_send(const void* buf, int len, struct block_list* bl, enum send_target
 	int i;
 	map_session_data *sd, *tsd;
 	struct party_data *p = NULL;
-	struct guild *g = NULL;
 	std::shared_ptr<s_battleground_data> bg;
 	int x0 = 0, x1 = 0, y0 = 0, y1 = 0, fd;
 	struct s_mapiterator* iter;
@@ -647,48 +646,47 @@ int clif_send(const void* buf, int len, struct block_list* bl, enum send_target
 	case GUILD_SAMEMAP_WOS:
 	case GUILD:
 	case GUILD_WOS:
-	case GUILD_NOBG:
-		if (sd && sd->status.guild_id)
-			g = sd->guild;
+	case GUILD_NOBG: {
+		if (!sd || !sd->status.guild_id || !sd->guild)
+			break;
 
-		if (g) {
-			for(i = 0; i < g->max_member; i++) {
-				if( (sd = g->member[i].sd) != nullptr ){
-					if( !session_isActive( fd = sd->fd ) )
-						continue;
+		const auto &g = sd->guild->guild;
+		for(i = 0; i < g.max_member; i++) {
+			if( (sd = g.member[i].sd) != nullptr ){
+				if( !session_isActive( fd = sd->fd ) )
+					continue;
 
-					if( type == GUILD_NOBG && sd->bg_id )
-						continue;
+				if( type == GUILD_NOBG && sd->bg_id )
+					continue;
 
-					if( sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS) )
-						continue;
+				if( sd->bl.id == bl->id && (type == GUILD_WOS || type == GUILD_SAMEMAP_WOS || type == GUILD_AREA_WOS) )
+					continue;
 
-					if( type != GUILD && type != GUILD_NOBG && type != GUILD_WOS && sd->bl.m != bl->m )
-						continue;
+				if( type != GUILD && type != GUILD_NOBG && type != GUILD_WOS && sd->bl.m != bl->m )
+					continue;
 
-					if( (type == GUILD_AREA || type == GUILD_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1) )
-						continue;
+				if( (type == GUILD_AREA || type == GUILD_AREA_WOS) && (sd->bl.x < x0 || sd->bl.y < y0 || sd->bl.x > x1 || sd->bl.y > y1) )
+					continue;
 
-					WFIFOHEAD(fd,len);
-					memcpy(WFIFOP(fd,0), buf, len);
-					WFIFOSET(fd,len);
-				}
+				WFIFOHEAD(fd,len);
+				memcpy(WFIFOP(fd,0), buf, len);
+				WFIFOSET(fd,len);
 			}
-			if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
-				break;
+		}
+		if (!enable_spy) //Skip unnecessary parsing. [Skotlex]
+			break;
 
-			iter = mapit_getallusers();
-			while( ( tsd = (map_session_data*)mapit_next( iter ) ) != nullptr ){
-				if( tsd->guildspy == g->guild_id && session_isActive( fd = tsd->fd ) ){
-					WFIFOHEAD( fd, len );
-					memcpy( WFIFOP( fd, 0 ), buf, len );
-					WFIFOSET( fd, len );
-				}
+		iter = mapit_getallusers();
+		while( ( tsd = (map_session_data*)mapit_next( iter ) ) != nullptr ){
+			if( tsd->guildspy == g.guild_id && session_isActive( fd = tsd->fd ) ){
+				WFIFOHEAD( fd, len );
+				memcpy( WFIFOP( fd, 0 ), buf, len );
+				WFIFOSET( fd, len );
 			}
-			mapit_free(iter);
 		}
+		mapit_free(iter);
 		break;
-
+	}
 	case BG_AREA:
 	case BG_AREA_WOS:
 		x0 = bl->x - AREA_SIZE;
@@ -3311,12 +3309,12 @@ void clif_guild_xy_remove(map_session_data *sd)
  *------------------------------------------*/
 void clif_guild_castle_list(map_session_data& sd){
 #if PACKETVER_MAIN_NUM >= 20190731 || PACKETVER_RE_NUM >= 20190717 || PACKETVER_ZERO_NUM >= 20190814
-	struct guild* g = sd.guild;
+	auto &g = sd.guild;
 
 	if (g == nullptr)
 		return;
 
-	int castle_count = guild_checkcastles(g);
+	int castle_count = guild_checkcastles(g->guild);
 
 	if (castle_count > 0) {
 		struct PACKET_ZC_GUILD_AGIT_INFO* p = (struct PACKET_ZC_GUILD_AGIT_INFO*)packet_buffer;
@@ -3326,7 +3324,7 @@ void clif_guild_castle_list(map_session_data& sd){
 
 		int i = 0;
 		for (const auto& gc : castle_db) {
-			if (gc.second->guild_id == g->guild_id && gc.second->client_id) {
+			if (gc.second->guild_id == g->guild.guild_id && gc.second->client_id) {
 				p->castle_list[i] = static_cast<int8>( gc.second->client_id );
 				p->packetLength += static_cast<int16>( sizeof( p->castle_list[0] ) );
 				++i;
@@ -3378,7 +3376,7 @@ void clif_guild_castle_teleport_res(map_session_data& sd, enum e_siege_teleport_
 void clif_parse_guild_castle_info_request(int fd, map_session_data* sd){
 #if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515
 	const struct PACKET_CZ_REQ_AGIT_INVESTMENT* p = (struct PACKET_CZ_REQ_AGIT_INVESTMENT*)RFIFOP(fd, 0);
-	struct guild* g = sd->guild;
+	auto &g = sd->guild;
 
 	if (g == nullptr)
 		return;
@@ -3387,7 +3385,7 @@ void clif_parse_guild_castle_info_request(int fd, map_session_data* sd){
 
 	if (gc == nullptr)
 		return;
-	if (gc->guild_id != g->guild_id)
+	if (gc->guild_id != g->guild.guild_id)
 		return;
 
 	clif_guild_castleinfo(*sd, gc);
@@ -3400,7 +3398,7 @@ void clif_parse_guild_castle_info_request(int fd, map_session_data* sd){
 void clif_parse_guild_castle_teleport_request(int fd, map_session_data* sd){
 #if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190522 || PACKETVER_ZERO_NUM >= 20190515
 	const struct PACKET_CZ_REQ_MOVE_GUILD_AGIT* p = (struct PACKET_CZ_REQ_MOVE_GUILD_AGIT*)RFIFOP(fd, 0);
-	struct guild* g = sd->guild;
+	auto &g = sd->guild;
 
 	if (g == nullptr)
 		return;
@@ -3411,7 +3409,7 @@ void clif_parse_guild_castle_teleport_request(int fd, map_session_data* sd){
 		return;
 	if (!gc->warp_enabled)
 		return;
-	if (gc->guild_id != g->guild_id)
+	if (gc->guild_id != g->guild.guild_id)
 		return;
 
 	if (map_getmapflag(sd->bl.m, MF_GVG_CASTLE) 
@@ -8780,8 +8778,8 @@ void clif_guild_belonginfo( map_session_data& sd ){
 		return;
 	}
 
-	struct guild& guild = *sd.guild;
-	int position = guild_getposition( &sd );
+	const auto &guild = sd.guild->guild;
+	int position = guild_getposition(sd);
 
 	if( position < 0 ){
 		return;
@@ -8810,19 +8808,17 @@ void clif_guild_belonginfo( map_session_data& sd ){
 /// status:
 ///     0 = offline
 ///     1 = online
-void clif_guild_memberlogin_notice(struct guild *g,int idx,int flag)
+void clif_guild_memberlogin_notice(const struct mmo_guild &g,int idx,int flag)
 {
 	unsigned char buf[64];
 	map_session_data* sd;
 
-	nullpo_retv(g);
-
 	WBUFW(buf, 0)=0x1f2;
-	WBUFL(buf, 2)=g->member[idx].account_id;
-	WBUFL(buf, 6)=g->member[idx].char_id;
+	WBUFL(buf, 2)=g.member[idx].account_id;
+	WBUFL(buf, 6)=g.member[idx].char_id;
 	WBUFL(buf,10)=flag;
 
-	if( ( sd = g->member[idx].sd ) != NULL )
+	if( ( sd = g.member[idx].sd ) != NULL )
 	{
 		WBUFW(buf,14) = sd->status.sex;
 		WBUFW(buf,16) = sd->status.hair;
@@ -8849,7 +8845,6 @@ void clif_guild_memberlogin_notice(struct guild *g,int idx,int flag)
 // to economize traffic. [LuzZza]
 void clif_guild_send_onlineinfo(map_session_data *sd)
 {
-	struct guild *g;
 	unsigned char buf[14*128];
 	int i, count=0, p_len;
 
@@ -8857,18 +8852,19 @@ void clif_guild_send_onlineinfo(map_session_data *sd)
 
 	p_len = packet_len(0x16d);
 
-	if(!(g = sd->guild))
+	auto &g = sd->guild;
+	if (!g)
 		return;
 
-	for(i=0; i<g->max_member; i++) {
+	for(i=0; i<g->guild.max_member; i++) {
 
-		if(g->member[i].account_id > 0 &&
-			g->member[i].account_id != sd->status.account_id) {
+		if(g->guild.member[i].account_id > 0 &&
+			g->guild.member[i].account_id != sd->status.account_id) {
 
 			WBUFW(buf,count*p_len) = 0x16d;
-			WBUFL(buf,count*p_len+2) = g->member[i].account_id;
-			WBUFL(buf,count*p_len+6) = g->member[i].char_id;
-			WBUFL(buf,count*p_len+10) = g->member[i].online;
+			WBUFL(buf,count*p_len+2) = g->guild.member[i].account_id;
+			WBUFL(buf,count*p_len+6) = g->guild.member[i].char_id;
+			WBUFL(buf,count*p_len+10) = g->guild.member[i].online;
 			count++;
 		}
 	}
@@ -8910,7 +8906,7 @@ void clif_guild_basicinfo( map_session_data& sd ){
 		return;
 	}
 
-	struct guild& guild = *sd.guild;
+	const auto &guild = sd.guild->guild;
 	struct PACKET_ZC_GUILD_INFO p = {};
 
 	p.PacketType = HEADER_ZC_GUILD_INFO;
@@ -8926,7 +8922,7 @@ void clif_guild_basicinfo( map_session_data& sd ){
 	p.virtue = 0; // Virtue: (down) Wicked [-100,100] Righteous (up)
 	p.emblemVersion = guild.emblem_id;
 	safestrncpy( p.guildname, guild.name, sizeof( p.guildname ) );
-	safestrncpy( p.manageLand, msg_txt( &sd, 300 + guild_checkcastles( &guild ) ), sizeof( p.manageLand ) );
+	safestrncpy( p.manageLand, msg_txt( &sd, 300 + guild_checkcastles( guild ) ), sizeof( p.manageLand ) );
 	p.zeny = 0;
 #if PACKETVER >= 20200902
 	p.masterGID = guild.member[0].char_id; // leader
@@ -8946,17 +8942,17 @@ void clif_guild_basicinfo( map_session_data& sd ){
 void clif_guild_allianceinfo(map_session_data *sd)
 {
 	int fd,i,c;
-	struct guild *g;
 
 	nullpo_retv(sd);
-	if( (g = sd->guild) == NULL )
+	auto &g = sd->guild;
+	if (!g)
 		return;
 
 	fd = sd->fd;
 	WFIFOHEAD(fd, MAX_GUILDALLIANCE * 32 + 4);
 	WFIFOW(fd, 0)=0x14c;
 	for(i=c=0;i<MAX_GUILDALLIANCE;i++){
-		struct guild_alliance *a=&g->alliance[i];
+		struct guild_alliance *a=&g->guild.alliance[i];
 		if(a->guild_id>0){
 			WFIFOL(fd,c*32+4)=a->opposition;
 			WFIFOL(fd,c*32+8)=a->guild_id;
@@ -8982,14 +8978,14 @@ void clif_guild_memberlist( map_session_data& sd ){
 		return;
 	}
 
-	struct guild& guild = *sd.guild;
+	const auto &guild = sd.guild->guild;
 	struct PACKET_ZC_MEMBERMGR_INFO* p = (struct PACKET_ZC_MEMBERMGR_INFO*)packet_buffer;
 
 	p->PacketType = HEADER_ZC_MEMBERMGR_INFO;
 	p->packetLength = sizeof( *p );
 
 	for( int i = 0, c = 0; i < guild.max_member; i++ ){
-		struct guild_member& member = guild.member[i];
+		const auto &member = guild.member[i];
 
 		if( member.account_id == 0 ){
 			continue;
@@ -9030,10 +9026,10 @@ void clif_guild_memberlist( map_session_data& sd ){
 void clif_guild_positionnamelist(map_session_data *sd)
 {
 	int i,fd;
-	struct guild *g;
 
 	nullpo_retv(sd);
-	if( (g = sd->guild) == NULL )
+	auto &g = sd->guild;
+	if (!g)
 		return;
 
 	fd = sd->fd;
@@ -9041,7 +9037,7 @@ void clif_guild_positionnamelist(map_session_data *sd)
 	WFIFOW(fd, 0)=0x166;
 	for(i=0;i<MAX_GUILDPOSITION;i++){
 		WFIFOL(fd,i*28+4)=i;
-		safestrncpy(WFIFOCP(fd,i*28+8),g->position[i].name,NAME_LENGTH);
+		safestrncpy(WFIFOCP(fd,i*28+8),g->guild.position[i].name,NAME_LENGTH);
 	}
 	WFIFOW(fd,2)=i*28+4;
 	WFIFOSET(fd,WFIFOW(fd,2));
@@ -9058,17 +9054,17 @@ void clif_guild_positionnamelist(map_session_data *sd)
 void clif_guild_positioninfolist(map_session_data *sd)
 {
 	int i,fd;
-	struct guild *g;
 
 	nullpo_retv(sd);
-	if( (g = sd->guild) == NULL )
+	auto &g = sd->guild;
+	if (!g)
 		return;
 
 	fd = sd->fd;
 	WFIFOHEAD(fd, MAX_GUILDPOSITION * 16 + 4);
 	WFIFOW(fd, 0)=0x160;
 	for(i=0;i<MAX_GUILDPOSITION;i++){
-		struct guild_position *p=&g->position[i];
+		struct guild_position *p=&g->guild.position[i];
 		WFIFOL(fd,i*16+ 4)=i;
 		WFIFOL(fd,i*16+ 8)=p->mode;
 		WFIFOL(fd,i*16+12)=i;
@@ -9086,7 +9082,7 @@ void clif_guild_positioninfolist(map_session_data *sd)
 ///     &0x10 = allow expel
 /// ranking:
 ///     TODO
-void clif_guild_positionchanged(struct guild *g,int idx)
+void clif_guild_positionchanged(const struct mmo_guild &g,int idx)
 {
 	// FIXME: This packet is intended to update the clients after a
 	// commit of position info changes, not sending one packet per
@@ -9094,16 +9090,14 @@ void clif_guild_positionchanged(struct guild *g,int idx)
 	map_session_data *sd;
 	unsigned char buf[128];
 
-	nullpo_retv(g);
-
 	WBUFW(buf, 0)=0x174;
 	WBUFW(buf, 2)=44;  // packet len
 	// GUILD_REG_POSITION_INFO{
 	WBUFL(buf, 4)=idx;
-	WBUFL(buf, 8)=g->position[idx].mode;
+	WBUFL(buf, 8)=g.position[idx].mode;
 	WBUFL(buf,12)=idx;
-	WBUFL(buf,16)=g->position[idx].exp_mode;
-	safestrncpy(WBUFCP(buf,20),g->position[idx].name,NAME_LENGTH);
+	WBUFL(buf,16)=g.position[idx].exp_mode;
+	safestrncpy(WBUFCP(buf,20),g.position[idx].name,NAME_LENGTH);
 	// }*
 	if( (sd=guild_getavailablesd(g))!=NULL )
 		clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD);
@@ -9112,7 +9106,7 @@ void clif_guild_positionchanged(struct guild *g,int idx)
 
 /// Notifies clients in a guild about updated member position assignments (ZC_ACK_REQ_CHANGE_MEMBERS).
 /// 0156 <packet len>.W { <account id>.L <char id>.L <position id>.L }*
-void clif_guild_memberpositionchanged(struct guild *g,int idx)
+void clif_guild_memberpositionchanged(const struct mmo_guild &g, int idx)
 {
 	// FIXME: This packet is intended to update the clients after a
 	// commit of member position assignment changes, not sending one
@@ -9120,14 +9114,12 @@ void clif_guild_memberpositionchanged(struct guild *g,int idx)
 	map_session_data *sd;
 	unsigned char buf[64];
 
-	nullpo_retv(g);
-
 	WBUFW(buf, 0)=0x156;
 	WBUFW(buf, 2)=16;  // packet len
 	// MEMBER_POSITION_INFO{
-	WBUFL(buf, 4)=g->member[idx].account_id;
-	WBUFL(buf, 8)=g->member[idx].char_id;
-	WBUFL(buf,12)=g->member[idx].position;
+	WBUFL(buf, 4)=g.member[idx].account_id;
+	WBUFL(buf, 8)=g.member[idx].char_id;
+	WBUFL(buf,12)=g.member[idx].position;
 	// }*
 	if( (sd=guild_getavailablesd(g))!=NULL )
 		clif_send(buf,WBUFW(buf,2),&sd->bl,GUILD);
@@ -9136,22 +9128,18 @@ void clif_guild_memberpositionchanged(struct guild *g,int idx)
 
 /// Sends emblems bitmap data to the client that requested it (ZC_GUILD_EMBLEM_IMG).
 /// 0152 <packet len>.W <guild id>.L <emblem id>.L <emblem data>.?B
-void clif_guild_emblem(map_session_data *sd,struct guild *g)
+void clif_guild_emblem(const map_session_data &sd, const struct mmo_guild &g)
 {
-	int fd;
-	nullpo_retv(sd);
-	nullpo_retv(g);
-
-	fd = sd->fd;
-	if( g->emblem_len <= 0 )
+	int fd = sd.fd;
+	if( g.emblem_len <= 0 )
 		return;
 
-	WFIFOHEAD(fd,g->emblem_len+12);
+	WFIFOHEAD(fd,g.emblem_len+12);
 	WFIFOW(fd,0)=0x152;
-	WFIFOW(fd,2)=g->emblem_len+12;
-	WFIFOL(fd,4)=g->guild_id;
-	WFIFOL(fd,8)=g->emblem_id;
-	memcpy(WFIFOP(fd,12),g->emblem_data,g->emblem_len);
+	WFIFOW(fd,2)=g.emblem_len+12;
+	WFIFOL(fd,4)=g.guild_id;
+	WFIFOL(fd,8)=g.emblem_id;
+	memcpy(WFIFOP(fd,12),g.emblem_data,g.emblem_len);
 	WFIFOSET(fd,WFIFOW(fd,2));
 }
 
@@ -9184,30 +9172,30 @@ void clif_guild_emblem_area(struct block_list* bl)
 void clif_guild_skillinfo(map_session_data* sd)
 {
 	int fd;
-	struct guild* g;
 	int i,c;
 
 	nullpo_retv(sd);
-	if( (g = sd->guild) == NULL )
+	auto &g = sd->guild;
+	if (!g)
 		return;
 
 	fd = sd->fd;
 	WFIFOHEAD(fd, 6 + MAX_GUILDSKILL*37);
 	WFIFOW(fd,0) = 0x0162;
-	WFIFOW(fd,4) = g->skill_point;
+	WFIFOW(fd,4) = g->guild.skill_point;
 	for(i = 0, c = 0; i < MAX_GUILDSKILL; i++)
 	{
-		if(g->skill[i].id > 0 && guild_check_skill_require(g, g->skill[i].id))
+		if(g->guild.skill[i].id > 0 && guild_check_skill_require(g->guild, g->guild.skill[i].id))
 		{
-			int id = g->skill[i].id;
+			int id = g->guild.skill[i].id;
 			int p = 6 + c*37;
 			WFIFOW(fd,p+0) = id;
 			WFIFOL(fd,p+2) = skill_get_inf(id);
-			WFIFOW(fd,p+6) = g->skill[i].lv;
-			WFIFOW(fd,p+8) = skill_get_sp(id, g->skill[i].lv);
-			WFIFOW(fd,p+10) = skill_get_range(id, g->skill[i].lv);
+			WFIFOW(fd,p+6) = g->guild.skill[i].lv;
+			WFIFOW(fd,p+8) = skill_get_sp(id, g->guild.skill[i].lv);
+			WFIFOW(fd,p+10) = skill_get_range(id, g->guild.skill[i].lv);
 			safestrncpy(WFIFOCP(fd,p+12), skill_get_name(id), NAME_LENGTH);
-			WFIFOB(fd,p+36)= (g->skill[i].lv < guild_skill_get_max(id) && sd == g->member[0].sd) ? 1 : 0;
+			WFIFOB(fd,p+36)= (g->guild.skill[i].lv < guild_skill_get_max(id) && sd == g->guild.member[0].sd) ? 1 : 0;
 			c++;
 		}
 	}
@@ -9220,41 +9208,35 @@ void clif_guild_skillinfo(map_session_data* sd)
 /// 016f <subject>.60B <notice>.120B
 void clif_guild_notice(map_session_data* sd)
 {
-	struct guild* g;
-
 	nullpo_retv(sd);
-	nullpo_retv(g = sd->guild);
+
+	auto &g = sd->guild;
 
 	int fd = sd->fd;
 
 	if ( !session_isActive(fd) )
 		return;
 
-	if(g->mes1[0] == '\0' && g->mes2[0] == '\0')
+	if(g->guild.mes1[0] == '\0' && g->guild.mes2[0] == '\0')
 		return;
 
 	WFIFOHEAD(fd,packet_len(0x16f));
 	WFIFOW(fd,0) = 0x16f;
-	memcpy(WFIFOP(fd,2), g->mes1, MAX_GUILDMES1);
-	memcpy(WFIFOP(fd,62), g->mes2, MAX_GUILDMES2);
+	memcpy(WFIFOP(fd,2), g->guild.mes1, MAX_GUILDMES1);
+	memcpy(WFIFOP(fd,62), g->guild.mes2, MAX_GUILDMES2);
 	WFIFOSET(fd,packet_len(0x16f));
 }
 
 
 /// Guild invite (ZC_REQ_JOIN_GUILD).
 /// 016a <guild id>.L <guild name>.24B
-void clif_guild_invite(map_session_data *sd,struct guild *g)
+void clif_guild_invite(const map_session_data &sd, const struct mmo_guild &g)
 {
-	int fd;
-
-	nullpo_retv(sd);
-	nullpo_retv(g);
-
-	fd=sd->fd;
+	int fd = sd.fd;
 	WFIFOHEAD(fd,packet_len(0x16a));
 	WFIFOW(fd,0)=0x16a;
-	WFIFOL(fd,2)=g->guild_id;
-	safestrncpy(WFIFOCP(fd,6),g->name,NAME_LENGTH);
+	WFIFOL(fd,2)=g.guild_id;
+	safestrncpy(WFIFOCP(fd,6),g.name,NAME_LENGTH);
 	WFIFOSET(fd,packet_len(0x16a));
 }
 
@@ -9330,11 +9312,11 @@ void clif_guild_expulsionlist(map_session_data* sd)
 	const int offset = NAME_LENGTH+40;
 #endif
 	int fd, i, c = 0;
-	struct guild* g;
 
 	nullpo_retv(sd);
 
-	if( (g = sd->guild) == NULL )
+	auto &g = sd->guild;
+	if (!g)
 		return;
 
 	fd = sd->fd;
@@ -9344,7 +9326,7 @@ void clif_guild_expulsionlist(map_session_data* sd)
 
 	for( i = 0; i < MAX_GUILDEXPULSION; i++ )
 	{
-		struct guild_expulsion* e = &g->expulsion[i];
+		struct guild_expulsion* e = &g->guild.expulsion[i];
 
 		if( e->account_id > 0 )
 		{
@@ -9365,7 +9347,7 @@ void clif_guild_expulsionlist(map_session_data* sd)
 
 /// Guild chat message (ZC_GUILD_CHAT).
 /// 017f <packet len>.W <message>.?B
-void clif_guild_message(struct guild *g,uint32 account_id,const char *mes,int len)
+void clif_guild_message(const struct mmo_guild &g,uint32 account_id,const char *mes,int len)
 {// TODO: account_id is not used, candidate for deletion? [Ai4rei]
 	map_session_data *sd;
 	uint8 buf[256];
@@ -9376,7 +9358,7 @@ void clif_guild_message(struct guild *g,uint32 account_id,const char *mes,int le
 	}
 	else if( len > sizeof(buf)-5 )
 	{
-		ShowWarning("clif_guild_message: Truncated message '%s' (len=%d, max=%" PRIuPTR ", guild_id=%d).\n", mes, len, sizeof(buf)-5, g->guild_id);
+		ShowWarning("clif_guild_message: Truncated message '%s' (len=%d, max=%" PRIuPTR ", guild_id=%d).\n", mes, len, sizeof(buf)-5, g.guild_id);
 		len = sizeof(buf)-5;
 	}
 
@@ -10091,10 +10073,10 @@ void clif_name( struct block_list* src, struct block_list *bl, send_target targe
 				int position;
 
 				// Will get the position of the guild the player is in
-				position = guild_getposition( sd );
+				position = guild_getposition(*sd);
 
-				safestrncpy( packet.guild_name, sd->guild->name, NAME_LENGTH );
-				safestrncpy( packet.position_name, sd->guild->position[position].name, NAME_LENGTH );
+				safestrncpy( packet.guild_name, sd->guild->guild.name, NAME_LENGTH );
+				safestrncpy( packet.position_name, sd->guild->guild.position[position].name, NAME_LENGTH );
 			}else if( sd->clan ){
 				safestrncpy( packet.position_name, sd->clan->name, NAME_LENGTH );
 			}
@@ -11210,10 +11192,10 @@ void clif_parse_LoadEndAck(int fd,map_session_data *sd)
 
 	/* Guild Aura Init */
 	if( sd->guild && sd->state.gmaster_flag ) {
-		guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->guild,GD_LEADERSHIP));
-		guild_guildaura_refresh(sd,GD_GLORYWOUNDS,guild_checkskill(sd->guild,GD_GLORYWOUNDS));
-		guild_guildaura_refresh(sd,GD_SOULCOLD,guild_checkskill(sd->guild,GD_SOULCOLD));
-		guild_guildaura_refresh(sd,GD_HAWKEYES,guild_checkskill(sd->guild,GD_HAWKEYES));
+		guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->guild->guild,GD_LEADERSHIP));
+		guild_guildaura_refresh(sd,GD_GLORYWOUNDS,guild_checkskill(sd->guild->guild,GD_GLORYWOUNDS));
+		guild_guildaura_refresh(sd,GD_SOULCOLD,guild_checkskill(sd->guild->guild,GD_SOULCOLD));
+		guild_guildaura_refresh(sd,GD_HAWKEYES,guild_checkskill(sd->guild->guild,GD_HAWKEYES));
 	}
 
 	if( sd->state.vending ) { /* show we have a vending */
@@ -13021,8 +13003,8 @@ void clif_parse_skill_toid( map_session_data* sd, uint16 skill_id, uint16 skill_
 	sd->skillitem = sd->skillitemlv = 0;
 
 	if( SKILL_CHK_GUILD(skill_id) ) {
-		if( sd->state.gmaster_flag || skill_id == GD_CHARGESHOUT_BEATING )
-			skill_lv = guild_checkskill(sd->guild, skill_id);
+		if (sd->guild && sd->state.gmaster_flag || skill_id == GD_CHARGESHOUT_BEATING)
+			skill_lv = guild_checkskill(sd->guild->guild, skill_id);
 		else
 			skill_lv = 0;
 	} else {
@@ -14304,7 +14286,7 @@ void clif_parse_GuildChangeMemberPosition( int fd, map_session_data *sd ){
 				return;
 			}
 
-			if( battle_config.guild_leaderchange_delay && DIFF_TICK( time( nullptr ),sd->guild->last_leader_change ) < battle_config.guild_leaderchange_delay ){
+			if( battle_config.guild_leaderchange_delay && DIFF_TICK( time( nullptr ),sd->guild->guild.last_leader_change ) < battle_config.guild_leaderchange_delay ){
 				clif_msg( sd, GUILD_MASTER_DELAY );
 				return;
 			}
@@ -14324,11 +14306,12 @@ void clif_parse_GuildChangeMemberPosition( int fd, map_session_data *sd ){
 /// 0151 <guild id>.L
 void clif_parse_GuildRequestEmblem(int fd,map_session_data *sd)
 {
-	struct guild* g;
 	int guild_id = RFIFOL(fd,packet_db[RFIFOW(fd,0)].pos[0]);
 
-	if( (g = guild_search(guild_id)) != NULL )
-		clif_guild_emblem(sd,g);
+	auto g = guild_search(guild_id);
+
+	if (g)
+		clif_guild_emblem(*sd, g->guild);
 }
 
 
@@ -14405,9 +14388,9 @@ void clif_parse_GuildChangeEmblem2(int fd, map_session_data* sd) {
 
 #if PACKETVER >= 20190724
 	const PACKET_CZ_GUILD_EMBLEM_CHANGE2* p = (PACKET_CZ_GUILD_EMBLEM_CHANGE2*)RFIFOP(fd, 0);
-	guild* g = sd->guild;
+	auto &g = sd->guild;
 
-	if (g == nullptr || g->guild_id != p->guild_id)
+	if (!g || g->guild.guild_id != p->guild_id)
 		return;
 
 	if (!sd->state.gmaster_flag)

+ 7 - 7
src/map/clif.hpp

@@ -34,7 +34,7 @@ struct skill_unit;
 struct s_vending;
 struct party;
 struct party_data;
-struct guild;
+struct mmo_guild;
 struct s_battleground_data;
 struct quest;
 struct party_booking_ad_info;
@@ -848,17 +848,17 @@ void clif_guild_allianceinfo(map_session_data *sd);
 void clif_guild_memberlist( map_session_data& sd );
 void clif_guild_skillinfo(map_session_data* sd);
 void clif_guild_send_onlineinfo(map_session_data *sd); //[LuzZza]
-void clif_guild_memberlogin_notice(struct guild *g,int idx,int flag);
-void clif_guild_invite(map_session_data *sd,struct guild *g);
+void clif_guild_memberlogin_notice(const struct mmo_guild &g,int idx,int flag);
+void clif_guild_invite(const map_session_data &sd, const struct mmo_guild &g);
 void clif_guild_inviteack(map_session_data *sd,int flag);
 void clif_guild_leave(map_session_data *sd,const char *name,const char *mes);
 void clif_guild_expulsion(map_session_data* sd, const char* name, const char* mes, uint32 account_id);
-void clif_guild_positionchanged(struct guild *g,int idx);
-void clif_guild_memberpositionchanged(struct guild *g,int idx);
-void clif_guild_emblem(map_session_data *sd,struct guild *g);
+void clif_guild_positionchanged(const struct mmo_guild &g,int idx);
+void clif_guild_memberpositionchanged(const struct mmo_guild &g,int idx);
+void clif_guild_emblem(const map_session_data &sd, const struct mmo_guild &g);
 void clif_guild_emblem_area(struct block_list* bl);
 void clif_guild_notice(map_session_data* sd);
-void clif_guild_message(struct guild *g,uint32 account_id,const char *mes,int len);
+void clif_guild_message(const struct mmo_guild &g,uint32 account_id,const char *mes,int len);
 void clif_guild_reqalliance(map_session_data *sd,uint32 account_id,const char *name);
 void clif_guild_allianceack(map_session_data *sd,int flag);
 void clif_guild_delalliance(map_session_data *sd,int guild_id,int flag);

+ 1 - 2
src/map/elemental.cpp

@@ -4,8 +4,7 @@
 #include "elemental.hpp"
 
 #include <cstring>
-#include <ctgmath> //floor
-#include <math.h>
+#include <cmath>
 #include <stdlib.h>
 
 #include <common/cbasetypes.hpp>

文件差異過大導致無法顯示
+ 217 - 232
src/map/guild.cpp


+ 20 - 11
src/map/guild.hpp

@@ -10,7 +10,7 @@
 
 #include "map.hpp" // NAME_LENGTH
 
-struct guild;
+struct mmo_guild;
 struct guild_member;
 struct guild_position;
 struct guild_castle;
@@ -27,20 +27,29 @@ struct guardian_data {
 	std::shared_ptr<guild_castle> castle;
 };
 
+class MapGuild {
+public:
+	struct mmo_guild guild;
+	struct Channel *channel;
+	int instance_id;
+	int32 chargeshout_flag_id;
+};
+
 uint16 guild_skill_get_max(uint16 id);
 
-int guild_checkskill(struct guild *g,int id);
-bool guild_check_skill_require(struct guild *g,uint16 id); // [Komurka]
-int guild_checkcastles(struct guild *g); // [MouseJstr]
+int guild_checkskill(const struct mmo_guild &g,int id);
+bool guild_check_skill_require(const struct mmo_guild &g,uint16 id); // [Komurka]
+int guild_checkcastles(const struct mmo_guild &g); // [MouseJstr]
 bool guild_isallied(int guild_id, int guild_id2); //Checks alliance based on guild Ids. [Skotlex]
 
 void do_init_guild(void);
-struct guild *guild_search(int guild_id);
-struct guild *guild_searchname(char *str);
+std::shared_ptr<MapGuild> guild_search(int guild_id);
+std::shared_ptr<MapGuild> guild_searchname(const char *str);
+std::shared_ptr<MapGuild> guild_searchnameid(const char *str);
 
-map_session_data *guild_getavailablesd(struct guild *g);
-int guild_getindex(struct guild *g,uint32 account_id,uint32 char_id);
-int guild_getposition(map_session_data *sd);
+map_session_data* guild_getavailablesd(const struct mmo_guild &g);
+int guild_getindex(const struct mmo_guild &g, uint32 account_id, uint32 char_id);
+int guild_getposition(const map_session_data &sd);
 t_exp guild_payexp(map_session_data *sd,t_exp exp);
 t_exp guild_getexp(map_session_data *sd,t_exp exp); // [Celest]
 
@@ -48,7 +57,7 @@ int guild_create(map_session_data *sd, const char *name);
 int guild_created(uint32 account_id,int guild_id);
 int guild_request_info(int guild_id);
 int guild_recv_noinfo(int guild_id);
-int guild_recv_info(struct guild *sg);
+int guild_recv_info(const struct mmo_guild &sg);
 int guild_npc_request_info(int guild_id,const char *ev);
 int guild_invite(map_session_data *sd,map_session_data *tsd);
 int guild_reply_invite(map_session_data *sd,int guild_id,int flag);
@@ -73,7 +82,7 @@ int guild_check_alliance(int guild_id1, int guild_id2, int flag);
 int guild_send_memberinfoshort(map_session_data *sd,int online);
 int guild_recv_memberinfoshort(int guild_id,uint32 account_id,uint32 char_id,int online,int lv,int class_);
 int guild_change_memberposition(int guild_id,uint32 account_id,uint32 char_id,short idx);
-int guild_memberposition_changed(struct guild *g,int idx,int pos);
+int guild_memberposition_changed(struct mmo_guild &g,int idx,int pos);
 int guild_change_position(int guild_id,int idx,int mode,int exp_mode,const char *name);
 int guild_position_changed(int guild_id,int idx,struct guild_position *p);
 int guild_change_notice(map_session_data *sd,int guild_id,const char *mes1,const char *mes2);

+ 11 - 11
src/map/instance.cpp

@@ -305,7 +305,7 @@ void instance_getsd(int instance_id, map_session_data *&sd, enum send_target *ta
 			(*target) = SELF;
 			break;
 		case IM_GUILD:
-			sd = guild_getavailablesd(guild_search(idata->owner_id));
+			sd = guild_getavailablesd(guild_search(idata->owner_id)->guild);
 			(*target) = GUILD;
 			break;
 		case IM_PARTY:
@@ -348,7 +348,7 @@ static TIMER_FUNC(instance_subscription_timer){
 
 	map_session_data *sd;
 	struct party_data *pd;
-	struct guild *gd;
+	std::shared_ptr<MapGuild> gd;
 	struct clan *cd;
 	e_instance_mode mode = idata->mode;
 	int ret = instance_addmap(instance_id); // Check that maps have been added
@@ -613,7 +613,7 @@ int instance_create(int owner_id, const char *name, e_instance_mode mode) {
 
 	map_session_data *sd = nullptr;
 	struct party_data *pd;
-	struct guild *gd;
+	std::shared_ptr<MapGuild> gd;
 	struct clan* cd;
 
 	switch(mode) {
@@ -683,7 +683,7 @@ int instance_create(int owner_id, const char *name, e_instance_mode mode) {
 			break;
 		case IM_GUILD:
 			gd->instance_id = instance_id;
-			sd = map_charid2sd(gd->member[0].char_id);
+			sd = map_charid2sd(gd->guild.member[0].char_id);
 			break;
 		case IM_CLAN:
 			cd->instance_id = instance_id;
@@ -878,7 +878,7 @@ void instance_destroy_command(map_session_data *sd) {
 
 		instance_id = pd->instance_id;
 	} else if (sd->instance_mode == IM_GUILD && sd->guild != nullptr && sd->guild->instance_id > 0) {
-		guild *gd = guild_search(sd->status.guild_id);
+		auto gd = guild_search(sd->status.guild_id);
 
 		if (gd == nullptr)
 			return;
@@ -888,7 +888,7 @@ void instance_destroy_command(map_session_data *sd) {
 		if (idata == nullptr)
 			return;
 
-		if (strcmp(sd->status.name, gd->master) != 0) // Player is not guild master
+		if (strcmp(sd->status.name, gd->guild.master) != 0) // Player is not guild master
 			return;
 
 		instance_id = gd->instance_id;
@@ -915,7 +915,7 @@ void instance_destroy_command(map_session_data *sd) {
 			instance_reqinfo(sd, pd->instance_id);
 	}
 	if (sd->guild != nullptr && sd->guild->instance_id > 0) {
-		guild *gd = guild_search(sd->status.guild_id);
+		auto gd = guild_search(sd->status.guild_id);
 
 		if (gd == nullptr)
 			return;
@@ -938,7 +938,7 @@ bool instance_destroy(int instance_id)
 
 	map_session_data *sd;
 	struct party_data *pd;
-	struct guild *gd;
+	std::shared_ptr<MapGuild> gd;
 	struct clan *cd;
 	e_instance_mode mode = idata->mode;
 	e_instance_notify type = IN_NOTIFY;
@@ -1065,7 +1065,7 @@ e_instance_enter instance_enter(map_session_data *sd, int instance_id, const cha
 
 	std::shared_ptr<s_instance_data> idata = nullptr;
 	struct party_data *pd;
-	struct guild *gd;
+	std::shared_ptr<MapGuild> gd;
 	struct clan *cd;
 	e_instance_mode mode;
 
@@ -1103,7 +1103,7 @@ e_instance_enter instance_enter(map_session_data *sd, int instance_id, const cha
 				return IE_NOMEMBER;
 			if (gd->instance_id == 0) // Guild must have an instance
 				return IE_NOINSTANCE;
-			if (idata->owner_id != gd->guild_id)
+			if (idata->owner_id != gd->guild.guild_id)
 				return IE_OTHER;
 			break;
 		case IM_CLAN:
@@ -1249,7 +1249,7 @@ void do_reload_instance(void)
 
 		if (sd && mapdata->instance_id > 0) {
 			struct party_data *pd;
-			struct guild *gd;
+			std::shared_ptr<MapGuild> gd;
 			struct clan *cd;
 			int instance_id;
 			std::shared_ptr<s_instance_data> idata = util::umap_find(instances, map[sd->bl.m].instance_id);

+ 17 - 18
src/map/intif.cpp

@@ -1666,9 +1666,9 @@ int intif_parse_GuildInfo(int fd)
 		guild_recv_noinfo(RFIFOL(fd,4));
 		return 0;
 	}
-	if( RFIFOW(fd,2)!=sizeof(struct guild)+4 )
-		ShowError("intif: guild info : data size error Gid: %d recv size: %d Expected size: %" PRIuPTR "\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct guild)+4);
-	guild_recv_info((struct guild *)RFIFOP(fd,4));
+	if( RFIFOW(fd,2)!=sizeof(struct mmo_guild)+4 )
+		ShowError("intif: guild info : data size error Gid: %d recv size: %d Expected size: %" PRIuPTR "\n",RFIFOL(fd,4),RFIFOW(fd,2),sizeof(struct mmo_guild)+4);
+	guild_recv_info(*(struct mmo_guild *)RFIFOP(fd,4));
 	return 1;
 }
 
@@ -1731,14 +1731,14 @@ int intif_parse_GuildBasicInfoChanged(int fd)
 	int type = RFIFOW(fd,8);
 	//void* data = RFIFOP(fd,10);
 
-	struct guild* g = guild_search(guild_id);
+	auto g = guild_search(guild_id);
 	if( g == NULL )
 		return 0;
 
 	switch(type) {
-	case GBI_EXP:        g->exp = RFIFOQ(fd,10); break;
-	case GBI_GUILDLV:    g->guild_lv = RFIFOW(fd,10); break;
-	case GBI_SKILLPOINT: g->skill_point = RFIFOL(fd,10); break;
+	case GBI_EXP:        g->guild.exp = RFIFOQ(fd,10); break;
+	case GBI_GUILDLV:    g->guild.guild_lv = RFIFOW(fd,10); break;
+	case GBI_SKILLPOINT: g->guild.skill_point = RFIFOL(fd,10); break;
 	}
 
 	return 1;
@@ -1759,25 +1759,24 @@ int intif_parse_GuildMemberInfoChanged(int fd)
 	int type = RFIFOW(fd,16);
 	//void* data = RFIFOP(fd,18);
 
-	struct guild* g;
 	int idx;
 
-	g = guild_search(guild_id);
-	if( g == NULL )
+	auto g = guild_search(guild_id);
+	if( g == nullptr )
 		return 0;
 
-	idx = guild_getindex(g,account_id,char_id);
+	idx = guild_getindex(g->guild,account_id,char_id);
 	if( idx == -1 )
 		return 0;
 
 	switch( type ) {
-	case GMI_POSITION:   g->member[idx].position   = RFIFOW(fd,18); guild_memberposition_changed(g,idx,RFIFOW(fd,18)); break;
-	case GMI_EXP:        g->member[idx].exp        = RFIFOQ(fd,18); break;
-	case GMI_HAIR:       g->member[idx].hair       = RFIFOW(fd,18); break;
-	case GMI_HAIR_COLOR: g->member[idx].hair_color = RFIFOW(fd,18); break;
-	case GMI_GENDER:     g->member[idx].gender     = RFIFOW(fd,18); break;
-	case GMI_CLASS:      g->member[idx].class_     = RFIFOW(fd,18); break;
-	case GMI_LEVEL:      g->member[idx].lv         = RFIFOW(fd,18); break;
+	case GMI_POSITION:   g->guild.member[idx].position   = RFIFOW(fd,18); guild_memberposition_changed(g->guild,idx,RFIFOW(fd,18)); break;
+	case GMI_EXP:        g->guild.member[idx].exp        = RFIFOQ(fd,18); break;
+	case GMI_HAIR:       g->guild.member[idx].hair       = RFIFOW(fd,18); break;
+	case GMI_HAIR_COLOR: g->guild.member[idx].hair_color = RFIFOW(fd,18); break;
+	case GMI_GENDER:     g->guild.member[idx].gender     = RFIFOW(fd,18); break;
+	case GMI_CLASS:      g->guild.member[idx].class_     = RFIFOW(fd,18); break;
+	case GMI_LEVEL:      g->guild.member[idx].lv         = RFIFOW(fd,18); break;
 	}
 	return 1;
 }

+ 9 - 2
src/map/itemdb.cpp

@@ -196,6 +196,8 @@ uint64 ItemDatabase::parseBodyNode(const ryml::NodeRef& node) {
 			item->subtype = 0;
 	}
 
+	bool has_buy = false, has_sell = false;
+
 	if (this->nodeExists(node, "Buy")) {
 		uint32 buy;
 
@@ -207,6 +209,7 @@ uint64 ItemDatabase::parseBodyNode(const ryml::NodeRef& node) {
 			buy = MAX_ZENY;
 		}
 
+		has_buy = true;
 		item->value_buy = buy;
 	} else {
 		if (!exists) {
@@ -225,6 +228,7 @@ uint64 ItemDatabase::parseBodyNode(const ryml::NodeRef& node) {
 			sell = MAX_ZENY;
 		}
 
+		has_sell = true;
 		item->value_sell = sell;
 	} else {
 		if (!exists) {
@@ -232,6 +236,8 @@ uint64 ItemDatabase::parseBodyNode(const ryml::NodeRef& node) {
 		}
 	}
 
+	hasPriceValue[item->nameid] = { has_buy, has_sell };
+
 	if (this->nodeExists(node, "Weight")) {
 		uint32 weight;
 
@@ -1153,9 +1159,9 @@ void ItemDatabase::loadingFinished(){
 		}
 
 		// When a particular price is not given, we should base it off the other one
-		if (item->value_buy == 0 && item->value_sell > 0)
+		if (!hasPriceValue[item->nameid].has_buy && hasPriceValue[item->nameid].has_sell)
 			item->value_buy = item->value_sell * 2;
-		else if (item->value_buy > 0 && item->value_sell == 0)
+		else if (hasPriceValue[item->nameid].has_buy && !hasPriceValue[item->nameid].has_sell)
 			item->value_sell = item->value_buy / 2;
 
 		if (item->value_buy / 124. < item->value_sell / 75.) {
@@ -1186,6 +1192,7 @@ void ItemDatabase::loadingFinished(){
 	}
 
 	TypesafeCachedYamlDatabase::loadingFinished();
+	hasPriceValue.clear();
 }
 
 /**

+ 9 - 3
src/map/itemdb.hpp

@@ -2134,6 +2134,15 @@ private:
 
 	e_sex defaultGender( const ryml::NodeRef& node, std::shared_ptr<item_data> id );
 
+	std::string create_item_link(struct item& item, std::shared_ptr<item_data>& data);
+
+	struct s_pricevalue {
+		bool has_buy;
+		bool has_sell;
+	};
+
+	std::unordered_map<t_itemid, s_pricevalue> hasPriceValue;
+
 public:
 	ItemDatabase() : TypesafeCachedYamlDatabase("ITEM_DB", 3, 1) {
 
@@ -2155,9 +2164,6 @@ public:
 	std::string create_item_link(struct item& item);
 	std::string create_item_link( std::shared_ptr<item_data>& data );
 	std::string create_item_link_for_mes( std::shared_ptr<item_data>& data, bool use_brackets, const char* name );
-
-private:
-	std::string create_item_link(struct item& item, std::shared_ptr<item_data>& data);
 };
 
 extern ItemDatabase item_db;

+ 4 - 4
src/map/map-server-generator.vcxproj

@@ -113,7 +113,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\json\include;$(SolutionDir)\3rdparty\pcre\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -130,7 +130,7 @@
       <PreprocessorDefinitions>$(DefineConstants);MAP_GENERATOR;WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\json\include;$(SolutionDir)\3rdparty\pcre\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -150,7 +150,7 @@
       <PreprocessorDefinitions>$(DefineConstants);MAP_GENERATOR;WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\json\include;$(SolutionDir)\3rdparty\pcre\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -173,7 +173,7 @@
       <PreprocessorDefinitions>$(DefineConstants);MAP_GENERATOR;WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\json\include;$(SolutionDir)\3rdparty\pcre\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 4 - 4
src/map/map-server.vcxproj

@@ -113,7 +113,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\pcre\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -130,7 +130,7 @@
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\pcre\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -150,7 +150,7 @@
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\pcre\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -173,7 +173,7 @@
       <PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\pcre\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 16 - 18
src/map/mob.cpp

@@ -684,7 +684,7 @@ int mob_once_spawn(map_session_data* sd, int16 m, int16 x, int16 y, const char*
 		if (mob_id == MOBID_EMPERIUM)
 		{
 			std::shared_ptr<guild_castle> gc = castle_db.mapindex2gc(map_getmapdata(m)->index);
-			struct guild* g = (gc) ? guild_search(gc->guild_id) : nullptr;
+			auto g = (gc) ? guild_search(gc->guild_id) : nullptr;
 			if (gc)
 			{
 				md->guardian_data = (struct guardian_data*)aCalloc(1, sizeof(struct guardian_data));
@@ -694,8 +694,8 @@ int mob_once_spawn(map_session_data* sd, int16 m, int16 x, int16 y, const char*
 				md->guardian_data->guild_id = gc->guild_id;
 				if (g)
 				{
-					md->guardian_data->emblem_id = g->emblem_id;
-					memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
+					md->guardian_data->emblem_id = g->guild.emblem_id;
+					memcpy(md->guardian_data->guild_name, g->guild.name, NAME_LENGTH);
 				}
 				else if (gc->guild_id) // Guild is not yet available, retry after the configured timespan.
 					add_timer(gettick() + battle_config.mob_respawn_time,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id);
@@ -774,7 +774,6 @@ static TIMER_FUNC(mob_spawn_guardian_sub){
 	//Needed because the guild_data may not be available at guardian spawn time.
 	struct block_list* bl = map_id2bl(id);
 	struct mob_data* md;
-	struct guild* g;
 	int guardup_lv;
 
 	if (bl == nullptr) //It is possible mob was already removed from map when the castle has no owner. [Skotlex]
@@ -788,7 +787,7 @@ static TIMER_FUNC(mob_spawn_guardian_sub){
 
 	md = (struct mob_data*)bl;
 	nullpo_ret(md->guardian_data);
-	g = guild_search((int)data);
+	auto g = guild_search((int)data);
 
 	if (g == nullptr)
 	{	//Liberate castle, if the guild is not found this is an error! [Skotlex]
@@ -808,9 +807,9 @@ static TIMER_FUNC(mob_spawn_guardian_sub){
 		}
 		return 0;
 	}
-	guardup_lv = guild_checkskill(g,GD_GUARDUP);
-	md->guardian_data->emblem_id = g->emblem_id;
-	memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
+	guardup_lv = guild_checkskill(g->guild, GD_GUARDUP);
+	md->guardian_data->emblem_id = g->guild.emblem_id;
+	memcpy(md->guardian_data->guild_name, g->guild.name, NAME_LENGTH);
 	md->guardian_data->guardup_lv = guardup_lv;
 	if( guardup_lv )
 		status_calc_mob(md, SCO_NONE); //Give bonuses.
@@ -824,7 +823,7 @@ int mob_spawn_guardian(const char* mapname, int16 x, int16 y, const char* mobnam
 {
 	struct mob_data *md=nullptr;
 	struct spawn_data data;
-	struct guild *g=nullptr;
+	std::shared_ptr<MapGuild> g = nullptr;
 	int16 m;
 	memset(&data, 0, sizeof(struct spawn_data)); //fixme
 	data.num = 1;
@@ -913,9 +912,9 @@ int mob_spawn_guardian(const char* mapname, int16 x, int16 y, const char* mobnam
 	}
 	if (g)
 	{
-		md->guardian_data->emblem_id = g->emblem_id;
-		memcpy (md->guardian_data->guild_name, g->name, NAME_LENGTH);
-		md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP);
+		md->guardian_data->emblem_id = g->guild.emblem_id;
+		memcpy (md->guardian_data->guild_name, g->guild.name, NAME_LENGTH);
+		md->guardian_data->guardup_lv = guild_checkskill(g->guild,GD_GUARDUP);
 	} else if (md->guardian_data->guild_id)
 		add_timer(gettick() + battle_config.mob_respawn_time,mob_spawn_guardian_sub,md->bl.id,md->guardian_data->guild_id);
 	mob_spawn(md);
@@ -3212,7 +3211,6 @@ void mob_revive(struct mob_data *md, unsigned int hp)
 
 int mob_guardian_guildchange(struct mob_data *md)
 {
-	struct guild *g;
 	nullpo_ret(md);
 
 	if (!md->guardian_data)
@@ -3233,7 +3231,7 @@ int mob_guardian_guildchange(struct mob_data *md)
 		return 0;
 	}
 
-	g = guild_search(md->guardian_data->castle->guild_id);
+	auto g = guild_search(md->guardian_data->castle->guild_id);
 	if (g == NULL)
 	{	//Properly remove guardian info from Castle data.
 		ShowError("mob_guardian_guildchange: New Guild (id %d) does not exists!\n", md->guardian_data->guild_id);
@@ -3243,10 +3241,10 @@ int mob_guardian_guildchange(struct mob_data *md)
 		return 0;
 	}
 
-	md->guardian_data->guild_id = g->guild_id;
-	md->guardian_data->emblem_id = g->emblem_id;
-	md->guardian_data->guardup_lv = guild_checkskill(g,GD_GUARDUP);
-	memcpy(md->guardian_data->guild_name, g->name, NAME_LENGTH);
+	md->guardian_data->guild_id = g->guild.guild_id;
+	md->guardian_data->emblem_id = g->guild.emblem_id;
+	md->guardian_data->guardup_lv = guild_checkskill(g->guild, GD_GUARDUP);
+	memcpy(md->guardian_data->guild_name, g->guild.name, NAME_LENGTH);
 
 	return 1;
 }

+ 1 - 1
src/map/navi.cpp

@@ -154,7 +154,7 @@ static int add_path(struct node_heap *heap, int16 x, int16 y, int g_cost, struct
  * Note: uses global g_open_set, therefore this method can't be called in parallel or recursivly.
  *------------------------------------------*/
 bool navi_path_search(struct navi_walkpath_data *wpd, const struct navi_pos *from, const struct navi_pos *dest, cell_chk cell) {
-	register int i, x, y, dx = 0, dy = 0;
+	int i, x, y, dx = 0, dy = 0;
 	struct map_data *mapdata = map_getmapdata(from->m);
 	struct navi_walkpath_data s_wpd;
 

+ 1 - 1
src/map/path.cpp

@@ -270,7 +270,7 @@ static int add_path(struct node_heap *heap, struct path_node *tp, int16 x, int16
  *------------------------------------------*/
 bool path_search(struct walkpath_data *wpd, int16 m, int16 x0, int16 y0, int16 x1, int16 y1, int flag, cell_chk cell)
 {
-	register int i, x, y, dx = 0, dy = 0;
+	int i, x, y, dx = 0, dy = 0;
 	struct map_data *mapdata = map_getmapdata(m);
 	struct walkpath_data s_wpd;
 

+ 9 - 11
src/map/pc.cpp

@@ -1225,7 +1225,7 @@ bool pc_can_sell_item(map_session_data *sd, struct item *item, enum npc_subtype
 		case NPCTYPE_SHOP:
 			if (item->bound && battle_config.allow_bound_sell&ISR_BOUND_SELLABLE && (
 				item->bound != BOUND_GUILD ||
-				(sd->guild && sd->status.char_id == sd->guild->member[0].char_id) ||
+				(sd->guild && sd->status.char_id == sd->guild->guild.member[0].char_id) ||
 				(item->bound == BOUND_GUILD && !(battle_config.allow_bound_sell&ISR_BOUND_GUILDLEADER_ONLY))
 				))
 				return true;
@@ -1233,7 +1233,7 @@ bool pc_can_sell_item(map_session_data *sd, struct item *item, enum npc_subtype
 		case NPCTYPE_ITEMSHOP:
 			if (item->bound && battle_config.allow_bound_sell&ISR_BOUND && (
 				item->bound != BOUND_GUILD ||
-				(sd->guild && sd->status.char_id == sd->guild->member[0].char_id) ||
+				(sd->guild && sd->status.char_id == sd->guild->guild.member[0].char_id) ||
 				(item->bound == BOUND_GUILD && !(battle_config.allow_bound_sell&ISR_BOUND_GUILDLEADER_ONLY))
 				))
 				return true;
@@ -7161,10 +7161,8 @@ uint8 pc_checkskill(map_session_data *sd, uint16 skill_id)
 		return 0;
 	}
 	if (SKILL_CHK_GUILD(skill_id) ) {
-		struct guild *g;
-
-		if( sd->status.guild_id>0 && (g=sd->guild)!=NULL)
-			return guild_checkskill(g,skill_id);
+		if (sd->status.guild_id>0 && sd->guild)
+			return guild_checkskill(sd->guild->guild,skill_id);
 		return 0;
 	}
 	return (sd->status.skill[idx].id == skill_id) ? sd->status.skill[idx].lv : 0;
@@ -9954,11 +9952,11 @@ void pc_revive(map_session_data *sd,unsigned int hp, unsigned int sp, unsigned i
 	if(battle_config.pc_invincible_time > 0)
 		pc_setinvincibletimer(sd, battle_config.pc_invincible_time);
 
-	if( sd->state.gmaster_flag ) {
-		guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->guild,GD_LEADERSHIP));
-		guild_guildaura_refresh(sd,GD_GLORYWOUNDS,guild_checkskill(sd->guild,GD_GLORYWOUNDS));
-		guild_guildaura_refresh(sd,GD_SOULCOLD,guild_checkskill(sd->guild,GD_SOULCOLD));
-		guild_guildaura_refresh(sd,GD_HAWKEYES,guild_checkskill(sd->guild,GD_HAWKEYES));
+	if (sd->state.gmaster_flag && sd->guild) {
+		guild_guildaura_refresh(sd,GD_LEADERSHIP,guild_checkskill(sd->guild->guild,GD_LEADERSHIP));
+		guild_guildaura_refresh(sd,GD_GLORYWOUNDS,guild_checkskill(sd->guild->guild,GD_GLORYWOUNDS));
+		guild_guildaura_refresh(sd,GD_SOULCOLD,guild_checkskill(sd->guild->guild,GD_SOULCOLD));
+		guild_guildaura_refresh(sd,GD_HAWKEYES,guild_checkskill(sd->guild->guild,GD_HAWKEYES));
 	}
 }
 

+ 3 - 1
src/map/pc.hpp

@@ -33,6 +33,8 @@ enum e_instance_mode : uint8;
 enum e_log_pick_type : uint32;
 enum sc_type : int16;
 
+class MapGuild;
+
 #define MAX_PC_BONUS 50 /// Max bonus, usually used by item bonus
 #define MAX_PC_FEELHATE 3 /// Max feel hate info
 #define DAMAGELOG_SIZE_PC 100	/// Damage log
@@ -716,7 +718,7 @@ public:
 	int party_invite, party_invite_account; // for handling party invitation (holds party id and account id)
 	int adopt_invite; // Adoption
 
-	struct guild *guild; // [Ind] speed everything up
+	std::shared_ptr<MapGuild> guild; // [Ind] speed everything up
 	int guild_invite,guild_invite_account;
 	int guild_emblem_id,guild_alliance,guild_alliance_account;
 	short guild_x,guild_y; // For guildmate position display. [Skotlex] should be short [zzo]

+ 44 - 52
src/map/script.cpp

@@ -5916,7 +5916,6 @@ BUILDIN_FUNC(warpguild)
 {
 	TBL_PC *sd = NULL;
 	TBL_PC *pl_sd;
-	struct guild* g;
 	struct s_mapiterator* iter;
 	int type, mapindex = 0, m = -1;
 
@@ -5925,7 +5924,7 @@ BUILDIN_FUNC(warpguild)
 	int y           = script_getnum(st,4);
 	int gid         = script_getnum(st,5);
 
-	g = guild_search(gid);
+	auto g = guild_search(gid);
 	if( g == NULL )
 		return SCRIPT_CMD_SUCCESS;
 
@@ -9005,11 +9004,11 @@ BUILDIN_FUNC(getpartyleader)
 BUILDIN_FUNC(getguildname)
 {
 	int guild_id;
-	struct guild* g;
 
 	guild_id = script_getnum(st,2);
-	if( ( g = guild_search(guild_id) ) != NULL )
-		script_pushstrcopy(st,g->name);
+	auto g = guild_search(guild_id);
+	if (g)
+		script_pushstrcopy(st,g->guild.name);
 	else 
 		script_pushconststr(st,"null");
 	return SCRIPT_CMD_SUCCESS;
@@ -9022,11 +9021,11 @@ BUILDIN_FUNC(getguildname)
 BUILDIN_FUNC(getguildmaster)
 {
 	int guild_id;
-	struct guild* g;
 
 	guild_id = script_getnum(st,2);
-	if( ( g = guild_search(guild_id) ) != NULL )
-		script_pushstrcopy(st,g->member[0].name);
+	auto g = guild_search(guild_id);
+	if (g)
+		script_pushstrcopy(st,g->guild.member[0].name);
 	else 
 		script_pushconststr(st,"null");
 	return SCRIPT_CMD_SUCCESS;
@@ -9035,11 +9034,11 @@ BUILDIN_FUNC(getguildmaster)
 BUILDIN_FUNC(getguildmasterid)
 {
 	int guild_id;
-	struct guild* g;
 
 	guild_id = script_getnum(st,2);
-	if( ( g = guild_search(guild_id) ) != NULL )
-		script_pushint(st,g->member[0].char_id);
+	auto g = guild_search(guild_id);
+	if (g)
+		script_pushint(st,g->guild.member[0].char_id);
 	else
 		script_pushint(st,0);
 	return SCRIPT_CMD_SUCCESS;
@@ -9059,7 +9058,6 @@ BUILDIN_FUNC(strcharinfo)
 {
 	TBL_PC *sd;
 	int num;
-	struct guild* g;
 	struct party_data* p;
 
 	if (!script_charid2sd(3,sd)) {
@@ -9080,8 +9078,8 @@ BUILDIN_FUNC(strcharinfo)
 			}
 			break;
 		case 2:
-			if( ( g = sd->guild ) != NULL ) {
-				script_pushstrcopy(st,g->name);
+			if (sd->guild) {
+				script_pushstrcopy(st,sd->guild->guild.name);
 			} else {
 				script_pushconststr(st,"");
 			}
@@ -10296,15 +10294,14 @@ BUILDIN_FUNC(getgdskilllv)
 {
 	int guild_id;
 	uint16 skill_id;
-	struct guild* g;
 
 	guild_id = script_getnum(st,2);
 	skill_id = ( script_isstring(st, 3) ? skill_name2id(script_getstr(st,3)) : script_getnum(st,3) );
-	g = guild_search(guild_id);
-	if( g == NULL )
+	auto g = guild_search(guild_id);
+	if (!g)
 		script_pushint(st, -1);
 	else
-		script_pushint(st, guild_checkskill(g,skill_id));
+		script_pushint(st, guild_checkskill(g->guild,skill_id));
 
 	return SCRIPT_CMD_SUCCESS;
 }
@@ -10878,9 +10875,9 @@ BUILDIN_FUNC(guild_has_permission){
 		return SCRIPT_CMD_SUCCESS;
 	}
 
-	int position = guild_getposition(sd);
+	int position = guild_getposition(*sd);
 	
-	if( position < 0 || ( sd->guild->position[position].mode&permission ) != permission ){
+	if( position < 0 || ( sd->guild->guild.position[position].mode&permission ) != permission ){
 		script_pushint( st, false );
 
 		return SCRIPT_CMD_SUCCESS;
@@ -11981,20 +11978,19 @@ BUILDIN_FUNC(getmapguildusers)
 	int16 m;
 	int gid;
 	int c=0;
-	struct guild *g = NULL;
 	str=script_getstr(st,2);
 	gid=script_getnum(st,3);
 	if ((m = map_mapname2mapid(str)) < 0) { // map id on this server (m == -1 if not in actual map-server)
 		script_pushint(st,-1);
 		return SCRIPT_CMD_SUCCESS;
 	}
-	g = guild_search(gid);
+	auto g = guild_search(gid);
 
 	if (g){
 		unsigned short i;
-		for(i = 0; i < g->max_member; i++)
+		for(i = 0; i < g->guild.max_member; i++)
 		{
-			if (g->member[i].sd && g->member[i].sd->bl.m == m)
+			if (g->guild.member[i].sd && g->guild.member[i].sd->bl.m == m)
 				c++;
 		}
 	}
@@ -14099,7 +14095,7 @@ BUILDIN_FUNC(failedremovecards) {
 BUILDIN_FUNC(mapwarp)	// Added by RoVeRT
 {
 	int x,y,m,check_val=0,check_ID=0,i=0;
-	struct guild *g = NULL;
+	std::shared_ptr<MapGuild> g;
 	struct party_data *p = NULL;
 	const char *str;
 	const char *mapname;
@@ -14123,10 +14119,10 @@ BUILDIN_FUNC(mapwarp)	// Added by RoVeRT
 		case 1:
 			g = guild_search(check_ID);
 			if (g){
-				for( i=0; i < g->max_member; i++)
+				for( i=0; i < g->guild.max_member; i++)
 				{
-					if(g->member[i].sd && g->member[i].sd->bl.m==m){
-						pc_setpos(g->member[i].sd,index,x,y,CLR_TELEPORT);
+					if(g->guild.member[i].sd && g->guild.member[i].sd->bl.m==m){
+						pc_setpos(g->guild.member[i].sd,index,x,y,CLR_TELEPORT);
 					}
 				}
 			}
@@ -15654,7 +15650,6 @@ BUILDIN_FUNC(recovery)
 		}
 		case 2:
 		{
-			struct guild* g;
 			//When no guild given, we use invoker guild
 			int g_id = 0, i;
 			if(script_hasdata(st,5)) {//Bad maps shouldn't cause issues
@@ -15668,12 +15663,12 @@ BUILDIN_FUNC(recovery)
 				g_id = script_getnum(st,3);
 			else if(script_rid2sd(sd))
 				g_id = sd->status.guild_id;
-			g = guild_search(g_id);
+			auto g = guild_search(g_id);
 			if(g == NULL)
 				return SCRIPT_CMD_SUCCESS;
 			for (i = 0; i < MAX_GUILD; i++) {
 				map_session_data* pl_sd;
-				if((!(pl_sd = g->member[i].sd) || pl_sd->status.guild_id != g_id)
+				if((!(pl_sd = g->guild.member[i].sd) || pl_sd->status.guild_id != g_id)
 					|| (map_idx && pl_sd->bl.m != map_idx))
 					continue;
 				recovery_sub(pl_sd, revive);
@@ -21331,7 +21326,7 @@ int script_instancegetid(struct script_state* st, e_instance_mode mode)
 				}
 					break;
 				case IM_GUILD: {
-					struct guild *gd = guild_search(sd->status.guild_id);
+					auto gd = guild_search(sd->status.guild_id);
 
 					if (gd && gd->instance_id > 0)
 						instance_id = gd->instance_id;
@@ -21735,7 +21730,6 @@ BUILDIN_FUNC(instance_check_party)
 BUILDIN_FUNC(instance_check_guild)
 {
 	int amount, min, max, i, guild_id = 0, c = 0;
-	struct guild *g = NULL;
 
 	amount = script_hasdata(st,3) ? script_getnum(st,3) : 1; // Amount of needed Guild members for the Instance.
 	min = script_hasdata(st,4) ? script_getnum(st,4) : 1; // Minimum Level needed to join the Instance.
@@ -21754,7 +21748,8 @@ BUILDIN_FUNC(instance_check_guild)
 	else
 		return SCRIPT_CMD_FAILURE;
 
-	if (!(g = guild_search(guild_id))) {
+	auto g = guild_search(guild_id);
+	if (!g) {
 		script_pushint(st, 0); // Returns false if guild does not exist.
 		return SCRIPT_CMD_FAILURE;
 	}
@@ -21762,7 +21757,7 @@ BUILDIN_FUNC(instance_check_guild)
 	for(i = 0; i < MAX_GUILD; i++) {
 		map_session_data *pl_sd;
 
-		if ((pl_sd = g->member[i].sd)) {
+		if ((pl_sd = g->guild.member[i].sd)) {
 			if (map_id2bl(pl_sd->bl.id) && !pl_sd->state.autotrade) {
 				if (pl_sd->status.base_level < min) {
 					script_pushint(st, 0);
@@ -23493,10 +23488,9 @@ BUILDIN_FUNC(disable_command) {
  */
 BUILDIN_FUNC(getguildmember)
 {
-	struct guild *g = NULL;
 	uint8 j = 0;
 
-	g = guild_search(script_getnum(st,2));
+	auto g = guild_search(script_getnum(st,2));
 
 	if (g) {
 		uint8 i, type = 0;
@@ -23528,25 +23522,25 @@ BUILDIN_FUNC(getguildmember)
 		}
 
 		for (i = 0; i < MAX_GUILD; i++) {
-			if (g->member[i].account_id) {
+			if (g->guild.member[i].account_id) {
 				switch (type) {
 					case 2:
 						if (data)
-							setd_sub_num( st, NULL, varname, j, g->member[i].account_id, data->ref );
+							setd_sub_num( st, NULL, varname, j, g->guild.member[i].account_id, data->ref );
 						else
-							mapreg_setreg(reference_uid(add_str("$@guildmemberaid"), j),g->member[i].account_id);
+							mapreg_setreg(reference_uid(add_str("$@guildmemberaid"), j),g->guild.member[i].account_id);
 						break;
 					case 1:
 						if (data)
-							setd_sub_num( st, NULL, varname, j, g->member[i].char_id, data->ref );
+							setd_sub_num( st, NULL, varname, j, g->guild.member[i].char_id, data->ref );
 						else
-							mapreg_setreg(reference_uid(add_str("$@guildmembercid"), j), g->member[i].char_id);
+							mapreg_setreg(reference_uid(add_str("$@guildmembercid"), j), g->guild.member[i].char_id);
 						break;
 					default:
 						if (data)
-							setd_sub_str( st, NULL, varname, j, g->member[i].name, data->ref );
+							setd_sub_str( st, NULL, varname, j, g->guild.member[i].name, data->ref );
 						else
-							mapreg_setregstr(reference_uid(add_str("$@guildmembername$"), j), g->member[i].name);
+							mapreg_setregstr(reference_uid(add_str("$@guildmembername$"), j), g->guild.member[i].name);
 						break;
 				}
 				j++;
@@ -24533,7 +24527,6 @@ BUILDIN_FUNC(jobcanentermap) {
  */
 BUILDIN_FUNC(getguildalliance)
 {
-	struct guild *guild_data1, *guild_data2;
 	int guild_id1, guild_id2, i = 0;
 
 	guild_id1 = script_getnum(st,2);
@@ -24549,8 +24542,8 @@ BUILDIN_FUNC(getguildalliance)
 		return SCRIPT_CMD_SUCCESS;
 	}
 
-	guild_data1 = guild_search(guild_id1);
-	guild_data2 = guild_search(guild_id2);
+	auto guild_data1 = guild_search(guild_id1);
+	auto guild_data2 = guild_search(guild_id2);
 
 	if (guild_data1 == NULL) {
 		ShowWarning("buildin_getguildalliance: Requesting non-existent GuildID1 '%d'.\n", guild_id1);
@@ -24563,13 +24556,13 @@ BUILDIN_FUNC(getguildalliance)
 		return SCRIPT_CMD_FAILURE;
 	}
 
-	ARR_FIND(0, MAX_GUILDALLIANCE, i, guild_data1->alliance[i].guild_id == guild_id2);
+	ARR_FIND(0, MAX_GUILDALLIANCE, i, guild_data1->guild.alliance[i].guild_id == guild_id2);
 	if (i == MAX_GUILDALLIANCE) {
 		script_pushint(st, 0);
 		return SCRIPT_CMD_SUCCESS;
 	}
 
-	if (guild_data1->alliance[i].opposition)
+	if (guild_data1->guild.alliance[i].opposition)
 		script_pushint(st, 2);
 	else
 		script_pushint(st, 1);
@@ -25929,7 +25922,6 @@ BUILDIN_FUNC(identifyall) {
 BUILDIN_FUNC(is_guild_leader)
 {
 	map_session_data* sd;
-	struct guild* guild_data;
 	int guild_id;
 
 	if (!script_rid2sd(sd)) {
@@ -25942,9 +25934,9 @@ BUILDIN_FUNC(is_guild_leader)
 	else
 		guild_id = sd->status.guild_id;
 
-	guild_data = guild_search(guild_id);
+	auto guild_data = guild_search(guild_id);
 	if (guild_data)
-		script_pushint(st, (guild_data->member[0].char_id == sd->status.char_id));
+		script_pushint(st, (guild_data->guild.member[0].char_id == sd->status.char_id));
 	else
 		script_pushint(st, false);
 	return SCRIPT_CMD_SUCCESS;

+ 37 - 32
src/map/skill.cpp

@@ -888,6 +888,9 @@ bool skill_isNotOk(uint16 skill_id, map_session_data *sd)
 		case ALL_GUARDIAN_RECALL:
 		case ECLAGE_RECALL:
 		case ALL_PRONTERA_RECALL:
+		case ALL_GLASTHEIM_RECALL:
+		case ALL_THANATOS_RECALL:
+		case ALL_LIGHTHALZEN_RECALL:
 			if(mapdata->getMapFlag(MF_NOWARP)) {
 				clif_skill_teleportmessage(sd,0);
 				return true;
@@ -10362,9 +10365,8 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 			int8 dx[9] = {-1, 1, 0, 0,-1, 1,-1, 1, 0};
 			int8 dy[9] = { 0, 0, 1,-1, 1,-1,-1, 1, 0};
 			uint8 j = 0, calls = 0, called = 0;
-			struct guild *g;
 			// i don't know if it actually summons in a circle, but oh well. ;P
-			g = sd?sd->guild:guild_search(status_get_guild_id(src));
+			auto g = sd?sd->guild:guild_search(status_get_guild_id(src));
 			if (!g)
 				break;
 
@@ -10377,10 +10379,10 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 				}
 
 			clif_skill_nodamage(src,bl,skill_id,skill_lv,1);
-			for (i = 0; i < g->max_member && (!calls || (calls && called < calls)); i++, j++) {
+			for (i = 0; i < g->guild.max_member && (!calls || (calls && called < calls)); i++, j++) {
 				if (j > 8)
 					j = 0;
-				if ((dstsd = g->member[i].sd) != NULL && sd != dstsd && !dstsd->state.autotrade && !pc_isdead(dstsd)) {
+				if ((dstsd = g->guild.member[i].sd) != NULL && sd != dstsd && !dstsd->state.autotrade && !pc_isdead(dstsd)) {
 					if (map_getmapflag(dstsd->bl.m, MF_NOWARP) && !map_flag_gvg2(dstsd->bl.m))
 						continue;
 					if (!pc_job_can_entermap((enum e_job)dstsd->status.class_, src->m, pc_get_group_level(dstsd)))
@@ -10401,7 +10403,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 		break;
 	case GD_CHARGESHOUT_FLAG:
 		if (sd && sd->guild && sd->state.gmaster_flag == 1) {
-			mob_data *md = mob_once_spawn_sub(src, src->m, src->x, src->y, sd->guild->name, MOBID_GUILD_SKILL_FLAG, nullptr, SZ_SMALL, AI_GUILD);
+			mob_data *md = mob_once_spawn_sub(src, src->m, src->x, src->y, sd->guild->guild.name, MOBID_GUILD_SKILL_FLAG, nullptr, SZ_SMALL, AI_GUILD);
 
 			if (md) {
 				sd->guild->chargeshout_flag_id = md->bl.id;
@@ -11649,6 +11651,9 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 	case ALL_GUARDIAN_RECALL:
 	case ECLAGE_RECALL:
 	case ALL_PRONTERA_RECALL:
+	case ALL_GLASTHEIM_RECALL:
+	case ALL_THANATOS_RECALL:
+	case ALL_LIGHTHALZEN_RECALL:
 		if( sd )
 		{
 			short x=0, y=0; // Destiny position.
@@ -11682,6 +11687,21 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
 				}
 				mapindex  = mapindex_name2id(MAP_PRONTERA);
 				break;
+			case ALL_GLASTHEIM_RECALL:
+				x = 200;
+				y = 268;
+				mapindex  = mapindex_name2id(MAP_GLASTHEIM);
+				break;
+			case ALL_THANATOS_RECALL:
+				x = 139;
+				y = 156;
+				mapindex  = mapindex_name2id(MAP_THANATOS);
+				break;
+			case ALL_LIGHTHALZEN_RECALL:
+				x = 307;
+				y = 307;
+				mapindex  = mapindex_name2id(MAP_LIGHTHALZEN);
+				break;
 			}
 
 			if(!mapindex)
@@ -21133,7 +21153,8 @@ TIMER_FUNC(skill_unit_timer){
 	return 0;
 }
 
-static int skill_unit_temp[20];  // temporary storage for tracking skill unit skill ids as players move in/out of them
+static std::vector<int16> skill_unit_cell; // Temporary storage for tracking skill unit skill IDs as players move in/out of them
+
 /*==========================================
  * flag :
  *	1 : store that skill_unit in array
@@ -21143,13 +21164,11 @@ static int skill_unit_temp[20];  // temporary storage for tracking skill unit sk
 int skill_unit_move_sub(struct block_list* bl, va_list ap)
 {
 	struct skill_unit* unit = (struct skill_unit *)bl;
-
 	struct block_list* target = va_arg(ap,struct block_list*);
 	t_tick tick = va_arg(ap,t_tick);
 	int flag = va_arg(ap,int);
 	bool dissonance;
 	uint16 skill_id;
-	int i;
 
 	nullpo_ret(unit);
 	nullpo_ret(target);
@@ -21184,17 +21203,11 @@ int skill_unit_move_sub(struct block_list* bl, va_list ap)
 		if( group->src_id == target->id && group->state.song_dance&0x2 ) { //Ensemble check to see if they went out/in of the area [Skotlex]
 			if( flag&1 ) {
 				if( flag&2 ) { //Clear this skill id.
-					ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == skill_id );
-					if( i < ARRAYLENGTH(skill_unit_temp) )
-						skill_unit_temp[i] = 0;
+					util::vector_erase_if_exists(skill_unit_cell, skill_id);
 				}
 			} else {
 				if( flag&2 ) { //Store this skill id.
-					ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == 0 );
-					if( i < ARRAYLENGTH(skill_unit_temp) )
-						skill_unit_temp[i] = skill_id;
-					else
-						ShowError("skill_unit_move_sub: Reached limit of unit objects per cell! (skill_id: %hu)\n", skill_id );
+					skill_unit_cell.push_back(skill_id);
 				}
 			}
 
@@ -21210,20 +21223,14 @@ int skill_unit_move_sub(struct block_list* bl, va_list ap)
 		if( flag&1 ) {
 			int result = skill_unit_onplace(unit,target,tick);
 
-			if( flag&2 && result ) { //Clear skill ids we have stored in onout.
-				ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == result );
-				if( i < ARRAYLENGTH(skill_unit_temp) )
-					skill_unit_temp[i] = 0;
+			if( flag&2 && result > 0 ) { //Clear skill ids we have stored in onout.
+				util::vector_erase_if_exists(skill_unit_cell, result);
 			}
 		} else {
 			int result = skill_unit_onout(unit,target,tick);
 
-			if( flag&2 && result ) { //Store this unit id.
-				ARR_FIND( 0, ARRAYLENGTH(skill_unit_temp), i, skill_unit_temp[i] == 0 );
-				if( i < ARRAYLENGTH(skill_unit_temp) )
-					skill_unit_temp[i] = skill_id;
-				else
-					ShowError("skill_unit_move_sub: Reached limit of unit objects per cell! (skill_id: %hu)\n", skill_id );
+			if( flag&2 && result > 0 ) { //Store this unit id.
+				skill_unit_cell.push_back(skill_id);
 			}
 		}
 
@@ -21256,16 +21263,14 @@ int skill_unit_move(struct block_list *bl, t_tick tick, int flag)
 		return 0;
 
 	if( flag&2 && !(flag&1) ) //Onout, clear data
-		memset(skill_unit_temp, 0, sizeof(skill_unit_temp));
+		skill_unit_cell.clear();
 
 	map_foreachincell(skill_unit_move_sub,bl->m,bl->x,bl->y,BL_SKILL,bl,tick,flag);
 
 	if( flag&2 && flag&1 ) { //Onplace, check any skill units you have left.
-		int i;
-
-		for( i = 0; i < ARRAYLENGTH(skill_unit_temp); i++ )
-			if( skill_unit_temp[i] )
-				skill_unit_onleft(skill_unit_temp[i], bl, tick);
+		for (const auto &it : skill_unit_cell) {
+			skill_unit_onleft(it, bl, tick);
+		}
 	}
 
 	return 0;

+ 3 - 0
src/map/skill.hpp

@@ -1941,6 +1941,9 @@ enum e_skill {
 	ECLAGE_RECALL,
 
 	ALL_PRONTERA_RECALL = 3042,
+	ALL_GLASTHEIM_RECALL,
+	ALL_THANATOS_RECALL,
+	ALL_LIGHTHALZEN_RECALL,
 
 	GC_DARKCROW = 5001,
 	RA_UNLIMIT,

+ 2 - 2
src/map/status.cpp

@@ -9089,9 +9089,9 @@ int status_get_emblem_id(struct block_list *bl)
 			break;
 		case BL_NPC:
 			if (((TBL_NPC*)bl)->subtype == NPCTYPE_SCRIPT && ((TBL_NPC*)bl)->u.scr.guild_id > 0) {
-				struct guild *g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
+				auto g = guild_search(((TBL_NPC*)bl)->u.scr.guild_id);
 				if (g)
-					return g->emblem_id;
+					return g->guild.emblem_id;
 			}
 			break;
 		case BL_ELEM:

+ 3 - 3
src/map/storage.cpp

@@ -561,7 +561,7 @@ char storage_guild_storageopen(map_session_data* sd)
 		return GSTORAGE_NO_GUILD;
 
 #ifdef OFFICIAL_GUILD_STORAGE
-	if (!guild_checkskill(sd->guild, GD_GUILD_STORAGE))
+	if (!guild_checkskill(sd->guild->guild, GD_GUILD_STORAGE))
 		return GSTORAGE_NO_STORAGE; // Can't open storage if the guild has not learned the skill
 #endif
 
@@ -573,7 +573,7 @@ char storage_guild_storageopen(map_session_data* sd)
 #if PACKETVER >= 20140205
 	int pos;
 
-	if ((pos = guild_getposition(sd)) < 0 || !(sd->guild->position[pos].mode&GUILD_PERM_STORAGE))
+	if ((pos = guild_getposition(*sd)) < 0 || !(sd->guild->guild.position[pos].mode&GUILD_PERM_STORAGE))
 		return GSTORAGE_NO_PERMISSION; // Guild member doesn't have permission
 #endif
 
@@ -584,7 +584,7 @@ char storage_guild_storageopen(map_session_data* sd)
 
 	if((gstor = guild2storage2(sd->status.guild_id)) == nullptr
 #ifdef OFFICIAL_GUILD_STORAGE
-		|| (gstor->max_amount != guild_checkskill(sd->guild, GD_GUILD_STORAGE) * 100)
+		|| (gstor->max_amount != guild_checkskill(sd->guild->guild, GD_GUILD_STORAGE) * 100)
 #endif
 	) {
 		intif_request_guild_storage(sd->status.account_id,sd->status.guild_id);

+ 4 - 4
src/tool/csv2yaml.vcxproj

@@ -115,7 +115,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -131,7 +131,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -150,7 +150,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -171,7 +171,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 4 - 4
src/tool/mapcache.vcxproj

@@ -95,7 +95,7 @@
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -112,7 +112,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -131,7 +131,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -152,7 +152,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 4 - 4
src/tool/yaml2sql.vcxproj

@@ -96,7 +96,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -112,7 +112,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -131,7 +131,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -152,7 +152,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 4 - 4
src/tool/yamlupgrade.vcxproj

@@ -96,7 +96,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -112,7 +112,7 @@
       <Optimization>Disabled</Optimization>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -131,7 +131,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>
@@ -152,7 +152,7 @@
       <IntrinsicFunctions>true</IntrinsicFunctions>
       <PreprocessorDefinitions>$(DefineConstants);WIN32;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;MINICORE;NDEBUG;_CONSOLE;_LIB;%(PreprocessorDefinitions)</PreprocessorDefinitions>
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\yaml-cpp\include\;$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
     </ClCompile>
     <Link>

+ 4 - 4
src/web/web-server.vcxproj

@@ -98,7 +98,7 @@
       <DisableSpecificWarnings>4018;4200</DisableSpecificWarnings>
       <MultiProcessorCompilation>true</MultiProcessorCompilation>
       <ConformanceMode>true</ConformanceMode>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -116,7 +116,7 @@
       <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\httplib\;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\json\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -136,7 +136,7 @@
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\httplib\;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\json\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>
@@ -158,7 +158,7 @@
       <RuntimeLibrary>MultiThreaded</RuntimeLibrary>
       <AdditionalIncludeDirectories>$(SolutionDir)src;$(SolutionDir)3rdparty\httplib\;$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;$(SolutionDir)\3rdparty\json\include;$(SolutionDir)3rdparty\libconfig\;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
       <DisableSpecificWarnings>4018</DisableSpecificWarnings>
-      <LanguageStandard>stdcpp14</LanguageStandard>
+      <LanguageStandard>stdcpp17</LanguageStandard>
     </ClCompile>
     <Link>
       <SubSystem>Console</SubSystem>

部分文件因文件數量過多而無法顯示