summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.travis.yml16
-rw-r--r--CHANGELOG.md49
-rw-r--r--README.md77
-rw-r--r--conf/map/script.conf2
-rwxr-xr-xconfigure2
-rw-r--r--db/constants.conf2
-rw-r--r--db/pre-re/mob_skill_db.conf6
-rw-r--r--db/re/item_db.conf48
-rw-r--r--doc/constants.md17
-rw-r--r--doc/permissions.md1
-rw-r--r--doc/script_commands.txt121
-rw-r--r--mariadb.bat15
-rw-r--r--npc/custom/events/mushroom_event.txt2
-rw-r--r--npc/custom/stylist.txt78
-rw-r--r--npc/jobs/1-1e/ninja.txt78
-rw-r--r--npc/other/inventory_expansion.txt18
-rw-r--r--npc/quests/quests_nameless.txt23
-rw-r--r--npc/quests/quests_prontera.txt24
-rw-r--r--npc/re/instances/ghost_palace.txt2
-rw-r--r--npc/re/jobs/2e/kagerou_oboro.txt440
-rw-r--r--npc/re/merchants/enchan_mora.txt12
-rw-r--r--npc/re/merchants/renters.txt111
-rw-r--r--sql-files/item_db_re.sql6
-rw-r--r--sql-files/main.sql2
-rw-r--r--sql-files/mob_skill_db.sql6
-rw-r--r--sql-files/upgrades/2019-05-09--18-07.sql22
-rw-r--r--sql-files/upgrades/index.txt1
-rw-r--r--src/char/char.c23
-rw-r--r--src/common/HPMDataCheck.h7
-rw-r--r--src/common/mmo.h38
-rw-r--r--src/common/packets/packets2019_len_main.h103
-rw-r--r--src/common/packets/packets2019_len_re.h109
-rw-r--r--src/common/packets/packets2019_len_zero.h86
-rw-r--r--src/map/atcommand.c15
-rw-r--r--src/map/clif.c256
-rw-r--r--src/map/clif.h9
-rw-r--r--src/map/instance.c9
-rw-r--r--src/map/itemdb.c3
-rw-r--r--src/map/itemdb.h3
-rw-r--r--src/map/map.c179
-rw-r--r--src/map/map.h43
-rw-r--r--src/map/messages_main.h123
-rw-r--r--src/map/messages_re.h123
-rw-r--r--src/map/messages_zero.h45
-rw-r--r--src/map/mob.c3
-rw-r--r--src/map/npc.c33
-rw-r--r--src/map/npc.h2
-rw-r--r--src/map/packets.h16
-rw-r--r--src/map/packets_keys_main.h12
-rw-r--r--src/map/packets_keys_zero.h10
-rw-r--r--src/map/packets_shuffle_main.h11
-rw-r--r--src/map/packets_shuffle_re.h11
-rw-r--r--src/map/packets_shuffle_zero.h10
-rw-r--r--src/map/packets_struct.h134
-rw-r--r--src/map/pc.c7
-rw-r--r--src/map/pc.h3
-rw-r--r--src/map/pc_groups.c1
-rw-r--r--src/map/pc_groups.h1
-rw-r--r--src/map/quest.c42
-rw-r--r--src/map/quest.h34
-rw-r--r--src/map/refine.c2
-rw-r--r--src/map/script.c408
-rw-r--r--src/map/script.h4
-rw-r--r--src/map/status.h5
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc26
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc36
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc9
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc189
-rw-r--r--tools/install_mariadb.bat7
-rw-r--r--tools/setup_mariadb.ps190
70 files changed, 2506 insertions, 955 deletions
diff --git a/.travis.yml b/.travis.yml
index cbf4f164c..4197fe4f2 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -39,7 +39,7 @@ matrix:
- compiler: false
include:
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20190418 --enable-packetver-re --enable-buildbot" HPM="1"
+ env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20190619 --enable-packetver-re --enable-buildbot" HPM="1"
addons:
apt:
sources:
@@ -52,7 +52,7 @@ matrix:
- libxml-sax-perl
- libxml-parser-perl
- compiler: clang
- env: CONFIGURE_FLAGS="--enable-debug CC=clang-5.0 --enable-Werror --enable-packetver=20190418 --enable-packetver-re --enable-buildbot"
+ env: CONFIGURE_FLAGS="--enable-debug CC=clang-5.0 --enable-Werror --enable-packetver=20190619 --enable-packetver-re --enable-buildbot"
addons:
apt:
sources:
@@ -72,7 +72,7 @@ matrix:
- gdb
- clang-5.0
- compiler: clang
- env: CONFIGURE_FLAGS="--enable-debug CC=clang-4.0 --enable-Werror --enable-packetver=20190418 --enable-packetver-re --enable-buildbot"
+ env: CONFIGURE_FLAGS="--enable-debug CC=clang-4.0 --enable-Werror --enable-packetver=20190619 --enable-packetver-re --enable-buildbot"
addons:
apt:
sources:
@@ -106,11 +106,11 @@ matrix:
- compiler: clang
env: CONFIGURE_FLAGS="--enable-debug --disable-renewal --enable-Werror --enable-buildbot"
- compiler: gcc
- env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20190418 --enable-packetver-re --enable-buildbot"
+ env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20190619 --enable-packetver-re --enable-buildbot"
- compiler: gcc
env: CONFIGURE_FLAGS="--enable-debug --disable-renewal --enable-Werror --enable-buildbot"
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-5 --disable-manager --enable-Werror --enable-packetver=20190418 --enable-packetver-re --enable-buildbot"
+ env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-5 --disable-manager --enable-Werror --enable-packetver=20190619 --enable-packetver-re --enable-buildbot"
addons:
apt:
sources:
@@ -128,7 +128,7 @@ matrix:
- gdb
- gcc-5
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20190418 --enable-packetver-re --enable-buildbot"
+ env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20190619 --enable-packetver-re --enable-buildbot"
addons:
apt:
sources:
@@ -146,7 +146,7 @@ matrix:
- gdb
- gcc-6
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-7 --disable-manager --enable-Werror --enable-packetver=20190418 --enable-packetver-re --enable-buildbot"
+ env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-7 --disable-manager --enable-Werror --enable-packetver=20190619 --enable-packetver-re --enable-buildbot"
addons:
apt:
sources:
@@ -164,7 +164,7 @@ matrix:
- gdb
- gcc-7
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-8 --disable-manager --enable-Werror --enable-packetver=20190418 --enable-packetver-re --enable-buildbot"
+ env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-8 --disable-manager --enable-Werror --enable-packetver=20190619 --enable-packetver-re --enable-buildbot"
addons:
apt:
sources:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index fccc2e5b1..77ed1d1f0 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -9,6 +9,53 @@ and this project does not adhere to [Semantic Versioning](http://semver.org/spec
If you are reading this in a text editor, simply ignore this section
-->
+### [v2019.06.02] `June 2 2019`
+
+### Added
+
+- Added Stat Reduction Potions to the Renewal item DB. (#2483)
+- Added the constant `MAX_NPC_PER_MAP` to the script engine. (part of #2474)
+- Added the `cap_value()` script command, to cap a value between a minimum and maximum. (#2472)
+- Added the `mesclear()` script command, to clean an NPC message dialog without user interaction. (#2471)
+- Added a script for simplified installation on Windows development machines. (#2222)
+- Added/updated packets, encryption keys and message tables for clients up to 2019-05-30. (#2468, #2490)
+- Added support for multiple hotkeys sets (two 'tabs' on the RE clients). The constant `MAX_HOTKEYS_DB` represents the maximum amount of hotkeys saved to the database. This requires a database migration. (part of #2468)
+- Added the `delitemidx()` script command, to delete an item by its inventory index. (#2394)
+- Added the `getguildonline()` script command, to return the amount of online guild members. (#2290)
+- Added the `nostorage` and `nogstorage` mapflags, disallowing storage usage on the affected maps. The `bypass_nostorage` permission is also provided, to bypass those mapflags. (#2221)
+
+### Changed
+
+- Moved the questinfo data from map to npc data, allowing the use of multiple `questinfo()` blocks. (#2433, issue #2431)
+- Removed code duplication from the map data cleanup functions. (part of #2433)
+- Allow to read negative values from `input()`. The minimum value is still set to 0 in the default configuration, but it can be overridden globally by editing `input_min_value` or locally by specifying the `min` and `max` arguments to `input()`. (#2375)
+- Extended the `getmapinfo()` command to return the total number of NPCs in a map (`MAPINFO_NPC_COUNT`). (#2474)
+- Updated the pre-renewal Byorgue summon slave delay to match the official value, increased before renewal to prevent farming exploits. (#2456)
+- Changed the `"all"` special value used by `killmonster()` to be lowercase and case sensitive, for consistency with other script commands. (#2380)
+- Updated and simplified the Windows installation instructions. (part of #2222)
+- Updated some NPC/name translations to match the official ones or the official intent. Cougar -> Kuuga Gai, Gaebolg -> Geoborg, Family -> Clan, Magic Gear -> Mado Gear (#2457)
+- Updated the Mado Gear rental NPC to sell Mado Gear Box and Cooling Device. (part of #2457)
+- Changed the `expandinventoryack()`, `expandinventoryresult()`, `expandinventory()` and `getinventorysize()` script commands to be lowercase, for consistency. (#2374)
+
+### Fixed
+
+- Fixed the `failedremovecards()` command, to only remove the carts when `type` is set to 1, as described in its documentation. (#2477, issue #2469)
+- Fixed a crash when using `npcspeed()`, `npcwalkto()`, `npcstop()`, `unitwalk()`, `unitwarp()`, `unitstop()` on a floating NPC without a sprite. (#2430)
+- Fixed a stats calculation regression. (#2482)
+- Fixed a version check for the `ZC_PING` packet. (part of #2468)
+- Fixed errors caused by missing Option DB and Option Drop Groups DB data when the map server loads the mob database in minimal mode. (#2486, related to issue #2484)
+
+### Deprecated
+
+- Deprecated use of `"All"` with `killmonster()`. Use `"all"` instead. (part of #2380)
+- Deprecated the mixed case version of the `expandInventoryAck()`, `expandInventoryResult()`, `expandInventory()` and `getInventorySize()` script commands. Use the lowercase variants instead. (part of #2374)
+
+## [v2019.05.05+4] `May 5 2019` `PATCH 4`
+
+### Fixed
+
+- Fixed a reading error in refine database caused refine chances to be incorrectly read. (#2481)
+
## [v2019.05.05+3] `May 5 2019` `PATCH 3`
### Fixed
@@ -762,6 +809,8 @@ If you are reading this in a text editor, simply ignore this section
- New versioning scheme and project changelogs/release notes (#1853)
[Unreleased]: https://github.com/HerculesWS/Hercules/compare/stable...master
+[v2019.06.02]: https://github.com/HerculesWS/Hercules/compare/v2019.05.05+4...v2019.06.02
+[v2019.05.05+4]: https://github.com/HerculesWS/Hercules/compare/v2019.05.05+3...v2019.05.05+4
[v2019.05.05+3]: https://github.com/HerculesWS/Hercules/compare/v2019.05.05+2...v2019.05.05+3
[v2019.05.05+2]: https://github.com/HerculesWS/Hercules/compare/v2019.05.05+1...v2019.05.05+2
[v2019.05.05+1]: https://github.com/HerculesWS/Hercules/compare/v2019.05.05...v2019.05.05+1
diff --git a/README.md b/README.md
index b17eedbda..0b4257b3b 100644
--- a/README.md
+++ b/README.md
@@ -52,14 +52,11 @@ Before installing Hercules, you will need to install certain tools and applicati
This differs between the varying Operating Systems available, so the
following list is broken down into Windows and Unix (incl. Linux) prerequisites.
-For a list of supported platforms, please refer to the [Supported
-Platforms](https://github.com/HerculesWS/Hercules/wiki/Supported-Platforms) wiki page.
+For a list of supported platforms, please refer to the [Supported Platforms](https://github.com/HerculesWS/Hercules/wiki/Supported-Platforms) wiki page.
#### Windows
- - Git client
- - MySQL-compatible server ([MySQL Community Edition](https://www.mysql.com/products/community/) or
- [MariaDB](https://mariadb.org/))
- - Microsoft Visual Studio ([Version 2012 through 2015](https://www.visualstudio.com/))
+ - [Git client](https://git-scm.com/)
+ - [Microsoft Visual Studio Community](https://visualstudio.microsoft.com/vs/community/)
#### Unix/Linux/BSD (names of packages may require specific version numbers on certain distributions)
- git
@@ -85,10 +82,20 @@ Platforms](https://github.com/HerculesWS/Hercules/wiki/Supported-Platforms) wiki
- MySQL GUI clients
- [MySQL Workbench](http://www.mysql.com/downloads/workbench/) (cross-platform)
- [HeidiSQL](http://www.heidisql.com/) (Windows)
+ - [DBeaver](http://dbeaver.jkiss.org/) (cross-platform)
- [Sequel Pro](http://www.sequelpro.com/) (Mac OS X)
+ - *More options available at [mariadb.com](https://mariadb.com/kb/en/library/graphical-and-enhanced-clients/)*
- GUI Git clients
+ - [GitHub Desktop](https://desktop.github.com/) (cross-platform)
+ - [GitKraken](https://www.gitkraken.com/git-client) (cross-platform)
+ - [SmartGit](https://www.syntevo.com/smartgit/) (cross-platform)
- [Atlassian SourceTree](https://www.sourcetreeapp.com/) (Windows, Mac OS X)
- - [TortoiseGit](https://tortoisegit.org/) (Windows)
+ - *More options available at [git-scm.com](https://git-scm.com/downloads/guis)*
+ - Text editors with syntax highlighting
+ - [Visual Studio Code](https://code.visualstudio.com) (cross-platform)
+ - [Atom](https://atom.io) (cross-platform)
+ - [Notepad++](https://notepad-plus-plus.org) (Windows)
+ - *More options available at [wikipedia.org](https://en.wikipedia.org/wiki/Comparison_of_text_editors#Overview)*
## Installation
@@ -99,39 +106,49 @@ guides relevant to your Operation System, please refer to the Wiki (links at
the end of this file).
#### Windows
+##### Easy installation
1. Install the prerequisites.
- 2. Clone the Hercules repository (see [GitHub](https://github.com/HerculesWS/Hercules)) using a git client, into a new
+ 2. Clone the [Hercules repository](https://github.com/HerculesWS/Hercules) using a git client, into a new
folder.
- 3. Connect to the MySQL server as root:
- - Create a database (hercules): `CREATE DATABASE hercules;`
- - Create a user (hercules): `CREATE USER 'hercules'@'localhost' IDENTIFIED BY 'password';`.
- - Give permissions (GRANT SELECT,INSERT,UPDATE,DELETE) to the user: `GRANT SELECT,INSERT,UPDATE,DELETE ON hercules.* TO 'hercules'@'localhost';`
- 4. Connect to the MySQL server as the new user:
- - Import the .sql files in /sql-files/ into the new database.
- 5. Start Visual Studio and load the provided solution:
- - Compile and run the three projects, login-server, char-server, map-server.
+ - If you do not want to use the command line, you can instead clone with [GitHub Desktop](https://desktop.github.com/).
+ 3. Run `mariadb.bat` to automatically install and configure MariaDB.
+ 4. Start Visual Studio and load the provided solution:
+ - Compile and run the three projects, login-server, char-server, map-server.
+##### Manual installation
+ 1. Install the prerequisites.
+ 2. Install a MySQL-compatible server, such as [MariaDB](https://mariadb.org/) (recommended) or [MySQL Community Edition](https://www.mysql.com/products/community/)
+ 3. Clone the Hercules repository [Hercules repository](https://github.com/HerculesWS/Hercules) using a git client, into a new
+ folder.
+ 4. Connect to the MySQL server as root:
+ - Create a database (hercules): `CREATE DATABASE hercules;`
+ - Create a user (hercules): `CREATE USER 'hercules'@'localhost' IDENTIFIED BY 'password';`.
+ - Give permissions (GRANT SELECT,INSERT,UPDATE,DELETE) to the user: `GRANT SELECT,INSERT,UPDATE,DELETE ON hercules.* TO 'hercules'@'localhost';`
+ 5. Connect to the MySQL server as the new user:
+ - Import the .sql files in /sql-files/ into the new database.
+ 6. Start Visual Studio and load the provided solution:
+ - Compile and run the three projects, login-server, char-server, map-server.
#### Unix
1. Install the prerequisites through your distribution's package manager
- - (Red Hat compatible / CentOS) `yum install gcc make mysql mysql-devel mysql-server pcre-devel zlib-devel git`
- - (Debian compatible) `apt-get install gcc make libmysqlclient-dev zlib1g-dev libpcre3-dev mysql-server git`
- - (FreeBSD) `pkg install clang35 gmake mysql56-server mysql-connector-c pcre git`
- - (Mac OS X):
- - Install Xcode through the Mac App Store
- - Initialize the build tools through the Terminal `xcode-select --help`
- - Install Homebrew as described on the project page
- - Install the other prerequisites: `brew install mysql pcre`
+ - (Red Hat compatible / CentOS) `yum install gcc make mysql mysql-devel mysql-server pcre-devel zlib-devel git`
+ - (Debian compatible) `apt-get install gcc make libmysqlclient-dev zlib1g-dev libpcre3-dev mysql-server git`
+ - (FreeBSD) `pkg install clang35 gmake mysql56-server mysql-connector-c pcre git`
+ - (Mac OS X):
+ - Install Xcode through the Mac App Store
+ - Initialize the build tools through the Terminal `xcode-select --help`
+ - Install Homebrew as described on the project page
+ - Install the other prerequisites: `brew install mysql pcre`
2. Clone the Hercules repository `git clone https://github.com/HerculesWS/Hercules.git ~/Hercules`
3. Configure the MySQL server and start it.
4. Connect to the MySQL server as root:
- - Create a database (hercules): `CREATE DATABASE hercules;`
- - Create a user (hercules): `CREATE USER 'hercules'@'localhost' IDENTIFIED BY 'password';`.
- - Give permissions (GRANT SELECT,INSERT,UPDATE,DELETE) to the user: `GRANT SELECT,INSERT,UPDATE,DELETE ON hercules.* TO 'hercules'@'localhost';`
+ - Create a database (hercules): `CREATE DATABASE hercules;`
+ - Create a user (hercules): `CREATE USER 'hercules'@'localhost' IDENTIFIED BY 'password';`.
+ - Give permissions (GRANT SELECT,INSERT,UPDATE,DELETE) to the user: `GRANT SELECT,INSERT,UPDATE,DELETE ON hercules.* TO 'hercules'@'localhost';`
5. Connect to the MySQL server as the new user:
- - Import the .sql files in /sql-files/ into the new database.
+ - Import the .sql files in /sql-files/ into the new database.
6. Enter the Hercules directory and configure/build Hercules
- - `./configure`
- - `make clean && make sql` (on FreeBSD, replace `make` with `gmake`)
+ - `./configure`
+ - `make clean && make sql` (on FreeBSD, replace `make` with `gmake`)
7. Start the three servers login-server, char-server, map-server.
## Troubleshooting
diff --git a/conf/map/script.conf b/conf/map/script.conf
index fc617d858..802ce2538 100644
--- a/conf/map/script.conf
+++ b/conf/map/script.conf
@@ -52,7 +52,7 @@ script_configuration: {
// Default value of the 'min' argument of the script command 'input'.
// When the 'min' argument isn't provided, this value is used instead.
// Defaults to 0.
- //input_min_value: 0
+ input_min_value: 0
// Default value of the 'max' argument of the script command 'input'.
// When the 'max' argument isn't provided, this value is used instead.
diff --git a/configure b/configure
index 4ab9057e8..8ac5f1d4f 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.ac 5b2340b4d.
+# From configure.ac cdc66ce0e.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69.
#
diff --git a/db/constants.conf b/db/constants.conf
index b3dd902a4..f1283b26e 100644
--- a/db/constants.conf
+++ b/db/constants.conf
@@ -424,6 +424,8 @@ constants_db: {
mf_noviewid: 56
mf_pairship_startable: 57
mf_pairship_endable: 58
+ mf_nostorage: 59
+ mf_nogstorage: 60
comment__: "Cell Properties"
cell_walkable: 0
diff --git a/db/pre-re/mob_skill_db.conf b/db/pre-re/mob_skill_db.conf
index 8f752cb68..e375754d9 100644
--- a/db/pre-re/mob_skill_db.conf
+++ b/db/pre-re/mob_skill_db.conf
@@ -43540,7 +43540,7 @@ mob_skill_db:(
SkillLevel: 2
Rate: 10000
CastTime: 1000
- Delay: 60000
+ Delay: 60000000
SkillTarget: "MST_SELF"
CastCondition: "MSC_SLAVELE"
ConditionData: 1
@@ -43552,7 +43552,7 @@ mob_skill_db:(
SkillLevel: 2
Rate: 10000
CastTime: 1000
- Delay: 60000
+ Delay: 60000000
SkillTarget: "MST_SELF"
CastCondition: "MSC_SLAVELE"
ConditionData: 1
@@ -43564,7 +43564,7 @@ mob_skill_db:(
SkillLevel: 2
Rate: 10000
CastTime: 1000
- Delay: 60000
+ Delay: 60000000
SkillTarget: "MST_SELF"
CastCondition: "MSC_SLAVELE"
ConditionData: 1
diff --git a/db/re/item_db.conf b/db/re/item_db.conf
index 961fa102e..6c0bea7f0 100644
--- a/db/re/item_db.conf
+++ b/db/re/item_db.conf
@@ -148002,6 +148002,54 @@ item_db: (
Script: <" percentheal 5,5; ">
},
{
+ Id: 22702
+ AegisName: "STR_Soul_Potion"
+ Name: "STR Reduction Potion"
+ Type: "IT_DELAYCONSUME"
+ Buy: 10
+ Script: <" callfunc("F_CashReduceStat", bStr, -1, STR_Soul_Potion); ">
+},
+{
+ Id: 22703
+ AegisName: "AGI_Soul_Potion"
+ Name: "AGI Reduction Potion"
+ Type: "IT_DELAYCONSUME"
+ Buy: 10
+ Script: <" callfunc("F_CashReduceStat", bAgi, -1, AGI_Soul_Potion); ">
+},
+{
+ Id: 22704
+ AegisName: "VIT_Soul_Potion"
+ Name: "VIT Reduction Potion"
+ Type: "IT_DELAYCONSUME"
+ Buy: 10
+ Script: <" callfunc("F_CashReduceStat", bVit, -1, VIT_Soul_Potion); ">
+},
+{
+ Id: 22705
+ AegisName: "INT_Soul_Potion"
+ Name: "INT Reduction Potion"
+ Type: "IT_DELAYCONSUME"
+ Buy: 10
+ Script: <" callfunc("F_CashReduceStat", bInt, -1, INT_Soul_Potion); ">
+},
+{
+ Id: 22706
+ AegisName: "DEX_Soul_Potion"
+ Name: "DEX Reduction Potion"
+ Type: "IT_DELAYCONSUME"
+ Buy: 10
+ Script: <" callfunc("F_CashReduceStat", bDex, -1, DEX_Soul_Potion); ">
+},
+{
+ Id: 22707
+ AegisName: "LUK_Soul_Potion"
+ Name: "LUK Reduction Potion"
+ Type: "IT_DELAYCONSUME"
+ Buy: 10
+ Script: <" callfunc("F_CashReduceStat", bLuk, -1, LUK_Soul_Potion); ">
+},
+{
Id: 22737
AegisName: "Bullet_Case_Blood_"
Name: "Bloody Bullet Case"
diff --git a/doc/constants.md b/doc/constants.md
index d5dbf7afd..48564573d 100644
--- a/doc/constants.md
+++ b/doc/constants.md
@@ -362,6 +362,8 @@
- `mf_noviewid`: 56
- `mf_pairship_startable`: 57
- `mf_pairship_endable`: 58
+- `mf_nostorage`: 59
+- `mf_nogstorage`: 60
### Cell Properties
@@ -3934,6 +3936,7 @@
- `MAX_MENU_LENGTH`: 2048
- `MOB_CLONE_START`: 4001
- `MOB_CLONE_END`: 5000
+- `MAX_NPC_PER_MAP`: 512
### status options
@@ -4123,6 +4126,7 @@
- `PERM_DISABLE_STORE`: 16777216
- `PERM_DISABLE_EXP`: 33554432
- `PERM_DISABLE_SKILL_USAGE`: 67108864
+- `PERM_BYPASS_NOSTORAGE`: 134217728
### Data types
@@ -4201,6 +4205,7 @@
- `MAPINFO_SIZE_X`: 2
- `MAPINFO_SIZE_Y`: 3
- `MAPINFO_ZONE`: 4
+- `MAPINFO_NPC_COUNT`: 5
### consolemes options
@@ -4456,6 +4461,12 @@
- `UDT_BODY2`: 56
- `UDT_GROUP`: 57
+### getguildonline types
+
+- `GUILD_ONLINE_ALL`: 0
+- `GUILD_ONLINE_VENDOR`: 1
+- `GUILD_ONLINE_NO_VENDOR`: 2
+
### Renewal
- `RENEWAL`: 1
@@ -17895,6 +17906,12 @@
- `Chest_Of_Death`: 22679
- `Solo_Christmas_Gift`: 22685
- `Solo_Cookie`: 22686
+- `STR_Soul_Potion`: 22702
+- `AGI_Soul_Potion`: 22703
+- `VIT_Soul_Potion`: 22704
+- `INT_Soul_Potion`: 22705
+- `DEX_Soul_Potion`: 22706
+- `LUK_Soul_Potion`: 22707
- `Bullet_Case_Blood_`: 22737
- `Bullet_Case_Silver_`: 22738
- `Sphere_Case_Wind_`: 22739
diff --git a/doc/permissions.md b/doc/permissions.md
index 7d29b59fd..a8794ecae 100644
--- a/doc/permissions.md
+++ b/doc/permissions.md
@@ -48,4 +48,5 @@ disable_pickup | Ability to disable the player from picking up any i
disable_exp | Ability to disable the player from gaining any experience point.
disable_store | Ability to disable the player from using/openning npc and player stores.
disable_skill_usage | Ability to disable the player from using any skill.
+bypass_nostorage | Ability to bypass the nostorage and nogstorage mapflag.
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index 516454365..5cc3ea186 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -1301,6 +1301,21 @@ and the script will terminate.
---------------------------------------
+*mesclear();
+
+This command will clear the dialog text and continue the script without player interaction.
+
+Example:
+ mes("This is how the 'mesclear' script command works.");
+ sleep2 3000;
+ mesclear(); // This will clear the dialog and continue to the next one.
+ mes("I will show you again.");
+ sleep2 3000;
+ mesclear(); // This will clear the dialog and continue to the next one.
+ mes("Bye!");
+
+---------------------------------------
+
*close()
This command will create a 'close' button in the message window for the
@@ -3192,6 +3207,30 @@ runs of getcartinventorylist().
---------------------------------------
+*setfavoriteitemidx(<idx>, <flag>)
+
+This function will set an item in inventory as favorite or not.
+If its favorite item, it will be moved to favorite tab, else move out from favorite tab.
+Note: Cant change favorite flag of an equipped item.
+
+Valid Parameters:
+ <idx> - inventory index, refer *getinventorylist()
+ <flag> - true/false (true = favorite item, false = otherwise)
+
+---------------------------------------
+
+*autofavoriteitem(<item_id>, <flag>)
+
+This function will auto set an item as favorite when <item_id> is obtained.
+If its favorite item, it will be auto moved to favorite tab, else move out from favorite tab.
+This setting affect not only attached player, but also everyone player globally.
+
+Valid Parameters:
+ <item_id> - item ID
+ <flag> - true/false (true = favorite item, false = otherwise)
+
+---------------------------------------
+
*cardscnt()
This function will return the number of cards inserted into the weapon
@@ -3396,11 +3435,12 @@ argument is omitted, it will try to use the map of the attached NPC, or the
map of the attached player if the NPC can't be found.
Valid <info> are:
- MAPINFO_NAME name of the map
- MAPINFO_ID numeric ID of the map
- MAPINFO_ZONE name of the zone used by the map
- MAPINFO_SIZE_X width of the map (cells on the x axis)
- MAPINFO_SIZE_Y height of the map (cells on the y axis)
+ MAPINFO_NAME name of the map
+ MAPINFO_ID numeric ID of the map
+ MAPINFO_ZONE name of the zone used by the map
+ MAPINFO_SIZE_X width of the map (cells on the x axis)
+ MAPINFO_SIZE_Y height of the map (cells on the y axis)
+ MAPINFO_NPC_COUNT total number of NPC in the map
Examples:
getmapinfo(MAPINFO_ID, "map name"); // ID from name
@@ -3785,6 +3825,18 @@ getarraysize(), because it is not cleared between runs of getguildmember().
For usage examples, see getpartymember().
---------------------------------------
+
+*getguildonline(<guild id>{, <type>});
+
+Returns the amount of players online in the specified guild id.
+Returns -1 if the guild was not found.
+
+Valid <type> are:
+ GUILD_ONLINE_ALL Returns the total amount of players online in the guild.
+ GUILD_ONLINE_VENDOR Returns the total amount of vendors online in the guild.
+ GUILD_ONLINE_NO_VENDOR Returns the total amount of non-vendors online in the guild.
+
+---------------------------------------
//=====================================
2.2 - End of Guild-Related Commands
//=====================================
@@ -5345,6 +5397,34 @@ Check getitem2() to understand its expanded parameters.
---------------------------------------
+*delitemidx(<index>{, <amount>{, <account id>}})
+
+This command will remove an item at the given inventory index. Unlike the
+'delitem()' counterpart, this doesn't check invalid Item ID, making it useful to remove
+invalid item IDs in player's inventory.
+
+If <amount> is not specified, this will remove all of the items at the specified index.
+Note that items with the 'ForceSerial' flag, not yet merged through 'mergeitem()', will only
+be removed at the given index.
+
+The only way to get the inventory index is by using 'getinventorylist()'. After deleting
+an item at the given index, that index can remain empty until the player relogs, so you
+should recall 'getinventorylist()' again. If you try to delete an item at an invalid index, the
+script will terminate with an error.
+
+This command is also useful to remove rental/bound items because 'delitem()'
+does not discriminate at choosing which item to remove.
+
+Example:
+
+ // This will remove all invalid Item ID in player's inventory
+ getinventorylist();
+ for (.@i = 0; .@i < @inventorylist_count; ++.@i)
+ if (getiteminfo(@inventorylist_id[.@i], ITEMINFO_TYPE) == -1)
+ delitemidx(@inventorylist_idx[.@i]);
+
+---------------------------------------
+
*countitem(<item id>)
*countitem("<item name>")
@@ -5747,6 +5827,10 @@ storage window, to avoid any disruption when both windows overlap.
openstorage();
end;
+The mapflag 'nostorage' when set to type '2' (or 3), will not open the
+account storage. Unless the character group has the permission 'bypass_nostorage'.
+In case blocked by mapflag, returns 0.
+
---------------------------------------
*openmail()
@@ -5808,6 +5892,10 @@ time.
This will also fail and return 2 if the attached character does not belong
to any guild.
+The mapflag 'nogstorage' when set to type '2' (or 3), will not open the
+guild storage. Unless the character group has the permission 'bypass_nostorage'.
+In case blocked by mapflag, returns 1.
+
---------------------------------------
*guildchangegm(<guild id>, <new master's name>)
@@ -6511,7 +6599,7 @@ This command will kill all monsters that were spawned with monster() or
areamonster() and have a specified event label attached to them. Commonly
used to get rid of remaining quest monsters once the quest is complete.
-If the label is given as "All", all monsters which have their respawn
+If the label is given as "all", all monsters which have their respawn
times set to -1 (like all the monsters summoned with 'monster' or
'areamonster' script command, and all monsters summoned with GM commands,
but no other ones - that is, all non-permanent monsters) on the specified
@@ -8276,6 +8364,7 @@ Valid <permission> are:
PERM_DISABLE_STORE
PERM_DISABLE_EXP
PERM_DISABLE_SKILL_USAGE
+ PERM_BYPASS_NOSTORAGE
Example:
@@ -8536,6 +8625,18 @@ Example:
---------------------------------------
+*cap_value(<number>, <min>, <max>)
+
+Returns the number but capped between <min> and <max>.
+
+Example:
+ // capped between 0 ~ 100
+ .@value = cap_value(10, 0, 100); // .@value will be equal to 10
+ .@value = cap_value(1000, 0, 100); // .@value will be equal to 100
+ .@value = cap_value(-10, 3, 100); // .@value will be equal to 3
+
+---------------------------------------
+
*md5("<string>")
Returns the md5 checksum of a number or string.
@@ -10388,7 +10489,7 @@ Works for 20170830 RE and main and for any zero clients
---------------------------------------
-*expandInventoryAck(<result>{, <itemId>})
+*expandinventoryack(<result>{, <itemId>})
Send initial inventory expansion result.
Normally this function should be called from script label
@@ -10406,7 +10507,7 @@ Works for 20181212 zero clients
---------------------------------------
-*expandInventoryResult(<result>)
+*expandinventoryresult(<result>)
Send final inventory expansion result.
Normally this function should be called from script label
@@ -10423,7 +10524,7 @@ Works for 20181212 zero clients
---------------------------------------
-*expandInventory(<value>)
+*expandinventory(<value>)
Adjust player inventory to given value.
Maximum inventory size is MAX_INVENTORY.
@@ -10434,7 +10535,7 @@ Current max inventory size can be read by function getInventorySize().
---------------------------------------
-*getInventorySize()
+*getinventorysize()
Return current player max inventory size.
This value always smaller or equal to MAX_INVENTORY.
diff --git a/mariadb.bat b/mariadb.bat
new file mode 100644
index 000000000..67d7c39a3
--- /dev/null
+++ b/mariadb.bat
@@ -0,0 +1,15 @@
+@echo off
+
+WHERE powershell.exe >nul 2>nul
+IF %ERRORLEVEL% NEQ 0 (
+ ECHO ERROR: PowerShell is not installed on this computer!
+ ECHO Please download it here:
+ ECHO https://github.com/PowerShell/PowerShell#get-powershell
+ ECHO.
+ ECHO Once it is installed, please re-launch mariadb.bat
+ pause >nul
+ exit
+)
+
+powershell -NoLogo -ExecutionPolicy Bypass -File "%~dp0\tools\setup_mariadb.ps1"
+pause >nul
diff --git a/npc/custom/events/mushroom_event.txt b/npc/custom/events/mushroom_event.txt
index b04b99fff..fc7446814 100644
--- a/npc/custom/events/mushroom_event.txt
+++ b/npc/custom/events/mushroom_event.txt
@@ -41,7 +41,7 @@ OnMinute10: // Start time (every hour)
set .status,1;
set .Spawn,rand(1,10); // How many Mushrooms should spawn?
set .Map$,.maps$[rand(getarraysize(.maps$))];
- killmonster .Map$,"All";
+ killmonster(.Map$, "all");
monster .Map$,0,0,"Please don't kill me!",1084,.Spawn,strnpcinfo(NPC_NAME)+"::OnMobKilled";
announce "Find the Mushroom : Total of "+.Spawn+" Mushrooms have been spawned in "+.Map$+"!",0;
sleep 2500;
diff --git a/npc/custom/stylist.txt b/npc/custom/stylist.txt
index 0ee7d8822..188a91ca7 100644
--- a/npc/custom/stylist.txt
+++ b/npc/custom/stylist.txt
@@ -3,32 +3,72 @@
//===== By: ==================================================
//= Euphy
//===== Current Version: =====================================
-//= 1.1
+//= 1.2
//===== Description: =========================================
//= Changes your hair style, hair color, and cloth color.
//===== Additional Comments: =================================
//= 1.1 Switched to 'getbattleflag', credits to Saithis. [Euphy]
+//= 1.2 Fix style start at min_style, add Job_Summoner [AnnieRuru]
//============================================================
prontera,170,180,1 script Stylist#custom_stylist 2_M_DYEINGER,{
-
- setarray .@styles[1],getbattleflag("max_cloth_color"),getbattleflag("max_hair_style"),getbattleflag("max_hair_color");
- setarray .@Look[1],7,1,6;
- set .@s, select(" ~ Cloth color", " ~ Hairstyle", " ~ Hair color");
- set .@Revert, getlook(.@Look[.@s]);
- set .@style,1;
- while(1) {
- setlook .@Look[.@s], .@style;
- message strcharinfo(PC_NAME),"This is style #"+.@style+".";
- set .@menu$, " ~ Next (^0055FF"+((.@style!=.@styles[.@s])?.@style+1:1)+"^000000): ~ Previous (^0055FF"+((.@style!=1)?.@style-1:.@styles[.@s])+"^000000): ~ Jump to...: ~ Revert to original (^0055FF"+.@Revert+"^000000)";
- switch(select(.@menu$)) {
- case 1: set .@style, ((.@style!=.@styles[.@s])?.@style+1:1); break;
- case 2: set .@style, ((.@style!=1)?.@style-1:.@styles[.@s]); break;
- case 3: message strcharinfo(PC_NAME),"Choose a style between 1 - "+.@styles[.@s]+".";
- input .@style,0,.@styles[.@s];
- if (!.@style) set .@style, rand(1,.@styles[.@s]);
- break;
- case 4: set .@style, .@Revert; setlook .@Look[.@s], .@Revert; break;
+ .@choose = select("Hair style", "Hair color", "Cloth color") - 1;
+ .@part = .look[.@choose];
+ if (BaseClass != Job_Summoner)
+ callsub(L_styles, .@part, .minstyle[.@part], .maxstyle[.@part]);
+ else
+ callsub(L_styles, .@part, .summoner_minstyle[.@part], .summoner_maxstyle[.@part]);
+L_styles:
+ .@lookpart = getarg(0);
+ .@minstyle = getarg(1);
+ .@maxstyle = getarg(2);
+ .@i = .@revert = getlook(.@lookpart);
+ while (true) {
+ setlook(.@lookpart, .@i);
+ message(strcharinfo(PC_NAME), sprintf(_("This is style #%d."), .@i));
+ if (.@i == .@maxstyle)
+ .@next = .@minstyle;
+ else
+ .@next = .@i + 1;
+ if (.@i == .@minstyle)
+ .@previous = .@maxstyle;
+ else
+ .@previous = .@i - 1;
+ switch(select(
+ sprintf(_(" ~ Next (%s%d%s)"), F_MesColor(C_BLUE), .@next, F_MesColor(C_BLACK)),
+ sprintf(_(" ~ Previous (%s%d%s)"), F_MesColor(C_BLUE), .@previous, F_MesColor(C_BLACK)),
+ " ~ Jump to...",
+ sprintf(_(" ~ Revert to original (%s%d%s)"), F_MesColor(C_BLUE), .@revert, F_MesColor(C_BLACK)))) {
+ case 1:
+ .@i = .@next;
+ break;
+ case 2:
+ .@i = .@previous;
+ break;
+ case 3:
+ message(strcharinfo(PC_NAME), sprintf(_("Choose a style between %d - %d."), .@minstyle, .@maxstyle));
+ input(.@i, .@minstyle, .@maxstyle);
+ break;
+ case 4:
+ .@i = .@revert;
}
}
+ end;
+OnInit:
+ setarray .look[0], LOOK_HAIR, LOOK_HAIR_COLOR, LOOK_CLOTHES_COLOR;
+
+ .minstyle[LOOK_HAIR] = getbattleflag("min_hair_style");
+ .maxstyle[LOOK_HAIR] = getbattleflag("max_hair_style");
+ .minstyle[LOOK_HAIR_COLOR] = getbattleflag("min_hair_color");
+ .maxstyle[LOOK_HAIR_COLOR] = getbattleflag("max_hair_color");
+ .minstyle[LOOK_CLOTHES_COLOR] = getbattleflag("min_cloth_color");
+ .maxstyle[LOOK_CLOTHES_COLOR] = getbattleflag("max_cloth_color");
+
+ .summoner_minstyle[LOOK_HAIR] = getbattleflag("min_hair_style");
+ .summoner_maxstyle[LOOK_HAIR] = getbattleflag("max_hair_style");
+ .summoner_minstyle[LOOK_HAIR_COLOR] = getbattleflag("min_hair_color");
+ .summoner_maxstyle[LOOK_HAIR_COLOR] = getbattleflag("max_hair_color");
+ .summoner_minstyle[LOOK_CLOTHES_COLOR] = getbattleflag("min_cloth_color");
+ .summoner_maxstyle[LOOK_CLOTHES_COLOR] = getbattleflag("max_cloth_color");
+ end;
}
diff --git a/npc/jobs/1-1e/ninja.txt b/npc/jobs/1-1e/ninja.txt
index 762f94b4b..8911b5795 100644
--- a/npc/jobs/1-1e/ninja.txt
+++ b/npc/jobs/1-1e/ninja.txt
@@ -93,9 +93,9 @@ alberta,30,65,3 script Akagi 4_M_JOB_ASSASSIN,{
}
}
-que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
+que_ng,30,65,3 script Kuuga Gai#nq 4_M_JOB_ASSASSIN,{
if (Upper == 2) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "I... I've never";
mes "seen a baby as";
mes "powerful as you!";
@@ -105,7 +105,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
}
if (Class == Job_Novice) {
if (JobLevel < 10) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Hm? Have you come to";
mes "learn how to be a Ninja?";
mes "You're not quite experienced";
@@ -119,7 +119,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "Excuse me.";
mes "H-hello?";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "...............................";
mes "How did you do that?";
next;
@@ -127,7 +127,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "Do what? I didn't";
mes "do anything, I don't think...";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "H-How are you able to";
mes "see me? I'm supposed to";
mes "be invisible to the naked eye.";
@@ -140,7 +140,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "Calm down, there's no";
mes "need to get violent!";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "What...?";
mes "How did you dodge";
mes "all of my attacks?";
@@ -153,7 +153,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "to change my job";
mes "to a Ninja.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "...Oh. Is that all?";
mes "Hmm, you've got great";
mes "potential, but I can't help";
@@ -161,14 +161,14 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "enemies, and I can't let my";
mes "guard down for even a second.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "That Wildcat Joe is";
mes "completely ruthless...!";
mes "He could strike at any time!";
mes "He'll do anything to achieve";
mes "victory over his enemies!";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Wait, wait, I just";
mes "thought of something.";
mes "Maybe you can help me out.";
@@ -177,7 +177,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "really want to be a Ninja.";
next;
if(select("Sure.", "No, thanks.") == 2) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Hm? Well, alright.";
mes "Still, I don't see";
mes "why we can't help";
@@ -185,7 +185,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "little predicament...";
close;
}
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Great! Now, I wanted to";
mes "ask Wildcat Joe if he'd";
mes "agree to a temporary truce.";
@@ -193,7 +193,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "are out of weapons, so we";
mes "should get well equipped first.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Please take this letter,";
mes "and deliver it to Wildcat";
mes "Joe in Einbroch. He's a master";
@@ -201,7 +201,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "eye out for him. Ah, and look";
mes "for him in a high place.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Yeah, Wildcat Joe";
mes "always did have a thing";
mes "for hiding in high places.";
@@ -213,7 +213,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
close;
}
else if (NINJ_Q == 1) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Even if this task";
mes "isn't that urgent,";
mes "please hurry over to";
@@ -222,7 +222,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
close;
}
else if (NINJ_Q == 2) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Did you deliver that";
mes "letter to Wildcat Joe?";
mes "I still need to know his";
@@ -232,14 +232,14 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
close;
}
else if (NINJ_Q == 3) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Ah, you've returned.";
mes "So did Wildcat Joe send";
mes "you back here with his";
mes "response? Great, great,";
mes "please let me read it.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "What...?! How could he";
mes "reject my proposal for";
mes "a truce?! This can only";
@@ -247,14 +247,14 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "Kunai. Nuts! I have to catch";
mes "up to him, or I'm a goner!";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Listen, you've got to help";
mes "me out again! I need you to";
mes "gather some materials so that";
mes "I can craft my own Kunai to fight Wildcat Joe. Then, I'll go ahead";
mes "and change your job to a Ninja.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "All you need";
mes "to bring me is";
mes "^3355FF5 Cyfars^000000 and";
@@ -268,7 +268,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "asked me to gather";
mes "those same materials.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Curses! Then that means...";
mes "You actually helped Joe";
mes "in crafting his Kunai! No!";
@@ -281,7 +281,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
}
else if (NINJ_Q == 4) {
if (countitem(Cyfar) < 5 || countitem(Phracon) < 1) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Hurry and bring";
mes "^3355FF5 Cyfars^000000 and";
mes "^3355FF1 Phracon^000000 to me,";
@@ -291,7 +291,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
close;
}
if (SkillPoint != 0) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Whoa, whoa...";
mes "You still have some";
mes "leftover Skill Points.";
@@ -300,7 +300,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "change jobs, right?";
close;
}
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Ah, you're back with";
mes "everything that I need.";
mes "You've come earlier than";
@@ -308,14 +308,14 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "as promised, I'll turn";
mes "you into a Ninja.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Let me formally introduce";
- mes "myself. I am High Ninja Cougar";
+ mes "myself. I am High Ninja Kuuga Gai";
mes "in the Touga Ninja Corps, and";
mes "I'm in charge of the search";
mes "party to find Sir Kazma.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Sir Kazma is the chief";
mes "of my village, but he's";
mes "run away. This has resulted";
@@ -323,7 +323,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "the Ninja Corps. Things are";
mes "pretty unstable right now...";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "I initially didn't want to";
mes "accept you as a Ninja because";
mes "of this complicated situation.";
@@ -331,14 +331,14 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "you're truly worthy of joining";
mes "the Ninja ranks.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "According to his letter, even";
mes "Joe thinks highly of you. Just";
mes "remember that, as a Ninja, your";
mes "mission is your highest priority. But don't let mission objectives";
mes "supercede your conscience.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "''Secrecy above all else.''";
mes "To keep our secrets in the";
mes "shadows, you can only buy";
@@ -346,7 +346,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "authorized dealers. Please";
mes "keep that in mind.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "As of today, you are";
mes "now a proud member of the";
mes "Touga Ninja Corps. Be as";
@@ -361,7 +361,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
close;
}
else {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "How have you been?";
mes "Train hard: you want";
mes "to be able to vanish";
@@ -372,7 +372,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
}
} else {
if (BaseClass == Job_Ninja) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "How have you been?";
mes "Train hard: you want";
mes "to be able to vanish";
@@ -381,7 +381,7 @@ que_ng,30,65,3 script Cougar#nq 4_M_JOB_ASSASSIN,{
mes "the respect of any Ninja~";
close;
} else {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "What...?";
mes "How were you able";
mes "to find me hidden";
@@ -478,7 +478,7 @@ einbroch,184,194,3 script Suspicious Man#nq 4_M_SITDOWN,{
mes "?????!!";
next;
mes "[Suspicious Man]";
- mes "Why? Didn't you bring Cougar's letter for me?";
+ mes "Why? Didn't you bring Kuuga Gai's letter for me?";
next;
mes "["+strcharinfo(PC_NAME)+"]";
mes "Are you...";
@@ -487,7 +487,7 @@ einbroch,184,194,3 script Suspicious Man#nq 4_M_SITDOWN,{
mes "[Suspicious Man]";
mes "...Yes, but I prefer to";
mes "be called Red Leopard Joe.";
- mes "Cougar sent you to me, right?";
+ mes "Kuuga Gai sent you to me, right?";
mes "He's the only one who calls";
mes "me that. So you want to be";
mes "a Ninja, eh? Hmm, alright.";
@@ -513,7 +513,7 @@ einbroch,184,194,3 script Suspicious Man#nq 4_M_SITDOWN,{
mes "[Red Leopard Joe]";
mes "For now, let me read";
mes "this letter. Let's see...";
- mes "Hm. I thought that Cougar";
+ mes "Hm. I thought that Kuuga Gai";
mes "would want to challenge me";
mes "again, but he actually wants";
mes "a temporary truce? Hah!";
@@ -540,7 +540,7 @@ einbroch,184,194,3 script Suspicious Man#nq 4_M_SITDOWN,{
mes "[Red Leopard Joe]";
mes "Here you go.";
mes "Please bring this";
- mes "letter to Cougar.";
+ mes "letter to Kuuga Gai.";
mes "It'll take a while to";
mes "return to Amatsu, so let";
mes "me send you there directly...";
@@ -557,7 +557,7 @@ einbroch,184,194,3 script Suspicious Man#nq 4_M_SITDOWN,{
mes "Eh? I'm not sure what";
mes "happened, but it seems";
mes "that you haven't delivered";
- mes "my response to Cougar yet.";
+ mes "my response to Kuuga Gai yet.";
mes "Shall I directly send you";
mes "to Amatsu right now?";
next;
@@ -577,7 +577,7 @@ einbroch,184,194,3 script Suspicious Man#nq 4_M_SITDOWN,{
}
else if (NINJ_Q == 4) {
mes "[Red Leopard Joe]";
- mes "Cougar asked you to";
+ mes "Kuuga Gai asked you to";
mes "gather some materials";
mes "too? Oh well, I suppose";
mes "that I can't blame him.";
diff --git a/npc/other/inventory_expansion.txt b/npc/other/inventory_expansion.txt
index db18e09e1..8a5ac5e6c 100644
--- a/npc/other/inventory_expansion.txt
+++ b/npc/other/inventory_expansion.txt
@@ -33,28 +33,28 @@
OnInvExpandRequest:
if (countitem(Inventory_Extension_Coupon) < 1) {
- expandInventoryAck(EXPAND_INV_MISSING_ITEM);
+ expandinventoryack(EXPAND_INV_MISSING_ITEM);
end;
}
- if (getInventorySize() + INVENTORY_INCREASE_STEP > MAX_INVENTORY) {
- expandInventoryAck(EXPAND_INV_MAX_SIZE);
+ if (getinventorysize() + INVENTORY_INCREASE_STEP > MAX_INVENTORY) {
+ expandinventoryack(EXPAND_INV_MAX_SIZE);
end;
}
- expandInventoryAck(EXPAND_INV_ASK_CONFIRMATION, Inventory_Extension_Coupon);
+ expandinventoryack(EXPAND_INV_ASK_CONFIRMATION, Inventory_Extension_Coupon);
end;
OnInvExpandConfirmed:
if (countitem(Inventory_Extension_Coupon) < 1) {
- expandInventoryResult(EXPAND_INV_RESULT_MISSING_ITEM);
+ expandinventoryresult(EXPAND_INV_RESULT_MISSING_ITEM);
end;
}
- if (getInventorySize() + INVENTORY_INCREASE_STEP > MAX_INVENTORY) {
- expandInventoryResult(EXPAND_INV_RESULT_MAX_SIZE);
+ if (getinventorysize() + INVENTORY_INCREASE_STEP > MAX_INVENTORY) {
+ expandinventoryresult(EXPAND_INV_RESULT_MAX_SIZE);
end;
}
delitem(Inventory_Extension_Coupon, 1);
- if (expandInventory(INVENTORY_INCREASE_STEP) == true) {
- expandInventoryResult(EXPAND_INV_RESULT_SUCCESS);
+ if (expandinventory(INVENTORY_INCREASE_STEP) == true) {
+ expandinventoryresult(EXPAND_INV_RESULT_SUCCESS);
}
end;
diff --git a/npc/quests/quests_nameless.txt b/npc/quests/quests_nameless.txt
index 9461461a5..55f5c319c 100644
--- a/npc/quests/quests_nameless.txt
+++ b/npc/quests/quests_nameless.txt
@@ -61,7 +61,8 @@
//= 2.4
//=========================================================================
-//== Nameless Island and Cursed Monestary Access Quest :: aru_monas =
+// Nameless Island and Cursed Monestary Access Quest :: aru_monas
+//=========================================================================
airplane_01,90,63,0 script Event Switch#pc FAKE_NPC,3,3,{
end;
@@ -998,7 +999,7 @@ nameless_i,127,207,0 script Dead Crow#Aru HIDDEN_NPC,{
mes "^3355FFThis grass must be the";
mes "main ingredient of the";
mes "poison used to kill the";
- mes "Gaebolg family princes.^000000";
+ mes "Geoborg family princes.^000000";
next;
mes "["+strcharinfo(PC_NAME)+"]";
mes "Looks like I just hit";
@@ -4406,7 +4407,7 @@ izlude_in,113,66,0 script Strange Machine HIDDEN_NPC,{
mes "and vibrated violently";
mes "before coming to a sudden";
mes "stop. That was the wrong";
- mes "switch. You'd better ask Dorian... ";
+ mes "switch. You'd better ask Dorian...";
changequest 3105,3106;
diamond_edq = 11;
close;
@@ -4432,7 +4433,7 @@ izlude_in,113,66,0 script Strange Machine HIDDEN_NPC,{
mes "and vibrated violently";
mes "before coming to a sudden";
mes "stop. That was the wrong";
- mes "switch. You'd better ask Dorian... ";
+ mes "switch. You'd better ask Dorian...";
changequest 3105,3106;
diamond_edq = 11;
close;
@@ -4458,7 +4459,7 @@ izlude_in,113,66,0 script Strange Machine HIDDEN_NPC,{
mes "and vibrated violently";
mes "before coming to a sudden";
mes "stop. That was the wrong";
- mes "switch. You'd better ask Dorian... ";
+ mes "switch. You'd better ask Dorian...";
changequest 3105,3106;
diamond_edq = 11;
close;
@@ -4484,7 +4485,7 @@ izlude_in,113,66,0 script Strange Machine HIDDEN_NPC,{
mes "and vibrated violently";
mes "before coming to a sudden";
mes "stop. That was the wrong";
- mes "switch. You'd better ask Dorian... ";
+ mes "switch. You'd better ask Dorian...";
changequest 3105,3106;
diamond_edq = 11;
close;
@@ -4509,7 +4510,7 @@ izlude_in,113,66,0 script Strange Machine HIDDEN_NPC,{
mes "and vibrated violently";
mes "before coming to a sudden";
mes "stop. That was the wrong";
- mes "switch. You'd better ask Dorian... ";
+ mes "switch. You'd better ask Dorian...";
changequest 3105,3106;
diamond_edq = 11;
close;
@@ -4535,7 +4536,7 @@ izlude_in,113,66,0 script Strange Machine HIDDEN_NPC,{
mes "and vibrated violently";
mes "before coming to a sudden";
mes "stop. That was the wrong";
- mes "switch. You'd better ask Dorian... ";
+ mes "switch. You'd better ask Dorian...";
changequest 3105,3106;
diamond_edq = 11;
close;
@@ -4561,7 +4562,7 @@ izlude_in,113,66,0 script Strange Machine HIDDEN_NPC,{
mes "and vibrated violently";
mes "before coming to a sudden";
mes "stop. That was the wrong";
- mes "switch. You'd better ask Dorian... ";
+ mes "switch. You'd better ask Dorian...";
changequest 3105,3106;
diamond_edq = 11;
close;
@@ -4587,7 +4588,7 @@ izlude_in,113,66,0 script Strange Machine HIDDEN_NPC,{
mes "and vibrated violently";
mes "before coming to a sudden";
mes "stop. That was the wrong";
- mes "switch. You'd better ask Dorian... ";
+ mes "switch. You'd better ask Dorian...";
changequest 3105,3106;
diamond_edq = 11;
close;
@@ -10318,7 +10319,7 @@ comodo,139,184,3 script Scholar#zgang 2_M_SAGE_B,{
mes "jewel came into a rich man's";
mes "possession. However, he lost";
mes "his fortune and was completely";
- mes "ruined after obtaining it. Hence the moniker, ''Unlucky Emerald.''";
+ mes "ruined after obtaining it. Hence the moniker, ''Unlucky Emerald.''";
next;
mes "[Scholar]";
mes "Then the emerald came into";
diff --git a/npc/quests/quests_prontera.txt b/npc/quests/quests_prontera.txt
index e0bd9156e..b2fefb3cf 100644
--- a/npc/quests/quests_prontera.txt
+++ b/npc/quests/quests_prontera.txt
@@ -37,7 +37,7 @@
//= Collection of Prontera-based quests.
//= - Culvert Access
//= - Ph.D Hat Quest
-//= - Gaebolg Family Curse
+//= - Geoborg Family Curse
//================= Current Version =======================================
//= 2.9
//================= Variables Used ========================================
@@ -45,7 +45,7 @@
//= - MISC_QUEST (bit 8)
//= Ph.D Hat Quest:
//= - n/a
-//= Gaebolg Family Curse:
+//= Geoborg Family Curse:
//= - prt_curse (max 61)
//=========================================================================
@@ -799,7 +799,7 @@ yuno,311,195,3 script Historian#prt01 4_M_SAGE_A,{
mes "With the return of peace,";
mes "the 7 warriors established";
mes "the Rune-Midgarts Kingdom,";
- mes "choosing Tristram Gaebolg III";
+ mes "choosing Tristram Geoborg III";
mes "as the kingdom's first ruler. ";
next;
mes "[Historian]";
@@ -1228,7 +1228,7 @@ morocc_in,45,126,3 script Historian#prt02 4_F_GON,{
next;
mes "[Historian Rodafrian]";
mes "Anyway, your report about";
- mes "the Gaebolg family will be";
+ mes "the Geoborg family will be";
mes "greatly appreciated by the";
mes "Rekenber Historical Research";
mes "Group. But first, I need to";
@@ -1237,7 +1237,7 @@ morocc_in,45,126,3 script Historian#prt02 4_F_GON,{
mes "[Historian Rodafrian]";
mes "Anyway, keep this information";
mes "a secret between me and you";
- mes "for now. Then, when I reveal the secret curse of the Gaebolg royal";
+ mes "for now. Then, when I reveal the secret curse of the Geoborg royal";
mes "family, I'll finally outshine that Karlomoff! Bwahahahahaha!";
next;
mes "["+strcharinfo(PC_NAME)+"]";
@@ -2291,7 +2291,7 @@ prt_church,185,106,3 script Father Bamph 1_M_PASTOR,{
next;
mes "[Father Bamph]";
mes "Finally, the first Tristram of";
- mes "the Gaebolg family defeated";
+ mes "the Geoborg family defeated";
mes "Jormungand together with 6";
mes "other warriors, but only after";
mes "it killed his beloved father.";
@@ -2306,7 +2306,7 @@ prt_church,185,106,3 script Father Bamph 1_M_PASTOR,{
mes "[Father Bamph]";
mes "To this day...";
mes "^FF0000Every first prince of";
- mes "the Gaebolg family dies";
+ mes "the Geoborg family dies";
mes "at a young age^000000. That is";
mes "Jormungand's curse and";
mes "the royal family's secret.";
@@ -2429,7 +2429,7 @@ prt_church,185,106,3 script Father Bamph 1_M_PASTOR,{
mes "Oh, my. I learned the song";
mes "when I was a young boy from";
mes "my father. However, your version seems to reveal the secret curse";
- mes "of the Gaebolgs. Please tell me, where did you hear that song?";
+ mes "of the Geoborgs. Please tell me, where did you hear that song?";
next;
mes "["+strcharinfo(PC_NAME)+"]";
mes "Well, I first heard this";
@@ -3069,7 +3069,7 @@ prt_church,16,114,4 script Father Bamph#tomb 1_M_PASTOR,{
if (prt_curse == 18) {
mes "[Father Bamph]";
mes "There are the bodies";
- mes "of the Gaebolg princes";
+ mes "of the Geoborg princes";
mes "that were killed during";
mes "the exorcism. Please take";
mes "a look at the body to the left.";
@@ -3547,13 +3547,13 @@ OnTouch:
mes "["+strcharinfo(PC_NAME)+"]";
mes "Long ago, the giant serpent";
mes "Jormungand threatened mankind.";
- mes "7 warriors defeated Jormungand, led by Tristram III of the Gaebolg";
- mes "family, but Jormungand cursed the Gaebolg bloodline in its defeat.";
+ mes "7 warriors defeated Jormungand, led by Tristram III of the Geoborg";
+ mes "family, but Jormungand cursed the Geoborg bloodline in its defeat.";
next;
mes "["+strcharinfo(PC_NAME)+"]";
mes "Ever since, the curse kills";
mes "the first born prince of the";
- mes "Gaebolg family at an early age.";
+ mes "Geoborg family at an early age.";
mes "However, all of the princes of";
mes "this generation were killed.";
next;
diff --git a/npc/re/instances/ghost_palace.txt b/npc/re/instances/ghost_palace.txt
index 3e708dc57..a291984db 100644
--- a/npc/re/instances/ghost_palace.txt
+++ b/npc/re/instances/ghost_palace.txt
@@ -601,7 +601,7 @@ OnInstanceInit:
OnStart:
stopnpctimer instance_npcname("#gp3control");
disablenpc(instance_npcname("#gp3control"));
- killmonster(instance_mapname("1@spa"), "All");
+ killmonster(instance_mapname("1@spa"), "all");
disablenpc(instance_npcname("#gp3warp"));
enablenpc(instance_npcname("Lurid Royal Guard#gp5"));
enablenpc(instance_npcname("Tiara Princess#gp5"));
diff --git a/npc/re/jobs/2e/kagerou_oboro.txt b/npc/re/jobs/2e/kagerou_oboro.txt
index 5c54a0114..5818bb4fd 100644
--- a/npc/re/jobs/2e/kagerou_oboro.txt
+++ b/npc/re/jobs/2e/kagerou_oboro.txt
@@ -120,7 +120,7 @@ que_ng,21,76,0 script Wall with a Drawing#ko CLEAR_NPC,{
job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
if (MaxWeight - Weight < 1000 || checkweight("Knife",1) == 0) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "You don't need to carry so many things.";
close;
}
@@ -128,8 +128,8 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
for (set .@i,5131; .@i<=5146; set .@i,.@i+1)
if (questprogress(.@i)) erasequest .@i;
set job_kagero,0;
- mes "[Cougar]";
- mes "You are not in the Family of the Ninja.";
+ mes "[Kuuga Gai]";
+ mes "You are not in the clan of the Ninja.";
close2;
warp "amatsu",147,136;
end;
@@ -156,28 +156,28 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
mes "^1A95E6He keeps talking and doesn't stop to answer your question.^1A95E6";
next;
mes "[Old Man]";
- mes "There once was a quiet family living in ancient Amatsu times that is never mentioned in history books or stories.";
+ mes "There once was a quiet clan living in ancient Amatsu times that is never mentioned in history books or stories.";
next;
mes "[Old Man]";
mes "They lived beneath shadows but always yearned for the bright sun, like a sunflower.";
next;
mes "[Old Man]";
- mes "A family that was loyal to their lord who they served as their bright sun.";
+ mes "A clan that was loyal to their lord who they served as their bright sun.";
next;
mes "[Old Man]";
- mes "...a very trustworthy family...";
+ mes "...a very trustworthy clan...";
next;
mes "[Old Man]";
mes "....loyal to their core...";
next;
mes "[Old Man]";
- mes "...a family of integrity...";
+ mes "...a clan of integrity...";
next;
select("What happened to them?");
mes "^1A95E6The old man looks at you with a melancholy face.^1A95E6";
next;
mes "[Old Man]";
- mes "Why are you interested in a family that was abandoned by their lord and disappeared from history itself?";
+ mes "Why are you interested in a clan that was abandoned by their lord and disappeared from history itself?";
next;
if(select("I'm a Ninja.", "I'm bored.") == 2) {
mes "[Old Man]";
@@ -188,13 +188,13 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
}
cutin "job_ko02",2;
mes "[Old Man]";
- mes "Ninja! There was a time when the family was called ninjas, too.";
+ mes "Ninja! There was a time when the clan was called ninjas, too.";
next;
erasequest 5131;
setquest 5132;
set job_kagero,2;
mes "[Old Man]";
- mes "You'll have to lend me your ear for I have so much to tell you about the family story.";
+ mes "You'll have to lend me your ear for I have so much to tell you about the clan story.";
close2;
cutin "",255;
end;
@@ -206,13 +206,13 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
mes "This goes way back to ancient times and nobody in Amatsu remembers about it.";
next;
mes "[Old Man]";
- mes "The family worked behind the scenes and basically lived their lives for their lord.";
+ mes "The clan worked behind the scenes and basically lived their lives for their lord.";
next;
mes "[Old Man]";
mes "They were very loyal doing whatever deed their lord asked for.";
next;
mes "[Old Man]";
- mes "Ninja, the family was known as the dark family but that doesn't mean they wanted to be hidden in the darkness.";
+ mes "Ninja, the clan was known as the dark clan but that doesn't mean they wanted to be hidden in the darkness.";
next;
mes "[Old Man]";
mes "They were loyal enough to be satisfied as the lord's servants but their loyalty became the problem.";
@@ -222,13 +222,13 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
mes "They are a secret organization that even the lord didn't know much about.";
next;
mes "[Old Man]";
- mes "The few that knew about the family's existence, tried to investigate them but nobody was able to reveal their true identity.";
+ mes "The few that knew about the clan's existence, tried to investigate them but nobody was able to reveal their true identity.";
next;
mes "[Old Man]";
- mes "That is why this family has grown from loyal servants to a group feared for its secrets.";
+ mes "That is why this clan has grown from loyal servants to a group feared for its secrets.";
next;
mes "[Old Man]";
- mes "The lord shunned the family and didn't call them for their service any more but they never betrayed him.";
+ mes "The lord shunned the clan and didn't call them for their service any more but they never betrayed him.";
next;
select("They were really loyal people.");
cutin "job_ko03",2;
@@ -245,20 +245,20 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
} else if (job_kagero == 3) {
cutin "job_ko03",2;
mes "[Old Man]";
- mes "The family has been living in hiding for so long since the old days. The current lord didn't even know of their existence.";
+ mes "The clan has been living in hiding for so long since the old days. The current lord didn't even know of their existence.";
next;
select(".........");
cutin "job_ko01",2;
mes "[Old Man]";
- mes "I'm Guide Gion, the last of the dark ninja family.";
+ mes "I'm Leader Gion, the last of the dark ninja clan.";
next;
if(select("I think your time has ended.", "I need your teaching.") == 1) {
cutin "job_ko04",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Are you an assassin to end this old man's life?";
next;
- mes "[Guide Gion]";
- mes "So that is why you've shown interest in my family. I won't give up easily.";
+ mes "[Leader Gion]";
+ mes "So that is why you've shown interest in my clan. I won't give up easily.";
next;
percentheal -99,0;
mes "Pow!!";
@@ -268,50 +268,50 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
end;
}
cutin "job_ko02",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Teaching...";
mes "Been a long time since I last heard that word.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I guess this little visit was not by coincidence but a start of a connection.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Sorry I am not a teacher. But!";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I can help you on the path you've chosen, the ^33CC71"+ (Sex == SEX_MALE ? "Kagerou" : "Oboro") +"^000000 path.";
next;
- mes "^1A95E6You hear Guide Gion's voice faintly as you slip away.^1A95E6";
+ mes "^1A95E6You hear Leader Gion's voice faintly as you slip away.^1A95E6";
next;
erasequest 5133;
setquest 5134;
set job_kagero,4;
- mes "[Guide Gion]";
- mes "If you are prepared to follow me, Guide Gion, on the "+ (Sex == SEX_MALE ? "Kagerou" : "Oboro") +" path, we will meet again.";
+ mes "[Leader Gion]";
+ mes "If you are prepared to follow me, Leader Gion, on the "+ (Sex == SEX_MALE ? "Kagerou" : "Oboro") +" path, we will meet again.";
close2;
warp "amatsu",147,136;
end;
} else if (job_kagero == 4) {
cutin "job_ko02",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I thought you were afraid of the ^33CC71path of the "+ (Sex == SEX_MALE ? "Kagerou" : "Oboro") +"^33CC71 and wouldn't come back.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "But from the look of your eyes, I guess I misjudged you.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You will have to train your mind and body to walk steadily in the unknown world and never fall into temptation to stay on the path.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Our ancestors had 4 tests to train our people.";
next;
select("4 tests?");
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Yes, there are 4 tests.";
mes "My ancestors trained my people with 4 tests that involve ^087FF8knowledge^000000, ^087FF8survival^000000, ^087FF8weapons^000000, and ^087FF8battle^000000.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I know you are curious what these tests are. Let me explain one by one.";
next;
while(1) {
@@ -319,75 +319,75 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
set .@test, .@test | (1<<(.@i-1));
switch (.@i) {
case 1:
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "We need to be knowledgeable in order to assist the lord. This test is for this purpose.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You can pass the test if you successfully solve more than 9 out of 10 questions.";
next;
if (.@test != 15) {
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The test will be easy to pass if you've been steady in your studies. Now what other test are you curious about?";
next;
}
break;
case 2:
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Missions aren't always easy and safe. That is why survival instincts are vital to us.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "My ancestors call this test the dice test. It is a test to advance forward depending on the dice results.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Think of it as the simple dice games people play.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "But never let your guard down during the test because it isn't called the survival test for nothing.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "There will be blocks that help you while there are blocks that will interrupt you.";
next;
if (.@test != 15) {
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "If you deal with various situations wisely, you will be able to pass the test. Now what other test are you curious about?";
next;
}
break;
case 3:
- mes "[Guide Gion]";
- mes "My family was famous for using unique weapons that we created.";
+ mes "[Leader Gion]";
+ mes "My clan was famous for using unique weapons that we created.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You would be considered blessed if you created your own unique weapon.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Creating a weapon for yourself and refining it is the purpose of this test.";
next;
if (.@test != 15) {
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I hope you will be blessed and find the best weapon for yourself. Now what other test are you curious about?";
next;
}
break;
case 4:
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Missions are not always done alone. You will often work in teams of 2 or 3 for a common goal.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The battle test is only for those that pass that knowledge, survival and weapon tests. So! It is the very last test.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Unlike the other three tests that are done alone, you will have to compete with others in this final test.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "There is only one target!!";
mes "And only the first to get to the target passes the test.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You'll be lucky if you have no competitors during your test.";
next;
if (.@test != 15) {
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "A challenge is better than explaining it a hundred times. It's the actual experience that makes you better.";
next;
}
@@ -396,13 +396,13 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
if (.@test == 15) break;
}
cutin "job_ko02",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Seeing is believing, so go on and take the challenge.";
next;
erasequest 5134;
setquest 5135;
set job_kagero,5;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Let's start right away after you are done with preparations.";
close2;
cutin "",255;
@@ -414,110 +414,110 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
set .@ko_test, .@ko_test_01 + .@ko_test_02 + .@ko_test_03;
if (.@ko_test == 0) {
cutin "job_ko03",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "It's been a while.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Since I felt happy like this. I feel young and energetic seeing young people like you challenge themselves with a new path.";
next;
- mes "[Guide Gion]";
- mes "We're done with explaining about the tests, now should I tell you my family story?";
+ mes "[Leader Gion]";
+ mes "We're done with explaining about the tests, now should I tell you my clan story?";
next;
cutin "job_ko01",2;
- mes "[Guide Gion]";
- mes "My family started from two warriors.";
+ mes "[Leader Gion]";
+ mes "My clan started from two warriors.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Kagerou, a warrior like the dancing flames of the sun.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Oboro, a warrior like the misty moonlight.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The Sun and the Moon.";
mes "The sunlight that lights up the world and the moonlight that lights up the night. Both were very similar but different warriors.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "There was a time there was an enmity between both warriors.";
next;
- mes "[Guide Gion]";
- mes "But it didn't take long for them to become one as a family.";
+ mes "[Leader Gion]";
+ mes "But it didn't take long for them to become one as a clan.";
next;
select("How did it go afterwards?");
cutin "job_ko02",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Ha ha ha. It is never fun to listen to the whole story all at once, no? Come back after passing a test and I'll continue my story.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Which test will you select as your first test?";
next;
callsub L_StartTest,select("Test of Knowledge", "Test of Survival", "Test of Weaponry"),1;
end;
} else if (.@ko_test == 2) {
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
if (.@ko_test_01 == 2) {
set .@menu$,":Test of Survival:Test of Weaponry";
mes "You've passed the Test of Knowledge.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "My friend doesn't approve of others that easily but I guess he liked you.";
next;
} else if (.@ko_test_02 == 2) {
set .@menu$,"Test of Knowledge::Test of Weaponry";
mes "You've passed the Test of Survival.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Looks like you went through hell with this test.";
next;
} else if (.@ko_test_03 == 2) {
set .@menu$,"Test of Knowledge:Test of Survival:";
mes "You've passed the Test of Weaponry.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I wonder if Joe is satisfied with your performance.";
next;
}
- select("Please continue with the family story.");
+ select("Please continue with the clan story.");
cutin "job_ko02",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Looks like you are pretty eager to hear more. Where did I leave off... Ah! I remember.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Kagerou, a warrior like the dancing flames of the sun.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Oboro, a warrior like the misty moonlight.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Both warriors weren't close at first, because personality and everything else was completely opposite of each other.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The first place they met was the battlefield. And you know how enemies greet each other on a battlefield.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "They ended up injuring each other badly.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "But what can you do? War is a war.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The friend you've laughed with yesterday is a foe that you have to fight with in a war today.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "So nobody can get along with anyone during a war.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I'll continue the story after you pass another test.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Which test will you choose for the second test?";
next;
callsub L_StartTest,select(.@menu$),2;
end;
} else if (.@ko_test == 4) {
cutin "job_ko04",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
if (.@ko_test_01 == 2 && .@ko_test_02 == 2) {
set .@last_test,3;
mes "You've passed the ^339CCCTests of Knowledge and Survival^000000!";
@@ -529,96 +529,96 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
mes "You've passed the ^339CCCTests of Survival and Weaponry^000000!";
}
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You are already done with two tests. Hope you've learned a lot from them.";
next;
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Shall we continue with the story?";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Kagerou, a warrior like the dancing flames of the sun.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Oboro, a warrior like the misty moonlight.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I think I left off when the two warriors met at the battlefield as enemies.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The long war ended eventually but the wounds and pain of those that survived had just started.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "So these two warriors started to embrace and heal the war wounds together and became one.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "There is a backstory of a man appearing in front of them and winning the loyalty from both warriors.";
next;
select("Who is this man?");
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "There isn't much known about this man. Only a short mentioning of the two warriors pledging their allegiance.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Maybe current generations like me are the ancestors of the current Amatsu lord? But this is only an assumption.";
next;
- mes "[Guide Gion]";
- mes "I'm almost at the end of my family story. Come back after you've passed the third test and I will tell you the rest.";
+ mes "[Leader Gion]";
+ mes "I'm almost at the end of my clan story. Come back after you've passed the third test and I will tell you the rest.";
next;
callsub L_StartTest,.@last_test,3;
end;
} else if (.@ko_test == 6) {
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You've gone through three tests leaving only one to pass.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "As I've told you before, the last test is different because you have to compete against others.";
next;
select("Will you continue the story?");
cutin "job_ko02",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Ha ha ha. I will finish the story.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Kagerou, a warrior like the dancing flames of the sun.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Oboro, a warrior like the misty moonlight.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "It is told that the man that earned the loyalty of the two warriors was a humorous person.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "He like the jokes and conversations better than quarrels and he liked women over men.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Hmm... I don't know why this part of the story was kept alive all these years but this man wanted to bring these two warriors together.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Both warriors did travel together after the war but kept an awkward distance from each other.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "They must have had their reasons but their lord would send them out to a difficult mission together, put them in a secret room together and all sorts of situations together.";
next;
select("Sounds like an odd person.");
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Yes, he was. And his efforts didn't go in vain since the two warriors eventually got acquainted and married.";
next;
- mes "[Guide Gion]";
- mes "This is how the family started.";
+ mes "[Leader Gion]";
+ mes "This is how the clan started.";
next;
select("What happened after?");
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Sadly, the next part of story was purposely discontinued.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I think it's because someone wanted us to let go of the past and move forward.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "That's that. Now shouldn't you be preparing for the last test?";
next;
set job_kagero,6;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "But you must be tired from all the tests so far. Take a rest.";
close2;
cutin "",255;
@@ -631,12 +631,12 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
set .@test_ko$, "Survival";
else if (.@ko_test_03 == 1)
set .@test_ko$, "Weaponry";
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Weren't you taking the Test of " + .@test_ko$ + " just now?";
next;
switch(select("I want to go back to test site.", "Ah... no.")) {
case 1:
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The Test of " + .@test_ko$ + " site is over here.";
close2;
if (.@ko_test_01 == 1)
@@ -647,7 +647,7 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
warp "job_ko",121,129;
end;
case 2:
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The village is over here.";
close2;
warp "amatsu",147,136;
@@ -656,39 +656,39 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
}
} else if (job_kagero == 6) {
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You've come back already? You could have rested more. Is there a reason to hurry?";
next;
input .@inputstr$;
cutin "job_ko03",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Because of ^B24E59" + .@inputstr$ + "^000000?";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I have to admit, I don't understand you now.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "But since you've gone through much, I'm sure you will do good with the final test.";
next;
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Now! No more small talk. I'll let you know what the target is for the Test of Battle.";
next;
- mes "[Guide Gion]";
- mes "The target is a monster called the ^FF0000Family Secret^000000.";
+ mes "[Leader Gion]";
+ mes "The target is a monster called the ^FF0000Clan Secret^000000.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You will have to be careful because there are many similiar shaped and named monsters in test site.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "And if you are lucky, there will be others targeting the monster.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "May the blessings of '" + (Sex == SEX_MALE ? "Kagerou, dancing sun" : "Oboro, misty moonlight") + "' be with you.";
next;
setquest 5146;
set job_kagero,7;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Then let's go to the battle test field.";
close2;
switch(rand(3)) {
@@ -699,12 +699,12 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
end;
} else if (job_kagero == 7 || job_kagero == 8) {
cutin "job_ko03",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I see you are in the middle of the ^339CCCTest of Battle^000000. Will you go back to the test site?";
next;
switch(select("Go back to the test site.", "Visit the village.")) {
case 1:
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The test site is over here.";
close2;
switch(rand(3)) {
@@ -714,7 +714,7 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
}
end;
case 2:
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The village is over here.";
close2;
cutin "",255;
@@ -722,7 +722,7 @@ job_ko,25,115,4 script Old Man#ko 4_M_KAGE_OLD,{
}
} else {
cutin "job_ko03",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You should not be here. Leave!";
close2;
warp "amatsu",147,136;
@@ -737,14 +737,14 @@ L_StartTest:
case 2: set .@str$,"You are taking the ^339CCCTest of %s^000000 as the second test? "; break;
case 3: set .@str$,"Your third test is the ^339CCCTest of %s^000000! "; break;
}
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
switch (getarg(0)) {
case 1:
mes sprintf(.@str$ + "Then I will get to see a familiar face after so long...","Knowledge");
next;
select("Familiar face?");
setquest 5136;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Ha ha ha. You'll know when we get there. The Test of Knowledge is taken over here.";
close2;
warp "job_ko",72,128;
@@ -753,7 +753,7 @@ L_StartTest:
mes sprintf(.@str$ + "It's a lonesome test that you have to face alone.","Survival");
next;
setquest 5137;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "But I believe you can handle it. The Test of Survival is taken over here.";
close2;
warp "job_ko",62,16;
@@ -766,7 +766,7 @@ L_StartTest:
getitem "Phracon", 1;
mes "You receive 5 Iron Ore and 1 Phracon.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You will find these useful. The Test of Weaponry is taken over here.";
close2;
warp "job_ko",121,129;
@@ -775,74 +775,74 @@ L_StartTest:
}
//== Test of Knowledge =====================================
-job_ko,81,124,4 script Cougar#ko 4_M_JOB_ASSASSIN,{
+job_ko,81,124,4 script Kuuga Gai#ko 4_M_JOB_ASSASSIN,{
if (BaseJob != Job_Ninja) {
for (set .@i,5131; .@i<=5146; set .@i,.@i+1)
if (questprogress(.@i)) erasequest .@i;
set job_kagero,0;
- mes "[Cougar]";
- mes "Sorry, your family is not same as ours, is there something wrong?";
+ mes "[Kuuga Gai]";
+ mes "Sorry, your clan is not same as ours, is there something wrong?";
close2;
warp "amatsu",147,136;
end;
}
if (job_kagero == 5) {
if (MaxWeight - Weight < 1000 || checkweight("Knife",1) == 0) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "This is a test of knowledge, so why did you bring so many things?";
close;
}
set .@ko_test_01, questprogress(5136);
set .@ko_test_01_1, questprogress(5139);
if (.@ko_test_01 == 1 && .@ko_test_01_1 == 0) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "It's been a while.";
next;
select("Aren't you...");
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "I remember you from before looking for the way of the ninja.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "You've grown this strong already?";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Ha ha ha-";
mes "A truly determined youth! I like that.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Good! The test you are about to take is the ^339CCCTest of Knowledge^000000.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "I hope you haven't been lazy with your studies while focusing on getting stronger?";
next;
switch(select("Yes", "No")) {
case 1:
setquest 5139;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "That's a relief. Let me know when you are ready to start the test.";
close;
case 2:
setquest 5139;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "So you were all talk? Well, let me know when you are ready then.";
close;
}
} else if (.@ko_test_01 == 1 && .@ko_test_01_1 == 1) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "I'm ready at my end. Are you ready for the test?";
next;
if(select("Yes", "No") == 2) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Well, what can I do but wait for you.";
close;
}
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "This isn't your first test, is it?";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "You only need to choose the correct answer to my questions.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Let's start.";
next;
@@ -862,9 +862,9 @@ job_ko,81,124,4 script Cougar#ko 4_M_JOB_ASSASSIN,{
deletearray .@n[10],getarraysize(.@n) - .@questions;
freeloop(0);
- set @job_ko_cougar,0;
+ set @job_ko_kuuga,0;
for (set .@i,1; .@i<=.@questions; set .@i,.@i+1) {
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes (.@i < .@questions)?"Question number "+.@i+":":"Last question:";
switch (.@n[.@i-1]) {
case 1: callsub L_Question,"What is the DEX + LUK total for a Job Master?",2,"8:10:12:14"; break;
@@ -918,67 +918,67 @@ job_ko,81,124,4 script Cougar#ko 4_M_JOB_ASSASSIN,{
case 49: callsub L_Question,"Which of the following blacksmiths do not create ninja items?",2,"Khaibara:Aiku:Tetsu:Toshu"; break;
case 50: callsub L_Question,"What is the name of the suspicious man you can meet during the Ninja job change quest?",3,"Red Leopard Jack:Black Leopard Jack:Red Leopard Joe:Black Leopard Joe"; break;
default:
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "An unknown error has occurred.";
mes "Please contact customer service.";
close;
}
}
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "You're through all 10 questions. Wasn't so bad! The important part starts now.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "... ... ...";
next;
- if (@job_ko_cougar < 90) {
- mes "[Cougar]";
+ if (@job_ko_kuuga < 90) {
+ mes "[Kuuga Gai]";
mes "You fool!!";
mes "You couldn't even solve these?";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Can't believe someone who is taking a new path can be so pathetic.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "I'll give you another chance.";
mes "You will take the test again with new questions. Better pass it this time.";
} else {
- mes "[Cougar]";
- mes "Hmm. " + (@job_ko_cougar) + "?";
+ mes "[Kuuga Gai]";
+ mes "Hmm. " + (@job_ko_kuuga) + "?";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Well, looks like you weren't lazy with your studies.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "What? Proud of yourself for solving these questions?";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "You still have a long way to go and this is only a small fraction of it.";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Well... I'm curious how far your strong will can take you through other tests.";
next;
completequest 5136;
erasequest 5139;
- mes "[Cougar]";
- mes "I'll let you go now so go report back to Guide Gion with your results.";
+ mes "[Kuuga Gai]";
+ mes "I'll let you go now so go report back to Leader Gion with your results.";
close2;
warp "job_ko",16,113;
end;
}
- set @job_ko_cougar,0;
+ set @job_ko_kuuga,0;
close;
} else if (.@ko_test_01 == 2 && .@ko_test_01_1 == 0) {
- mes "[Cougar]";
- mes "I'll let you go now so go report back to Guide Gion with your results.";
+ mes "[Kuuga Gai]";
+ mes "I'll let you go now so go report back to Leader Gion with your results.";
close2;
warp "job_ko",16,113;
end;
}
}
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "How did you get here?";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "It's my duty to get rid of you.";
mes "^000099(He's a short, silent man.)^000000";
mes "This will push you back!";
@@ -991,7 +991,7 @@ L_Question:
mes getarg(0);
next;
if(select(getarg(2)) == getarg(1))
- set @job_ko_cougar, @job_ko_cougar + 10;
+ set @job_ko_kuuga, @job_ko_kuuga + 10;
return;
}
@@ -1934,7 +1934,7 @@ job_ko,127,125,4 script Red Leopard Joe#ko 4_M_JOB_ASSASSIN,{
if (questprogress(.@i)) erasequest .@i;
set job_kagero,0;
mes "[Red Leopard Joe]";
- mes "Sorry, your family is not the same as ours, is there something wrong?";
+ mes "Sorry, your clan is not the same as ours, is there something wrong?";
close2;
warp "amatsu",147,136;
end;
@@ -1959,17 +1959,17 @@ job_ko,127,125,4 script Red Leopard Joe#ko 4_M_JOB_ASSASSIN,{
next;
select("Long time indeed, Joe.");
mes "[Red Leopard Joe]";
- mes "You aren't surprised I'm here. Did you meet ^0237FDCougar^000000 before coming here?";
+ mes "You aren't surprised I'm here. Did you meet ^0237FDKuuga Gai^000000 before coming here?";
next;
mes "[Red Leopard Joe]";
mes "Don't like it that I'm not the first one you visited but that is not important.";
next;
mes "[Red Leopard Joe]";
mes "Alright, " + strcharinfo(PC_NAME) + "!";
- mes "Welcome to the workshop where weapons are created for the family.";
+ mes "Welcome to the workshop where weapons are created for the clan.";
next;
mes "[Red Leopard Joe]";
- mes "Our family has been creating and using unique weapons to serve our secret missions since ancient times.";
+ mes "Our clan has been creating and using unique weapons to serve our secret missions since ancient times.";
next;
select("Really? At Einbroch?");
mes "[Red Leopard Joe]";
@@ -1979,7 +1979,7 @@ job_ko,127,125,4 script Red Leopard Joe#ko 4_M_JOB_ASSASSIN,{
mes "Yes. Einbroch is known as an industrial city, the city of great blacksmiths create new technology.";
next;
mes "[Red Leopard Joe]";
- mes "My mission is to analyze their technology and report back to the family.";
+ mes "My mission is to analyze their technology and report back to the clan.";
next;
mes "[Red Leopard Joe]";
mes "I spoke more than I intended to.";
@@ -2503,44 +2503,44 @@ job_ko,127,121,0 duplicate(Refinement Tools#ko_01) Refinement Tools#ko_02 CLEAR_
//== Test of Battle ========================================
job_ko,148,46,4 script Guide Gion#ko2 4_M_KAGE_OLD,{
if (MaxWeight - Weight < 2000 || checkweight("Knife",1) == 0) {
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You don't need so many things now!";
close;
}
if (job_kagero == 7) {
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Looks like you haven't taken care of the target yet.";
next;
- mes "[Guide Gion]";
- mes "I'll tell you once more. The target is the ^FF0000Family Secret^000000.";
+ mes "[Leader Gion]";
+ mes "I'll tell you once more. The target is the ^FF0000Clan Secret^000000.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Of course the path will be difficult, so continue searching!";
close2;
cutin "",255;
end;
} else if (job_kagero == 8) {
cutin "job_ko02",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Looks like you've taken care of the target. Hmm.";
next;
if (checkmount()) {
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "But please get down from your frog. Otherwise I can't continue!";
close2;
cutin "",255;
end;
}
if (BaseLevel < 99 || JobLevel < 70) {
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "How did you get weaker? Come back once you've regained your previous levels.";
close2;
cutin "",255;
end;
}
if (SkillPoint != 0) {
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "Please come back after using all your Skill Points.";
close2;
cutin "",255;
@@ -2548,38 +2548,38 @@ job_ko,148,46,4 script Guide Gion#ko2 4_M_KAGE_OLD,{
}
mapannounce "job_ko","[Gion] Interrupting the Test of Battle.",bc_map;
cutin "job_ko04",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "The Test of Battle will be put off for a while. Don't worry because this does not have affect to other tests.";
next;
mapannounce "job_ko","[Gion] My Friend " + strcharinfo(PC_NAME) + " made it to " + (Sex == SEX_MALE ? "Kagerou" : "Oboro") + " Path. Congratulations!!",bc_map;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "My friend " + strcharinfo(PC_NAME) + " made it to " + (Sex == SEX_MALE ? "Kagerou" : "Oboro") + " Path. Congratulations!!";
next;
cutin "job_ko02",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "It is pleasant to meet a youth that is walking through a new path.";
next;
mes "[Someone's Voice]";
mes "Wait for a while, Gion.";
next;
- donpcevent "Cougar#ko2::OnEnable";
+ donpcevent "Kuuga Gai#ko2::OnEnable";
donpcevent "Red Leopard Joe#ko2::OnEnable";
cutin "job_ko04",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I'm sorry I almost forgot about you two. Do you have anything to share with " + strcharinfo(PC_NAME) + "?";
next;
cutin "",255;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "Hmm... Embarrassing... to speak so suddenly...";
next;
- mes "[Cougar]";
- mes strcharinfo(PC_NAME) + ", you are now a proud member of our family. Always hold your head high and...";
+ mes "[Kuuga Gai]";
+ mes strcharinfo(PC_NAME) + ", you are now a proud member of our clan. Always hold your head high and...";
next;
- mes "[Cougar]";
+ mes "[Kuuga Gai]";
mes "^777777(Gai's voice fades out.)^000000.";
mes "I'm sorry I strangled you when we first met.";
next;
- donpcevent "Cougar#ko2::OnDisable";
+ donpcevent "Kuuga Gai#ko2::OnDisable";
mes "[Red Leopard Joe]";
mes "Puhahaha! Gai is all talk. I know I was know valuable to you than that Gai.";
next;
@@ -2600,17 +2600,17 @@ job_ko,148,46,4 script Guide Gion#ko2 4_M_KAGE_OLD,{
mes "I named your weapons on my own but I know you'll like the name.";
next;
mes "[Red Leopard Joe]";
- mes "Guide Gion, please continue.";
+ mes "Leader Gion, please continue.";
next;
cutin "job_ko01",2;
donpcevent "Red Leopard Joe#ko2::OnDisable";
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I don't have much to add because Gai and Joe said it all.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I'm just sorry that the environment of all these tests could have been better for our later generation.";
next;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You only need to look forward and never turn back.";
next;
for (set .@i,5131; .@i<=5146; set .@i,.@i+1)
@@ -2619,21 +2619,21 @@ job_ko,148,46,4 script Guide Gion#ko2 4_M_KAGE_OLD,{
getnameditem .@item,strcharinfo(PC_NAME);
jobchange(Sex == SEX_MALE ? Job_Kagerou : Job_Oboro);
donpcevent "Summon Target#ko::OnEnable";
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I hope the blessings of Kagerou, dancing sun and Oboro, misty moonlight will be with you on your journey ahead.";
close2;
warp "que_ng",21,71;
end;
} else if (job_kagero == 9) {
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "I hope the blessings of Kagerou, dancing sun and Oboro, misty moonlight will be with you on your journey ahead.";
close2;
warp "que_ng",21,71;
end;
} else {
cutin "job_ko01",2;
- mes "[Guide Gion]";
+ mes "[Leader Gion]";
mes "You should not be here. Please leave!";
close2;
warp "amatsu",147,136;
@@ -2641,16 +2641,16 @@ job_ko,148,46,4 script Guide Gion#ko2 4_M_KAGE_OLD,{
}
}
-job_ko,151,47,4 script Cougar#ko2 4_M_JOB_ASSASSIN,{
- mes "[Cougar]";
+job_ko,151,47,4 script Kuuga Gai#ko2 4_M_JOB_ASSASSIN,{
+ mes "[Kuuga Gai]";
mes "Congratulation for choosing the road of development!";
close;
OnInit:
OnDisable:
- disablenpc "Cougar#ko2";
+ disablenpc "Kuuga Gai#ko2";
end;
OnEnable:
- enablenpc "Cougar#ko2";
+ enablenpc "Kuuga Gai#ko2";
end;
}
@@ -2684,7 +2684,7 @@ OnEnable:
case 6: set .@mob,1049; break;
case 7: set .@mob,1050; break;
}
- areamonster "job_ko",120,30,160,70,"Family Secret",.@mob,1,"Summon Target#ko::OnMyMobDead";
+ areamonster "job_ko",120,30,160,70,"Clan Secret",.@mob,1,"Summon Target#ko::OnMyMobDead";
end;
OnDisable:
initnpctimer;
@@ -2706,25 +2706,25 @@ OnInit:
donpcevent "Summon Fake#ko::OnEnable";
end;
OnEnable:
- areamonster "job_ko",120,30,160,70,"Family's Legacy",1002,5,"Summon Fake#ko::OnMyMobDead";
+ areamonster "job_ko",120,30,160,70,"Clan's Legacy",1002,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Kagerou's Memory",1002,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Oboro's Memory",1002,5,"Summon Fake#ko::OnMyMobDead";
- areamonster "job_ko",120,30,160,70,"Family's Mistake",1031,5,"Summon Fake#ko::OnMyMobDead";
+ areamonster "job_ko",120,30,160,70,"Clan's Mistake",1031,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Oboro's Mistake",1031,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Kagerou's Mistake",1031,5,"Summon Fake#ko::OnMyMobDead";
- areamonster "job_ko",120,30,160,70,"Family's Memory",1113,5,"Summon Fake#ko::OnMyMobDead";
+ areamonster "job_ko",120,30,160,70,"Clan's Memory",1113,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Oboro's Past",1113,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Kagerou's Past",1113,5,"Summon Fake#ko::OnMyMobDead";
- areamonster "job_ko",120,30,160,70,"Family's Legacy",1063,5,"Summon Fake#ko::OnMyMobDead";
+ areamonster "job_ko",120,30,160,70,"Clan's Legacy",1063,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Oboro's Legacy",1063,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Kagerou's Legacy",1063,5,"Summon Fake#ko::OnMyMobDead";
- areamonster "job_ko",120,30,160,70,"Family's Mistake",1010,5,"Summon Fake#ko::OnMyMobDead";
+ areamonster "job_ko",120,30,160,70,"Clan's Mistake",1010,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Oboro's Memory",1010,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Kagerou's Memory",1010,5,"Summon Fake#ko::OnMyMobDead";
- areamonster "job_ko",120,30,160,70,"Family's Past",1049,5,"Summon Fake#ko::OnMyMobDead";
+ areamonster "job_ko",120,30,160,70,"Clan's Past",1049,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Oboro's Mistake",1049,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Kagerou's Mistake",1049,5,"Summon Fake#ko::OnMyMobDead";
- areamonster "job_ko",120,30,160,70,"Family's Memory",1050,5,"Summon Fake#ko::OnMyMobDead";
+ areamonster "job_ko",120,30,160,70,"Clan's Memory",1050,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Oboro's Past",1050,5,"Summon Fake#ko::OnMyMobDead";
areamonster "job_ko",120,30,160,70,"Kagerou's Past",1050,5,"Summon Fake#ko::OnMyMobDead";
end;
diff --git a/npc/re/merchants/enchan_mora.txt b/npc/re/merchants/enchan_mora.txt
index 46979c82b..d114a3b61 100644
--- a/npc/re/merchants/enchan_mora.txt
+++ b/npc/re/merchants/enchan_mora.txt
@@ -580,16 +580,16 @@ mora,152,97,5 script Guardian of Power#pa082 4_F_DOGTRAVELER,{
next;
switch(.@job) {
case 0: // Rune Knight
- setarray .@items[0],2475,2476,2574,2575;
- .@i = select("Cancel", "Ur's Greaves (Shoes)", "Peuz's Greaves (Shoes)", "Ur's Manteau (Garment)", "Peuz's Manteau (Garment)")-2;
+ setarray .@items[0],2475,2574,2883,15036,2575,2476,2884,15037;
+ .@i = select("Cancel", "Ur's Greaves (Shoes)", "Ur's Manteau (Garment)", "Ur's Seal (Accessory)", "Ur's Plate (Armor)", "Peuz's Greaves (Shoes)", "Peuz's Manteau (Garment)", "Peuz's Seal (Accessory)", "Peuz's Plate (Armor)" )-2;
break;
case 1: // Guillotine Cross
- setarray .@items[0],2477,2478,2577,2578;
- .@i = select("Cancel", "Sapha Shoes (Shoes)", "Nab Shoes (Shoes)", "Sapha Hood (Garment)", "Nab Hood (Garment)")-2;
+ setarray .@items[0],2477,2577,2886,15038,2478,2578,2887,15039;
+ .@i = select("Cancel", "Sapha Shoes (Shoes)", "Sapha Hood (Garment)", "Sapha Ring (Accessory)", "Sapha's Cloth (Armor)", "Nab Shoes (Shoes)", "Nab Hood (Garment)", "Nab Ring (Accessory)", "Nab's Cloth (Armor)" )-2;
break;
case 2: // Ranger
- setarray .@items[0],2479,2480,2580,2581;
- .@i = select("Cancel", "White Wing Boots (Shoes)", "Black Wing Boots (Shoes)", "White Wing Manteau (Garment)", "Black Wing Manteau (Garment)")-2;
+ setarray .@items[0],2479,2580,2890,15042,2480,2581,2891,15043;
+ .@i = select("Cancel", "White Wing Boots (Shoes)", "White Wing Manteau (Garment)", "White Wing Brooch (Accessory)", "White Wing Suit (Armor)", "Black Wing Boots (Shoes)","Black Wing Manteau (Garment)", "Black Wing Brooch (Accessory)", "Black Wing Suit (Armor)" )-2;
break;
}
if (.@i == -1) {
diff --git a/npc/re/merchants/renters.txt b/npc/re/merchants/renters.txt
index ab6b3f9ac..30d9679b0 100644
--- a/npc/re/merchants/renters.txt
+++ b/npc/re/merchants/renters.txt
@@ -166,60 +166,125 @@ prontera,125,208,5 script Peco Peco Remover 8W_SOLDIER,{
close;
}
-//== Magic Gear Renter =====================================
+//== Mado Gear Renter :: madogear =====================================
- script ::mgm FAKE_NPC,{
- mes "[Magic Gear Master]";
+ mes "[Mado Gear Armorer]";
if (Class == Job_Mechanic || Class == Job_Mechanic_T || Class == Job_Baby_Mechanic) {
mes "Welcome, Mechanic.";
mes "Would you like to rent a Pushcart or";
- mes "ride a Magic Gear?";
+ mes "ride a Mado Gear?";
next;
- switch(select("Rent a Pushcart", "Ride a Magic Gear", "Cancel")) {
+ switch(select("Rent a Pushcart", "Ride a Mado Gear", "Buy Emergency Mado Gear", "Upgrade Cooling Device", "Cancel")) {
case 1:
if (checkcart()) {
- mes "[Magic Gear Master]";
+ mes "[Mado Gear Armorer]";
mes "I'm sorry, but you already";
mes "have a Pushcart.";
close;
}
setcart;
- mes "[Magic Gear Master]";
+ mes "[Mado Gear Armorer]";
mes "There you go!";
close;
case 2:
if (checkmount() == MOUNT_MADO) {
- mes "[Magic Gear Master]";
+ mes "[Mado Gear Armorer]";
mes "I'm sorry, but you're already";
- mes "riding a Magic Gear.";
+ mes "riding a Mado Gear.";
close;
} else if (!getskilllv(NC_MADOLICENCE)) {
- mes "[Magic Gear Master]";
- mes "Please learn the skill to get the Magic Gear License first.";
+ mes "[Mado Gear Armorer]";
+ mes "Please learn the skill to get the Mado Gear License first.";
close;
} else if(hascashmount()) {
- mes "[Magic Gear Master]";
+ mes "[Mado Gear Armorer]";
mes "Please remove your cash mount.";
close;
}
setmount(MOUNT_MADO);
- mes "[Magic Gear Master]";
+ mes "[Mado Gear Armorer]";
mes "Have fun, and please come again!";
close;
case 3:
+ mes "[Mado Gear Armorer]";
+ mes "Emergency Mado Gear is really useful for emergency situations and it is sold at 1,000,000 Zeny.";
+ next;
+ if (select("Purchase", "Cancel") == 2) {
+ mes "[Mado Gear Armorer]";
+ mes "I see. Please feel free to ask me";
+ mes "if you change your mind.";
+ close;
+ }
+ if (countitem(Mado_Box) > 0) {
+ mes "[Mado Gear Armorer]";
+ mes "I'm sorry, but you already have an Emergency Mado Gear.";
+ close;
+ }
+ if (Zeny < 1000000) {
+ mes "[Mado Gear Armorer]";
+ mes "I'm sorry, but you don't have enough Zeny to purchase the Emergency Mado Gear.";
+ close;
+ }
+ Zeny -= 1000000;
+ getitem Mado_Box, 1;
+ mes "[Mado Gear Armorer]";
+ mes "There you go!";
+ close;
+ case 4:
+ mes "[Mado Gear Armorer]";
+ mes "Which device do you want to upgrade?";
+ next;
+ if (select("Cooling Device", "High Quality Cooler") == 1) {
+ mes "[Mado Gear Armorer]";
+ mes "Upgrading Cooling Device to High Quality Cooler needs 1 Cooling Device and 2,000,000 Zeny.";
+ next;
+ .@itemid = Cooling_Device;
+ .@cost = 2000000;
+ } else {
+ mes "[Mado Gear Armorer]";
+ mes "Upgrading High Quality Cooler to Special Cooler needs 1 High Quality Cooler and 4,000,000 Zeny.";
+ next;
+ .@itemid = High_Quality_Cooler;
+ .@cost = 4000000;
+ }
+ if (select("Upgrade", "Cancel") == 2) {
+ mes "[Mado Gear Armorer]";
+ mes "I see. Please feel free to ask me";
+ mes "if you change your mind.";
+ close;
+ }
+ if (!countitem(.@itemid)) {
+ mes "[Mado Gear Armorer]";
+ mes "I'm sorry, but you don't have the " + getitemname(.@itemid) + ".";
+ close;
+ }
+ if (Zeny < .@cost) {
+ mes "[Mado Gear Armorer]";
+ mes "I'm sorry, but you don't have enough Zeny to upgrade the device.";
+ close;
+ }
+ Zeny -= .@cost;
+ delitem .@itemid, 1;
+ getitem (.@itemid == Cooling_Device ? High_Quality_Cooler : Special_Cooler), 1;
+ mes "[Mado Gear Armorer]";
+ mes "Here you are! Your very own " + getitemname(.@itemid) + ".";
+ close;
+ case 5:
close;
}
}
mes "How may I help you?";
- mes "Magic Gears are only available for Mechanics.";
+ mes "Mado Gears are only available for Mechanics.";
close;
}
-prontera,163,178,3 duplicate(mgm) Magic Gear Master#prt 8W_SOLDIER
-geffen,103,55,5 duplicate(mgm) Magic Gear Master#gef 8W_SOLDIER
-payon,166,106,5 duplicate(mgm) Magic Gear Master#pay 8W_SOLDIER
-aldebaran,133,112,5 duplicate(mgm) Magic Gear Master#alde 8W_SOLDIER
-yuno,167,187,3 duplicate(mgm) Magic Gear Master#yuno 8W_SOLDIER
-rachel,106,134,5 duplicate(mgm) Magic Gear Master#ra 8W_SOLDIER
-dicastes01,187,207,3 duplicate(mgm) Magic Gear Master#dic 8W_SOLDIER
-manuk,273,212,5 duplicate(mgm) Magic Gear Master#man 8W_SOLDIER
-splendide,180,174,5 duplicate(mgm) Magic Gear Master#spl 8W_SOLDIER
-mid_camp,242,243,3 duplicate(mgm) Magic Gear Master#mid 8W_SOLDIER
+
+prontera,163,178,3 duplicate(mgm) Mado Gear Armorer#prt 8W_SOLDIER
+geffen,103,55,5 duplicate(mgm) Mado Gear Armorer#gef 8W_SOLDIER
+payon,166,106,5 duplicate(mgm) Mado Gear Armorer#pay 8W_SOLDIER
+aldebaran,133,112,5 duplicate(mgm) Mado Gear Armorer#alde 8W_SOLDIER
+yuno,167,187,3 duplicate(mgm) Mado Gear Armorer#yuno 8W_SOLDIER
+rachel,106,134,5 duplicate(mgm) Mado Gear Armorer#ra 8W_SOLDIER
+dicastes01,187,207,3 duplicate(mgm) Mado Gear Armorer#dic 8W_SOLDIER
+manuk,273,212,5 duplicate(mgm) Mado Gear Armorer#man 8W_SOLDIER
+splendide,180,174,5 duplicate(mgm) Mado Gear Armorer#spl 8W_SOLDIER
+mid_camp,242,243,3 duplicate(mgm) Mado Gear Armorer#mid 8W_SOLDIER
diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql
index c2a017a8d..933ef3815 100644
--- a/sql-files/item_db_re.sql
+++ b/sql-files/item_db_re.sql
@@ -9956,6 +9956,12 @@ REPLACE INTO `item_db` VALUES ('22676','Hangul_Day_Event_Box','Hangul Day Event
REPLACE INTO `item_db` VALUES ('22679','Chest_Of_Death','Death Bin','18','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','170',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('22685','Solo_Christmas_Gift','Single Union Christmas Gift','2','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('22686','Solo_Cookie','Single Cookie','0','0','0','0','50','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','percentheal 5,5;','','');
+REPLACE INTO `item_db` VALUES ('22702','STR_Soul_Potion','STR Reduction Potion','11','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','callfunc(\"F_CashReduceStat\", bStr, -1, STR_Soul_Potion);','','');
+REPLACE INTO `item_db` VALUES ('22703','AGI_Soul_Potion','AGI Reduction Potion','11','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','callfunc(\"F_CashReduceStat\", bAgi, -1, AGI_Soul_Potion);','','');
+REPLACE INTO `item_db` VALUES ('22704','VIT_Soul_Potion','VIT Reduction Potion','11','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','callfunc(\"F_CashReduceStat\", bVit, -1, VIT_Soul_Potion);','','');
+REPLACE INTO `item_db` VALUES ('22705','INT_Soul_Potion','INT Reduction Potion','11','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','callfunc(\"F_CashReduceStat\", bInt, -1, INT_Soul_Potion);','','');
+REPLACE INTO `item_db` VALUES ('22706','DEX_Soul_Potion','DEX Reduction Potion','11','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','callfunc(\"F_CashReduceStat\", bDex, -1, DEX_Soul_Potion);','','');
+REPLACE INTO `item_db` VALUES ('22707','LUK_Soul_Potion','LUK Reduction Potion','11','0','10','5','0','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','callfunc(\"F_CashReduceStat\", bLuk, -1, LUK_Soul_Potion);','','');
REPLACE INTO `item_db` VALUES ('22737','Bullet_Case_Blood_','Bloody Bullet Case','2','0','2','1','250','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','getitem Shell_Of_Blood_, 500;','','');
REPLACE INTO `item_db` VALUES ('22738','Bullet_Case_Silver_','Silver Bullet Case','2','0','2','1','250','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','getitem Silver_Bullet_, 500;','','');
REPLACE INTO `item_db` VALUES ('22739','Sphere_Case_Wind_','Lightning Sphere Pack','2','0','2','1','350','0','0','0','0','0','18446744073709551615','63','2','0','0','0',NULL,'0','1','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','getitem Lighting_Sphere_, 500;','','');
diff --git a/sql-files/main.sql b/sql-files/main.sql
index 241efd39b..e364ec778 100644
--- a/sql-files/main.sql
+++ b/sql-files/main.sql
@@ -241,6 +241,7 @@ CREATE TABLE IF NOT EXISTS `char` (
`uniqueitem_counter` BIGINT(20) UNSIGNED NOT NULL DEFAULT '0',
`sex` ENUM('M','F','U') NOT NULL DEFAULT 'U',
`hotkey_rowshift` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
+ `hotkey_rowshift2` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
`attendance_count` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0',
`attendance_timer` BIGINT(20) NULL DEFAULT '0',
`title_id` INT(11) UNSIGNED NOT NULL DEFAULT '0',
@@ -928,6 +929,7 @@ INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1544738447); -- 2018-12-1
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1546059075); -- 2018-12-29--07-51.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1554760320); -- 2019-04-08--21-52.sql
INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1556147483); -- 2019-04-25--02-12.sql
+INSERT IGNORE INTO `sql_updates` (`timestamp`) VALUES (1557414445); -- 2019-05-09--18-07.sql
--
-- Table structure for table `storage`
diff --git a/sql-files/mob_skill_db.sql b/sql-files/mob_skill_db.sql
index 1610656fb..1e3ab9b90 100644
--- a/sql-files/mob_skill_db.sql
+++ b/sql-files/mob_skill_db.sql
@@ -4402,9 +4402,9 @@ REPLACE INTO `mob_skill_db` VALUES (1838,'Knocker@NPC_GROUNDATTACK','attack',185
REPLACE INTO `mob_skill_db` VALUES (1838,'Knocker@TF_SPRINKLESAND','attack',149,1,1000,0,5000,'yes','target','always',NULL,NULL,NULL,NULL,NULL,NULL,'6',NULL);
REPLACE INTO `mob_skill_db` VALUES (1838,'Knocker@TF_THROWSTONE','chase',152,1,2000,0,10000,'yes','target','always',NULL,NULL,NULL,NULL,NULL,NULL,'29',NULL);
REPLACE INTO `mob_skill_db` VALUES (1838,'Knocker@TF_THROWSTONE','attack',152,1,1000,0,10000,'yes','target','always',NULL,NULL,NULL,NULL,NULL,NULL,'29',NULL);
-REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@NPC_SUMMONSLAVE','idle',196,2,10000,1000,60000,'no','self','slavele','1',1829,1830,NULL,NULL,NULL,NULL,NULL);
-REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@NPC_SUMMONSLAVE','chase',196,2,10000,1000,60000,'no','self','slavele','1',1829,1830,NULL,NULL,NULL,NULL,NULL);
-REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@NPC_SUMMONSLAVE','attack',196,2,10000,1000,60000,'no','self','slavele','1',1829,1830,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@NPC_SUMMONSLAVE','idle',196,2,10000,1000,60000000,'no','self','slavele','1',1829,1830,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@NPC_SUMMONSLAVE','chase',196,2,10000,1000,60000000,'no','self','slavele','1',1829,1830,NULL,NULL,NULL,NULL,NULL);
+REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@NPC_SUMMONSLAVE','attack',196,2,10000,1000,60000000,'no','self','slavele','1',1829,1830,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@NPC_CALLSLAVE','idle',352,1,10000,0,10000,'yes','self','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@SM_BASH','attack',5,5,500,0,5000,'yes','target','always',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
REPLACE INTO `mob_skill_db` VALUES (1839,'Byorgue@AL_TELEPORT','idle',26,1,10000,0,0,'yes','self','rudeattacked',NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL);
diff --git a/sql-files/upgrades/2019-05-09--18-07.sql b/sql-files/upgrades/2019-05-09--18-07.sql
new file mode 100644
index 000000000..96d80c29c
--- /dev/null
+++ b/sql-files/upgrades/2019-05-09--18-07.sql
@@ -0,0 +1,22 @@
+#1557414445
+
+-- This file is part of Hercules.
+-- http://herc.ws - http://github.com/HerculesWS/Hercules
+--
+-- Copyright (C) 2015 Hercules Dev Team
+--
+-- Hercules 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/>.
+
+ALTER TABLE `char` ADD COLUMN `hotkey_rowshift2` TINYINT(3) UNSIGNED NOT NULL DEFAULT '0' AFTER `hotkey_rowshift`;
+INSERT INTO `sql_updates` (`timestamp`) VALUES (1557414445);
diff --git a/sql-files/upgrades/index.txt b/sql-files/upgrades/index.txt
index a820f3b0d..3025a728c 100644
--- a/sql-files/upgrades/index.txt
+++ b/sql-files/upgrades/index.txt
@@ -54,3 +54,4 @@
2018-12-29--07-51.sql
2019-04-08--21-52.sql
2019-04-25--02-12.sql
+2019-05-09--18-07.sql
diff --git a/src/char/char.c b/src/char/char.c
index 44225ecb5..cad28b373 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -477,7 +477,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
(p->look.head_mid != cp->look.head_mid) || (p->look.head_bottom != cp->look.head_bottom) || (p->delete_date != cp->delete_date) ||
(p->rename != cp->rename) || (p->slotchange != cp->slotchange) || (p->look.robe != cp->look.robe) ||
(p->show_equip != cp->show_equip) || (p->allow_party != cp->allow_party) || (p->font != cp->font) ||
- (p->uniqueitem_counter != cp->uniqueitem_counter) || (p->hotkey_rowshift != cp->hotkey_rowshift) ||
+ (p->uniqueitem_counter != cp->uniqueitem_counter) || (p->hotkey_rowshift != cp->hotkey_rowshift) || (p->hotkey_rowshift2 != cp->hotkey_rowshift2) ||
(p->clan_id != cp->clan_id) || (p->last_login != cp->last_login) || (p->attendance_count != cp->attendance_count) ||
(p->attendance_timer != cp->attendance_timer) || (p->title_id != cp->title_id) || (p->inventorySize != cp->inventorySize) ||
(p->allow_call != cp->allow_call)
@@ -507,7 +507,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
"`weapon`='%d',`shield`='%d',`head_top`='%d',`head_mid`='%d',`head_bottom`='%d',"
"`last_map`='%s',`last_x`='%d',`last_y`='%d',`save_map`='%s',`save_x`='%d',`save_y`='%d', `rename`='%d',"
"`delete_date`='%lu',`robe`='%d',`slotchange`='%d', `char_opt`='%u', `font`='%u', `uniqueitem_counter` ='%u',"
- "`hotkey_rowshift`='%d',`clan_id`='%d',`last_login`='%"PRId64"',`attendance_count`='%d',`attendance_timer`='%"PRId64"',"
+ "`hotkey_rowshift`='%d',`hotkey_rowshift2`='%d',`clan_id`='%d',`last_login`='%"PRId64"',`attendance_count`='%d',`attendance_timer`='%"PRId64"',"
"`title_id`='%d', `inventory_size`='%d'"
" WHERE `account_id`='%d' AND `char_id` = '%d'",
char_db, p->base_level, p->job_level,
@@ -520,7 +520,7 @@ static int char_mmo_char_tosql(int char_id, struct mmo_charstatus *p)
mapindex_id2name(p->save_point.map), p->save_point.x, p->save_point.y, p->rename,
(unsigned long)p->delete_date, // FIXME: platform-dependent size
p->look.robe,p->slotchange,opt,p->font,p->uniqueitem_counter,
- p->hotkey_rowshift,p->clan_id,p->last_login, p->attendance_count, p->attendance_timer,
+ p->hotkey_rowshift,p->hotkey_rowshift2,p->clan_id,p->last_login, p->attendance_count, p->attendance_timer,
p->title_id, p->inventorySize,
p->account_id, p->char_id) )
{
@@ -1215,7 +1215,7 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa
"`status_point`,`skill_point`,`option`,`karma`,`manner`,`party_id`,`guild_id`,`pet_id`,`homun_id`,`elemental_id`,`hair`,"
"`hair_color`,`clothes_color`,`body`,`weapon`,`shield`,`head_top`,`head_mid`,`head_bottom`,`last_map`,`last_x`,`last_y`,"
"`save_map`,`save_x`,`save_y`,`partner_id`,`father`,`mother`,`child`,`fame`,`rename`,`delete_date`,`robe`,`slotchange`,"
- "`char_opt`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`clan_id`,`last_login`, `attendance_count`, `attendance_timer`,"
+ "`char_opt`,`font`,`uniqueitem_counter`,`sex`,`hotkey_rowshift`,`hotkey_rowshift2`,`clan_id`,`last_login`, `attendance_count`, `attendance_timer`,"
"`title_id`, `inventory_size`"
" FROM `%s` WHERE `char_id`=? LIMIT 1", char_db)
|| SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT, &char_id, sizeof char_id)
@@ -1279,12 +1279,13 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 56, SQLDT_UINT32, &p->uniqueitem_counter, sizeof p->uniqueitem_counter, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 57, SQLDT_ENUM, &sex, sizeof sex, NULL, NULL)
|| SQL_ERROR == SQL->StmtBindColumn(stmt, 58, SQLDT_UCHAR, &p->hotkey_rowshift, sizeof p->hotkey_rowshift, NULL, NULL)
- || SQL_ERROR == SQL->StmtBindColumn(stmt, 59, SQLDT_INT, &p->clan_id, sizeof p->clan_id, NULL, NULL)
- || SQL_ERROR == SQL->StmtBindColumn(stmt, 60, SQLDT_INT64, &p->last_login, sizeof p->last_login, NULL, NULL)
- || SQL_ERROR == SQL->StmtBindColumn(stmt, 61, SQLDT_SHORT, &p->attendance_count, sizeof p->attendance_count, NULL, NULL)
- || SQL_ERROR == SQL->StmtBindColumn(stmt, 62, SQLDT_INT64, &p->attendance_timer, sizeof p->attendance_timer, NULL, NULL)
- || SQL_ERROR == SQL->StmtBindColumn(stmt, 63, SQLDT_INT, &p->title_id, sizeof p->title_id, NULL, NULL)
- || SQL_ERROR == SQL->StmtBindColumn(stmt, 64, SQLDT_INT, &p->inventorySize, sizeof p->inventorySize, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 59, SQLDT_UCHAR, &p->hotkey_rowshift2, sizeof p->hotkey_rowshift2, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 60, SQLDT_INT, &p->clan_id, sizeof p->clan_id, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 61, SQLDT_INT64, &p->last_login, sizeof p->last_login, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 62, SQLDT_SHORT, &p->attendance_count, sizeof p->attendance_count, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 63, SQLDT_INT64, &p->attendance_timer, sizeof p->attendance_timer, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 64, SQLDT_INT, &p->title_id, sizeof p->title_id, NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 65, SQLDT_INT, &p->inventorySize, sizeof p->inventorySize, NULL, NULL)
) {
SqlStmt_ShowDebug(stmt);
SQL->StmtFree(stmt);
@@ -1415,7 +1416,7 @@ static int char_mmo_char_fromsql(int char_id, struct mmo_charstatus *p, bool loa
while( SQL_SUCCESS == SQL->StmtNextRow(stmt) )
{
- if( hotkey_num >= 0 && hotkey_num < MAX_HOTKEYS )
+ if( hotkey_num >= 0 && hotkey_num < MAX_HOTKEYS_DB )
memcpy(&p->hotkeys[hotkey_num], &tmp_hotkey, sizeof(tmp_hotkey));
else
ShowWarning("chr->mmo_char_fromsql: ignoring invalid hotkey (hotkey=%d,type=%u,id=%u,lv=%u) of character %s (AID=%d,CID=%d)\n", hotkey_num, tmp_hotkey.type, tmp_hotkey.id, tmp_hotkey.lv, p->name, p->account_id, p->char_id);
diff --git a/src/common/HPMDataCheck.h b/src/common/HPMDataCheck.h
index db0594ff6..1e1d8068f 100644
--- a/src/common/HPMDataCheck.h
+++ b/src/common/HPMDataCheck.h
@@ -571,9 +571,6 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "mapcell", sizeof(struct mapcell), SERVER_TYPE_MAP },
{ "mapflag_skill_adjust", sizeof(struct mapflag_skill_adjust), SERVER_TYPE_MAP },
{ "mapit_interface", sizeof(struct mapit_interface), SERVER_TYPE_MAP },
- { "questinfo", sizeof(struct questinfo), SERVER_TYPE_MAP },
- { "questinfo_itemreq", sizeof(struct questinfo_itemreq), SERVER_TYPE_MAP },
- { "questinfo_qreq", sizeof(struct questinfo_qreq), SERVER_TYPE_MAP },
{ "spawn_data", sizeof(struct spawn_data), SERVER_TYPE_MAP },
#else
#define MAP_MAP_H
@@ -781,7 +778,6 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "packet_equipitem_ack", sizeof(struct packet_equipitem_ack), SERVER_TYPE_MAP },
{ "packet_gm_monster_item", sizeof(struct packet_gm_monster_item), SERVER_TYPE_MAP },
{ "packet_graffiti_entry", sizeof(struct packet_graffiti_entry), SERVER_TYPE_MAP },
- { "packet_hotkey", sizeof(struct packet_hotkey), SERVER_TYPE_MAP },
{ "packet_idle_unit", sizeof(struct packet_idle_unit), SERVER_TYPE_MAP },
{ "packet_idle_unit2", sizeof(struct packet_idle_unit2), SERVER_TYPE_MAP },
{ "packet_item_drop_announce", sizeof(struct packet_item_drop_announce), SERVER_TYPE_MAP },
@@ -889,6 +885,9 @@ HPExport const struct s_HPMDataCheck HPMDataCheck[] = {
{ "quest_dropitem", sizeof(struct quest_dropitem), SERVER_TYPE_MAP },
{ "quest_interface", sizeof(struct quest_interface), SERVER_TYPE_MAP },
{ "quest_objective", sizeof(struct quest_objective), SERVER_TYPE_MAP },
+ { "questinfo", sizeof(struct questinfo), SERVER_TYPE_MAP },
+ { "questinfo_itemreq", sizeof(struct questinfo_itemreq), SERVER_TYPE_MAP },
+ { "questinfo_qreq", sizeof(struct questinfo_qreq), SERVER_TYPE_MAP },
#else
#define MAP_QUEST_H
#endif // MAP_QUEST_H
diff --git a/src/common/mmo.h b/src/common/mmo.h
index eb74d62b3..1fa6fadc8 100644
--- a/src/common/mmo.h
+++ b/src/common/mmo.h
@@ -134,22 +134,33 @@
// Comment the following line to disable sc_data saving. [Skotlex]
#define ENABLE_SC_SAVING
-#if PACKETVER >= 20070227
+#if PACKETVER_MAIN_NUM >= 20070711 || PACKETVER_RE_NUM >= 20080827 || PACKETVER_AD_NUM >= 20070711 || PACKETVER_SAK_NUM >= 20070628 || defined(PACKETVER_ZERO)
// Comment the following like to disable server-side hot-key saving support. [Skotlex]
// Note that newer clients no longer save hotkeys in the registry!
#define HOTKEY_SAVING
-#if PACKETVER < 20090603
- // (27 = 9 skills x 3 bars) (0x02b9,191)
- #define MAX_HOTKEYS 27
-#elif PACKETVER < 20090617
- // (36 = 9 skills x 4 bars) (0x07d9,254)
- #define MAX_HOTKEYS 36
-#else // >= 20090617
- // (38 = 9 skills x 4 bars & 2 Quickslots)(0x07d9,268)
- #define MAX_HOTKEYS 38
-#endif // 20090603
-#endif // 20070227
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+#define MAX_HOTKEYS 38
+#elif PACKETVER_MAIN_NUM >= 20141022 || PACKETVER_RE_NUM >= 20141015 || defined(PACKETVER_ZERO)
+// (38 = 9 skills x 4 bars & 2 Quickslots)(0x07d9,268)
+#define MAX_HOTKEYS 38
+#elif PACKETVER_MAIN_NUM >= 20090617 || PACKETVER_RE_NUM >= 20090617 || PACKETVER_SAK_NUM >= 20090617
+// (38 = 9 skills x 4 bars & 2 Quickslots)(0x07d9,268)
+#define MAX_HOTKEYS 38
+#elif PACKETVER_MAIN_NUM >= 20090603 || PACKETVER_RE_NUM >= 20090603 || PACKETVER_SAK_NUM >= 20090603
+// (36 = 9 skills x 4 bars) (0x07d9,254)
+#define MAX_HOTKEYS 36
+#elif PACKETVER_MAIN_NUM >= 20070711 || PACKETVER_RE_NUM >= 20080827 || PACKETVER_AD_NUM >= 20070711 || PACKETVER_SAK_NUM >= 20070628
+// (27 = 9 skills x 3 bars) (0x02b9,191)
+#define MAX_HOTKEYS 27
+#endif
+#endif // PACKETVER_MAIN_NUM >= 20070711 || PACKETVER_RE_NUM >= 20080827 || PACKETVER_AD_NUM >= 20070711 || PACKETVER_SAK_NUM >= 20070628 || defined(PACKETVER_ZERO)
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+#define MAX_HOTKEYS_DB ((MAX_HOTKEYS) * 2)
+#else
+#define MAX_HOTKEYS_DB MAX_HOTKEYS
+#endif
#if PACKETVER >= 20150805 /* Cart Decoration */
#define CART_DECORATION
@@ -732,7 +743,7 @@ struct mmo_charstatus {
struct s_friend friends[MAX_FRIENDS]; //New friend system [Skotlex]
#ifdef HOTKEY_SAVING
- struct hotkey hotkeys[MAX_HOTKEYS];
+ struct hotkey hotkeys[MAX_HOTKEYS_DB];
#endif
bool show_equip;
bool allow_party;
@@ -753,6 +764,7 @@ struct mmo_charstatus {
short attendance_count;
unsigned char hotkey_rowshift;
+ unsigned char hotkey_rowshift2;
int32 title_id; // Achievement Title[Dastgir/Hercules]
};
diff --git a/src/common/packets/packets2019_len_main.h b/src/common/packets/packets2019_len_main.h
index f55db7cd0..3ec006750 100644
--- a/src/common/packets/packets2019_len_main.h
+++ b/src/common/packets/packets2019_len_main.h
@@ -3946,7 +3946,7 @@ packetLen(0x0a85, 82)
packetLen(0x0a86, -1)
// Packet: 0x0a87
-packetLen(0x0a87, -1)
+packetLen(0x0a87, -1) // ZC_BAN_LIST
// Packet: 0x0a88
packetLen(0x0a88, 2) // CZ_COOLDOWN_RESET
@@ -4312,7 +4312,11 @@ packetLen(0x0b02, 26) // AC_REFUSE_LOGIN4
packetLen(0x0b03, -1) // ZC_EQUIPWIN_MICROSCOPE_V7
// Packet: 0x0b04
+#if PACKETVER >= 20190605
+packetLen(0x0b04, 72)
+#elif PACKETVER >= 20190109
packetLen(0x0b04, 80)
+#endif
// Packet: 0x0b05
packetLen(0x0b05, 63) // ZC_OFFLINE_STORE_VISIBLE
@@ -4393,36 +4397,40 @@ packetLen(0x0b1d, 2) // ZC_PING
#endif
// Packet: 0x0b1e
-#if PACKETVER >= 20190227
+#if PACKETVER >= 20190619
+packetLen(0x0b1e, 14)
+#elif PACKETVER >= 20190227
packetLen(0x0b1e, 10)
#endif
// Packet: 0x0b1f
-#if PACKETVER >= 20190306
+#if PACKETVER >= 20190619
+packetLen(0x0b1f, 14)
+#elif PACKETVER >= 20190306
packetLen(0x0b1f, 10)
#endif
// Packet: 0x0b20
#if PACKETVER >= 20190403
-packetLen(0x0b20, 271)
+packetLen(0x0b20, 271) // ZC_SHORTCUT_KEY_LIST_V4
#endif
// Packet: 0x0b21
#if PACKETVER >= 20190403
-packetLen(0x0b21, 13)
+packetLen(0x0b21, 13) // CZ_SHORTCUT_KEY_CHANGE
#elif PACKETVER >= 20190306
// removed
#elif PACKETVER >= 20190227
-packetLen(0x0b21, 10)
+packetLen(0x0b21, 10) // CZ_SHORTCUT_KEY_CHANGE
#endif
// Packet: 0x0b22
#if PACKETVER >= 20190403
-packetLen(0x0b22, 5)
+packetLen(0x0b22, 5) // CZ_SHORTCUTKEYBAR_ROTATE
#elif PACKETVER >= 20190306
// removed
#elif PACKETVER >= 20190227
-packetLen(0x0b22, 6)
+packetLen(0x0b22, 6) // CZ_SHORTCUTKEYBAR_ROTATE
#endif
// Packet: 0x0b23
@@ -4445,9 +4453,86 @@ packetLen(0x0b25, 6)
#endif
// Packet: 0x0b26
-#if PACKETVER >= 20190417
+#if PACKETVER >= 20190522
+// removed
+#elif PACKETVER >= 20190508
+packetLen(0x0b26, 16)
+#elif PACKETVER >= 20190417
packetLen(0x0b26, 18)
#endif
+// Packet: 0x0b27
+#if PACKETVER >= 20190508
+packetLen(0x0b27, -1)
+#endif
+
+// Packet: 0x0b28
+#if PACKETVER >= 20190522
+packetLen(0x0b28, 3)
+#elif PACKETVER >= 20190508
+packetLen(0x0b28, 22)
+#endif
+
+// Packet: 0x0b29
+#if PACKETVER >= 20190605
+// removed
+#elif PACKETVER >= 20190508
+packetLen(0x0b29, 6)
+#endif
+
+// Packet: 0x0b2a
+#if PACKETVER >= 20190605
+// removed
+#elif PACKETVER >= 20190522
+packetLen(0x0b2a, 40)
+#elif PACKETVER >= 20190508
+packetLen(0x0b2a, 6)
+#endif
+
+// Packet: 0x0b2b
+#if PACKETVER >= 20190522
+packetLen(0x0b2b, 11)
+#endif
+
+// Packet: 0x0b2c
+#if PACKETVER >= 20190522
+packetLen(0x0b2c, 3)
+#endif
+
+// Packet: 0x0b2d
+#if PACKETVER >= 20190522
+packetLen(0x0b2d, 11)
+#endif
+
+// Packet: 0x0b2e
+#if PACKETVER >= 20190522
+packetLen(0x0b2e, 4)
+#endif
+
+// Packet: 0x0b2f
+#if PACKETVER >= 20190529
+packetLen(0x0b2f, 73) // ZC_PROPERTY_HOMUN_3
+#endif
+
+// Packet: 0x0b30
+#if PACKETVER >= 20190529
+packetLen(0x0b30, -1)
+#endif
+
+// Packet: 0x0b31
+#if PACKETVER >= 20190619
+packetLen(0x0b31, 17)
+#endif
+
+// Packet: 0x0b32
+#if PACKETVER >= 20190619
+packetLen(0x0b32, -1)
+#endif
+
+// Packet: 0x0b33
+#if PACKETVER >= 20190619
+packetLen(0x0b33, 17)
+#endif
+
#endif /* COMMON_PACKETS2019_LEN_MAIN_H */
diff --git a/src/common/packets/packets2019_len_re.h b/src/common/packets/packets2019_len_re.h
index 2f68261cd..24741a353 100644
--- a/src/common/packets/packets2019_len_re.h
+++ b/src/common/packets/packets2019_len_re.h
@@ -3952,7 +3952,7 @@ packetLen(0x0a85, 82)
packetLen(0x0a86, -1)
// Packet: 0x0a87
-packetLen(0x0a87, -1)
+packetLen(0x0a87, -1) // ZC_BAN_LIST
// Packet: 0x0a88
packetLen(0x0a88, 2) // CZ_COOLDOWN_RESET
@@ -4318,7 +4318,11 @@ packetLen(0x0b02, 26) // AC_REFUSE_LOGIN4
packetLen(0x0b03, -1) // ZC_EQUIPWIN_MICROSCOPE_V7
// Packet: 0x0b04
+#if PACKETVER >= 20190605
+packetLen(0x0b04, 72)
+#elif PACKETVER >= 20190109
packetLen(0x0b04, 80)
+#endif
// Packet: 0x0b05
packetLen(0x0b05, 63) // ZC_OFFLINE_STORE_VISIBLE
@@ -4399,36 +4403,46 @@ packetLen(0x0b1d, 2) // ZC_PING
#endif
// Packet: 0x0b1e
-#if PACKETVER >= 20190227
+#if PACKETVER >= 20190619
+packetLen(0x0b1e, 14)
+#elif PACKETVER >= 20190605
+packetLen(0x0b1e, 14)
+// ignored packet from 2019-06-05hRagexeRE
+#elif PACKETVER >= 20190227
packetLen(0x0b1e, 10)
#endif
// Packet: 0x0b1f
-#if PACKETVER >= 20190306
+#if PACKETVER >= 20190619
+packetLen(0x0b1f, 14)
+#elif PACKETVER >= 20190605
+packetLen(0x0b1f, 14)
+// ignored packet from 2019-06-05hRagexeRE
+#elif PACKETVER >= 20190306
packetLen(0x0b1f, 10)
#endif
// Packet: 0x0b20
#if PACKETVER >= 20190403
-packetLen(0x0b20, 271)
+packetLen(0x0b20, 271) // ZC_SHORTCUT_KEY_LIST_V4
#endif
// Packet: 0x0b21
#if PACKETVER >= 20190403
-packetLen(0x0b21, 13)
+packetLen(0x0b21, 13) // CZ_SHORTCUT_KEY_CHANGE
#elif PACKETVER >= 20190306
// removed
#elif PACKETVER >= 20190227
-packetLen(0x0b21, 10)
+packetLen(0x0b21, 10) // CZ_SHORTCUT_KEY_CHANGE
#endif
// Packet: 0x0b22
#if PACKETVER >= 20190403
-packetLen(0x0b22, 5)
+packetLen(0x0b22, 5) // CZ_SHORTCUTKEYBAR_ROTATE
#elif PACKETVER >= 20190306
// removed
#elif PACKETVER >= 20190227
-packetLen(0x0b22, 6)
+packetLen(0x0b22, 6) // CZ_SHORTCUTKEYBAR_ROTATE
#endif
// Packet: 0x0b23
@@ -4451,9 +4465,86 @@ packetLen(0x0b25, 6)
#endif
// Packet: 0x0b26
-#if PACKETVER >= 20190417
+#if PACKETVER >= 20190522
+// removed
+#elif PACKETVER >= 20190508
+packetLen(0x0b26, 16)
+#elif PACKETVER >= 20190417
packetLen(0x0b26, 18)
#endif
+// Packet: 0x0b27
+#if PACKETVER >= 20190508
+packetLen(0x0b27, -1)
+#endif
+
+// Packet: 0x0b28
+#if PACKETVER >= 20190522
+packetLen(0x0b28, 3)
+#elif PACKETVER >= 20190508
+packetLen(0x0b28, 22)
+#endif
+
+// Packet: 0x0b29
+#if PACKETVER >= 20190605
+// removed
+#elif PACKETVER >= 20190508
+packetLen(0x0b29, 6)
+#endif
+
+// Packet: 0x0b2a
+#if PACKETVER >= 20190605
+// removed
+#elif PACKETVER >= 20190522
+packetLen(0x0b2a, 40)
+#elif PACKETVER >= 20190508
+packetLen(0x0b2a, 6)
+#endif
+
+// Packet: 0x0b2b
+#if PACKETVER >= 20190522
+packetLen(0x0b2b, 11)
+#endif
+
+// Packet: 0x0b2c
+#if PACKETVER >= 20190522
+packetLen(0x0b2c, 3)
+#endif
+
+// Packet: 0x0b2d
+#if PACKETVER >= 20190522
+packetLen(0x0b2d, 11)
+#endif
+
+// Packet: 0x0b2e
+#if PACKETVER >= 20190522
+packetLen(0x0b2e, 4)
+#endif
+
+// Packet: 0x0b2f
+#if PACKETVER >= 20190529
+packetLen(0x0b2f, 73) // ZC_PROPERTY_HOMUN_3
+#endif
+
+// Packet: 0x0b30
+#if PACKETVER >= 20190529
+packetLen(0x0b30, -1)
+#endif
+
+// Packet: 0x0b31
+#if PACKETVER >= 20190619
+packetLen(0x0b31, 17)
+#endif
+
+// Packet: 0x0b32
+#if PACKETVER >= 20190619
+packetLen(0x0b32, -1)
+#endif
+
+// Packet: 0x0b33
+#if PACKETVER >= 20190619
+packetLen(0x0b33, 17)
+#endif
+
#endif /* COMMON_PACKETS2019_LEN_RE_H */
diff --git a/src/common/packets/packets2019_len_zero.h b/src/common/packets/packets2019_len_zero.h
index 24abdb7bd..85824232d 100644
--- a/src/common/packets/packets2019_len_zero.h
+++ b/src/common/packets/packets2019_len_zero.h
@@ -4312,7 +4312,11 @@ packetLen(0x0b02, 26) // AC_REFUSE_LOGIN4
packetLen(0x0b03, -1) // ZC_EQUIPWIN_MICROSCOPE_V7
// Packet: 0x0b04
+#if PACKETVER >= 20190605
+packetLen(0x0b04, 72)
+#elif PACKETVER >= 20190116
packetLen(0x0b04, 80)
+#endif
// Packet: 0x0b05
packetLen(0x0b05, 63) // ZC_OFFLINE_STORE_VISIBLE
@@ -4393,28 +4397,32 @@ packetLen(0x0b1d, 2) // ZC_PING
#endif
// Packet: 0x0b1e
-#if PACKETVER >= 20190313
+#if PACKETVER >= 20190626
+packetLen(0x0b1e, 14)
+#elif PACKETVER >= 20190313
packetLen(0x0b1e, 10)
#endif
// Packet: 0x0b1f
-#if PACKETVER >= 20190313
+#if PACKETVER >= 20190626
+packetLen(0x0b1f, 14)
+#elif PACKETVER >= 20190313
packetLen(0x0b1f, 10)
#endif
// Packet: 0x0b20
#if PACKETVER >= 20190327
-packetLen(0x0b20, 271)
+packetLen(0x0b20, 271) // ZC_SHORTCUT_KEY_LIST_V4
#endif
// Packet: 0x0b21
#if PACKETVER >= 20190327
-packetLen(0x0b21, 13)
+packetLen(0x0b21, 13) // CZ_SHORTCUT_KEY_CHANGE
#endif
// Packet: 0x0b22
#if PACKETVER >= 20190327
-packetLen(0x0b22, 5)
+packetLen(0x0b22, 5) // CZ_SHORTCUTKEYBAR_ROTATE
#endif
// Packet: 0x0b23
@@ -4433,7 +4441,9 @@ packetLen(0x0b25, 6)
#endif
// Packet: 0x0b26
-#if PACKETVER >= 20190424
+#if PACKETVER >= 20190515
+// removed
+#elif PACKETVER >= 20190424
packetLen(0x0b26, 16)
#endif
@@ -4445,23 +4455,81 @@ packetLen(0x0b27, 2)
#endif
// Packet: 0x0b28
-#if PACKETVER >= 20190502
+#if PACKETVER >= 20190515
+packetLen(0x0b28, 3)
+#elif PACKETVER >= 20190502
packetLen(0x0b28, 22)
#elif PACKETVER >= 20190424
packetLen(0x0b28, -1)
#endif
// Packet: 0x0b29
-#if PACKETVER >= 20190502
+#if PACKETVER >= 20190605
+// removed
+#elif PACKETVER >= 20190502
packetLen(0x0b29, 6)
#elif PACKETVER >= 20190424
packetLen(0x0b29, 3)
#endif
// Packet: 0x0b2a
-#if PACKETVER >= 20190502
+#if PACKETVER >= 20190605
+// removed
+#elif PACKETVER >= 20190529
+packetLen(0x0b2a, 40)
+#elif PACKETVER >= 20190502
packetLen(0x0b2a, 6)
#endif
+// Packet: 0x0b2b
+#if PACKETVER >= 20190515
+packetLen(0x0b2b, 11)
+#endif
+
+// Packet: 0x0b2c
+#if PACKETVER >= 20190515
+packetLen(0x0b2c, 3)
+#endif
+
+// Packet: 0x0b2d
+#if PACKETVER >= 20190515
+packetLen(0x0b2d, 11)
+#endif
+
+// Packet: 0x0b2e
+#if PACKETVER >= 20190515
+packetLen(0x0b2e, 4)
+#endif
+
+// Packet: 0x0b2f
+#if PACKETVER >= 20190529
+packetLen(0x0b2f, 73) // ZC_PROPERTY_HOMUN_3
+#endif
+
+// Packet: 0x0b30
+#if PACKETVER >= 20190529
+packetLen(0x0b30, -1)
+#endif
+
+// Packet: 0x0b31
+#if PACKETVER >= 20190626
+packetLen(0x0b31, 17)
+#endif
+
+// Packet: 0x0b32
+#if PACKETVER >= 20190626
+packetLen(0x0b32, -1)
+#endif
+
+// Packet: 0x0b33
+#if PACKETVER >= 20190626
+packetLen(0x0b33, 17)
+#endif
+
+// Packet: 0x0b34
+#if PACKETVER >= 20190626
+packetLen(0x0b34, 26)
+#endif
+
#endif /* COMMON_PACKETS2019_LEN_ZERO_H */
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 68272e67e..3c454011f 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -872,6 +872,11 @@ ACMD(storage)
if (sd->npc_id || sd->state.vending || sd->state.prevend || sd->state.buyingstore || sd->state.trading || sd->state.storage_flag)
return false;
+ if (!pc_has_permission(sd, PC_PERM_BYPASS_NOSTORAGE) && (map->list[sd->bl.m].flag.nostorage & 1)) { // mapflag nostorage already defined? can't open :c
+ clif->message(fd, msg_fd(fd, 1161)); // You currently cannot open your storage.
+ return false;
+ }
+
if (storage->open(sd) == 1) { //Already open.
clif->message(fd, msg_fd(fd,250)); // You have already opened your storage. Close it first.
return false;
@@ -905,6 +910,11 @@ ACMD(guildstorage)
return false;
}
+ if (!pc_has_permission(sd, PC_PERM_BYPASS_NOSTORAGE) && (map->list[sd->bl.m].flag.nogstorage & 1)) { // mapflag nogstorage already defined? can't open :c
+ clif->message(fd, msg_fd(fd, 1161)); // You currently cannot open your storage. (there is no other messages...)
+ return false;
+ }
+
if( gstorage->open(sd) ) {
clif->message(fd, msg_fd(fd,1201)); // Your guild's storage has already been opened by another member, try again later.
return false;
@@ -7789,6 +7799,7 @@ ACMD(mapflag)
CHECKFLAG(nodrop); CHECKFLAG(novending); CHECKFLAG(loadevent);
CHECKFLAG(nochat); CHECKFLAG(partylock); CHECKFLAG(guildlock); CHECKFLAG(src4instance);
CHECKFLAG(notomb); CHECKFLAG(nocashshop); CHECKFLAG(noviewid); CHECKFLAG(town);
+ CHECKFLAG(nostorage); CHECKFLAG(nogstorage);
clif->message(sd->fd," ");
clif->message(sd->fd,msg_fd(fd,1312)); // Usage: "@mapflag monster_noteleport 1" (0=Off | 1=On)
clif->message(sd->fd,msg_fd(fd,1313)); // Type "@mapflag available" to list the available mapflags.
@@ -7830,7 +7841,7 @@ ACMD(mapflag)
SETFLAG(nomvploot); SETFLAG(nightenabled); SETFLAG(nodrop); SETFLAG(novending);
SETFLAG(loadevent); SETFLAG(nochat); SETFLAG(partylock); SETFLAG(guildlock);
SETFLAG(src4instance); SETFLAG(notomb); SETFLAG(nocashshop); SETFLAG(noviewid);
- SETFLAG(town);
+ SETFLAG(town); SETFLAG(nostorage); SETFLAG(nogstorage);
clif->message(sd->fd, msg_fd(fd, 1314)); // Invalid flag name or flag.
@@ -7843,7 +7854,7 @@ ACMD(mapflag)
clif->message(sd->fd, "nozenypenalty, notrade, noskill, nowarp, nowarpto, noicewall, snow, clouds, clouds2,");
clif->message(sd->fd, "fog, fireworks, sakura, leaves, nobaseexp, nojobexp, nomobloot,");
clif->message(sd->fd, "nomvploot, nightenabled, nodrop, novending, loadevent, nochat, partylock,");
- clif->message(sd->fd, "guildlock, src4instance, notomb, nocashshop, noviewid");
+ clif->message(sd->fd, "guildlock, src4instance, notomb, nocashshop, noviewid, nostorage, nogstorage");
#undef CHECKFLAG
#undef SETFLAG
diff --git a/src/map/clif.c b/src/map/clif.c
index 5228f06a3..7c9a68b2b 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1649,7 +1649,9 @@ static void clif_hominfo(struct map_session_data *sd, struct homun_data *hd, int
p.level = hd->homunculus.level;
p.hunger = hd->homunculus.hunger;
p.intimacy = hd->homunculus.intimacy / 100;
+#if !(PACKETVER_MAIN_NUM >= 20190619 || PACKETVER_RE_NUM >= 20190605 || PACKETVER_ZERO_NUM >= 20190626)
p.itemId = 0; // equip id
+#endif
#ifdef RENEWAL
p.atk2 = cap_value(hstatus->rhw.atk2, 0, INT16_MAX);
#else
@@ -3909,20 +3911,16 @@ static void clif_arrow_fail(struct map_session_data *sd, int type)
/// 01ad <packet len>.W { <name id>.W }*
static void clif_arrow_create_list(struct map_session_data *sd)
{
- int i, c;
- int fd;
- int len;
- struct PACKET_ZC_MAKINGARROW_LIST *p;
-
nullpo_retv(sd);
- fd = sd->fd;
- len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ int fd = sd->fd;
+ int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
WFIFOHEAD(fd, len);
- p = WFIFOP(fd, 0);
- p->packetType = 0x1ad;
+ struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0);
+ p->packetType = HEADER_ZC_MAKINGARROW_LIST;
- for (i = 0, c = 0; i < MAX_SKILL_ARROW_DB; i++) {
+ int c = 0;
+ for (int i = 0; i < MAX_SKILL_ARROW_DB; i++) {
int j;
if (skill->dbs->arrow_db[i].nameid > 0
&& (j = pc->search_inventory(sd, skill->dbs->arrow_db[i].nameid)) != INDEX_NOT_FOUND
@@ -9482,7 +9480,8 @@ static void clif_mobname_normal_ack(int fd, struct block_list *bl)
struct PACKET_ZC_ACK_REQNAME_TITLE packet = { 0 };
packet.packet_id = HEADER_ZC_ACK_REQNAME_TITLE;
packet.gid = bl->id;
- memcpy(packet.name, BL_UCCAST(BL_MOB, bl)->db->name, NAME_LENGTH);
+ const struct mob_data *md = BL_UCCAST(BL_MOB, bl);
+ memcpy(packet.name, md->name, NAME_LENGTH);
#if PACKETVER_MAIN_NUM >= 20180207 || PACKETVER_RE_NUM >= 20171129 || PACKETVER_ZERO_NUM >= 20171130
struct unit_data *ud = unit->bl2ud(bl);
if (ud != NULL) {
@@ -10608,7 +10607,7 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
first_time = true;
sd->state.connect_new = 0;
clif->skillinfoblock(sd);
- clif->hotkeys(sd);
+ clif->hotkeysAll(sd);
clif->updatestatus(sd,SP_BASEEXP);
clif->updatestatus(sd,SP_NEXTBASEEXP);
clif->updatestatus(sd,SP_JOBEXP);
@@ -10790,15 +10789,7 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
// NPC Quest / Event Icon Check [Kisuka]
#if PACKETVER >= 20090218
- {
- int i;
- for (i = 0; i < VECTOR_LENGTH(map->list[sd->bl.m].qi_data); i++) {
- struct questinfo *qi = &VECTOR_INDEX(map->list[sd->bl.m].qi_data, i);
-
- if (quest->questinfo_validate(sd, qi))
- clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
- }
- }
+ quest->questinfo_refresh(sd);
#endif
}
@@ -10829,53 +10820,105 @@ static void clif_parse_TickSend(int fd, struct map_session_data *sd)
clif->notify_time(sd, timer->gettick());
}
+static void clif_hotkeysAll_send(struct map_session_data *sd)
+{
+#ifdef HOTKEY_SAVING
+ clif->hotkeys(sd, 0);
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+ // send second tab only if data exists
+ for (int i = MAX_HOTKEYS; i < MAX_HOTKEYS * 2; i++) {
+ if (sd->status.hotkeys[i].type != 0 || sd->status.hotkeys[i].id != 0 || sd->status.hotkeys[i].lv != 0) {
+ clif->hotkeys(sd, 1);
+ return;
+ }
+ }
+#endif
+#endif
+}
+
/// Sends hotkey bar.
/// 02b9 { <is skill>.B <id>.L <count>.W }*27 (ZC_SHORTCUT_KEY_LIST)
/// 07d9 { <is skill>.B <id>.L <count>.W }*36 (ZC_SHORTCUT_KEY_LIST_V2, PACKETVER >= 20090603)
/// 07d9 { <is skill>.B <id>.L <count>.W }*38 (ZC_SHORTCUT_KEY_LIST_V2, PACKETVER >= 20090617)
/// 0a00 <rotate>.B { <is skill>.B <id>.L <count>.W }*38 (ZC_SHORTCUT_KEY_LIST_V3, PACKETVER >= 20141022)
-static void clif_hotkeys_send(struct map_session_data *sd)
+static void clif_hotkeys_send(struct map_session_data *sd, int tab)
{
#ifdef HOTKEY_SAVING
- struct packet_hotkey p;
- int i;
nullpo_retv(sd);
- p.PacketType = hotkeyType;
-#if PACKETVER >= 20141022
- p.Rotate = sd->status.hotkey_rowshift;
+ struct PACKET_ZC_SHORTCUT_KEY_LIST p;
+ p.packetType = HEADER_ZC_SHORTCUT_KEY_LIST;
+#if PACKETVER_MAIN_NUM >= 20141022 || PACKETVER_RE_NUM >= 20141015 || defined(PACKETVER_ZERO)
+ if (tab == 0)
+ p.rotate = sd->status.hotkey_rowshift;
+ else
+ p.rotate = sd->status.hotkey_rowshift2;
+#endif
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+ p.tab = tab;
#endif
- for(i = 0; i < ARRAYLENGTH(p.hotkey); i++) {
- p.hotkey[i].isSkill = sd->status.hotkeys[i].type;
- p.hotkey[i].ID = sd->status.hotkeys[i].id;
- p.hotkey[i].count = sd->status.hotkeys[i].lv;
+ const int offset = tab * MAX_HOTKEYS;
+ for (int i = 0; i < MAX_HOTKEYS_PACKET; i++) {
+ p.hotkey[i].isSkill = sd->status.hotkeys[i + offset].type;
+ p.hotkey[i].id = sd->status.hotkeys[i + offset].id;
+ p.hotkey[i].count = sd->status.hotkeys[i + offset].lv;
}
- clif->send(&p, sizeof(p), &sd->bl, SELF);
+ clif->send(&p, sizeof(struct PACKET_ZC_SHORTCUT_KEY_LIST), &sd->bl, SELF);
#endif
}
-static void clif_parse_HotkeyRowShift(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
-static void clif_parse_HotkeyRowShift(int fd, struct map_session_data *sd)
+static void clif_parse_HotkeyRowShift1(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+static void clif_parse_HotkeyRowShift1(int fd, struct map_session_data *sd)
{
- int cmd = RFIFOW(fd, 0);
- sd->status.hotkey_rowshift = RFIFOB(fd, packet_db[cmd].pos[0]);
+#if PACKETVER_MAIN_NUM >= 20140129 || PACKETVER_RE_NUM >= 20140129 || defined(PACKETVER_ZERO)
+ const struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE1 *p = RFIFOP(fd, 0);
+ sd->status.hotkey_rowshift = p->rowshift;
+#endif
}
-static void clif_parse_Hotkey(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
-/// Request to update a position on the hotkey bar (CZ_SHORTCUT_KEY_CHANGE).
+static void clif_parse_HotkeyRowShift2(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+static void clif_parse_HotkeyRowShift2(int fd, struct map_session_data *sd)
+{
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+ const struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE2 *p = RFIFOP(fd, 0);
+ if (p->tab == 0)
+ sd->status.hotkey_rowshift = p->rowshift;
+ else
+ sd->status.hotkey_rowshift2 = p->rowshift;
+#endif
+}
+
+static void clif_parse_Hotkey1(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+/// Request to update a position on the hotkey bar (CZ_SHORTCUT_KEY_CHANGE1).
/// 02ba <index>.W <is skill>.B <id>.L <count>.W
-static void clif_parse_Hotkey(int fd, struct map_session_data *sd)
+static void clif_parse_Hotkey1(int fd, struct map_session_data *sd)
{
#ifdef HOTKEY_SAVING
- unsigned short idx;
- int cmd;
+#if PACKETVER_MAIN_NUM >= 20070618 || defined(PACKETVER_RE) || defined(PACKETVER_ZERO) || PACKETVER_AD_NUM >= 20070618 || PACKETVER_SAK_NUM >= 20070618
+ const struct PACKET_CZ_SHORTCUT_KEY_CHANGE1 *p = RFIFOP(fd, 0);
+ const unsigned short idx = p->index;
+ Assert_retv(idx < MAX_HOTKEYS);
- cmd = RFIFOW(fd, 0);
- idx = RFIFOW(fd, packet_db[cmd].pos[0]);
- if (idx >= MAX_HOTKEYS) return;
+ sd->status.hotkeys[idx].type = p->hotkey.isSkill;
+ sd->status.hotkeys[idx].id = p->hotkey.id;
+ sd->status.hotkeys[idx].lv = p->hotkey.count;
+#endif
+#endif
+}
- sd->status.hotkeys[idx].type = RFIFOB(fd, packet_db[cmd].pos[1]);
- sd->status.hotkeys[idx].id = RFIFOL(fd, packet_db[cmd].pos[2]);
- sd->status.hotkeys[idx].lv = RFIFOW(fd, packet_db[cmd].pos[3]);
+static void clif_parse_Hotkey2(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
+/// Request to update a position on the hotkey bar (CZ_SHORTCUT_KEY_CHANGE2).
+static void clif_parse_Hotkey2(int fd, struct map_session_data *sd)
+{
+#ifdef HOTKEY_SAVING
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+ const struct PACKET_CZ_SHORTCUT_KEY_CHANGE2 *p = RFIFOP(fd, 0);
+ const unsigned short idx = p->index + p->tab * MAX_HOTKEYS;
+ Assert_retv(idx < MAX_HOTKEYS_DB);
+
+ sd->status.hotkeys[idx].type = p->hotkey.isSkill;
+ sd->status.hotkeys[idx].id = p->hotkey.id;
+ sd->status.hotkeys[idx].lv = p->hotkey.count;
+#endif
#endif
}
@@ -12851,10 +12894,19 @@ static void clif_parse_NpcAmountInput(int fd, struct map_session_data *sd)
int npcid = RFIFOL(fd,2);
int amount = RFIFOL(fd,6);
- if (amount >= 0)
+ if (amount < sd->npc_amount_min) {
+ sd->npc_amount = sd->npc_amount_min;
+ sd->npc_input_capped_range = -1;
+ }
+ else if (amount > sd->npc_amount_max) {
+ sd->npc_amount = sd->npc_amount_max;
+ sd->npc_input_capped_range = 1;
+ }
+ else {
sd->npc_amount = amount;
- else
- sd->npc_amount = 0;
+ sd->npc_input_capped_range = 0;
+ }
+
npc->scriptcont(sd, npcid, false);
}
@@ -18976,27 +19028,30 @@ static void clif_parse_debug(int fd, struct map_session_data *sd)
*------------------------------------------*/
static int clif_elementalconverter_list(struct map_session_data *sd)
{
- int i,c,view,fd;
-
nullpo_ret(sd);
/// Main client packet processing function
- fd=sd->fd;
- WFIFOHEAD(fd, MAX_SKILL_PRODUCE_DB *2+4);
- WFIFOW(fd, 0)=0x1ad;
+ int fd = sd->fd;
+ int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ WFIFOHEAD(fd, len);
+ struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0);
+ p->packetType = HEADER_ZC_MAKINGARROW_LIST;
- for(i=0,c=0;i<MAX_SKILL_PRODUCE_DB;i++){
- if( skill->can_produce_mix(sd,skill->dbs->produce_db[i].nameid,23, 1) ){
- if((view = itemdb_viewid(skill->dbs->produce_db[i].nameid)) > 0)
- WFIFOW(fd,c*2+ 4)= view;
+ int c = 0;
+ for (int i = 0; i < MAX_SKILL_PRODUCE_DB; i++) {
+ if (skill->can_produce_mix(sd,skill->dbs->produce_db[i].nameid,23, 1) ) {
+ int view = itemdb_viewid(skill->dbs->produce_db[i].nameid);
+ if (view > 0)
+ p->items[c].itemId = view;
else
- WFIFOW(fd,c*2+ 4)= skill->dbs->produce_db[i].nameid;
+ p->items[c].itemId = skill->dbs->produce_db[i].nameid;
c++;
}
}
- WFIFOW(fd,2) = c*2+4;
- WFIFOSET(fd, WFIFOW(fd,2));
if (c > 0) {
+ len = c * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ p->packetLength = len;
+ WFIFOSET(fd, len);
sd->menuskill_id = SA_CREATECON;
sd->menuskill_val = c;
}
@@ -19027,33 +19082,33 @@ static void clif_millenniumshield(struct block_list *bl, short shields)
*------------------------------------------*/
static int clif_spellbook_list(struct map_session_data *sd)
{
- int i, c;
- int fd;
-
nullpo_ret(sd);
- fd = sd->fd;
- WFIFOHEAD(fd, 8 * 8 + 8);
- WFIFOW(fd,0) = 0x1ad;
+ int fd = sd->fd;
+ int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ WFIFOHEAD(fd, len);
+ struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0);
+ p->packetType = HEADER_ZC_MAKINGARROW_LIST;
- for (i = 0, c = 0; i < sd->status.inventorySize; i ++ )
+ int c = 0;
+ for (int i = 0; i < sd->status.inventorySize; i ++ )
{
- if( itemdb_is_spellbook(sd->status.inventory[i].nameid) )
+ if (itemdb_is_spellbook(sd->status.inventory[i].nameid))
{
- WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
+ p->items[c].itemId = sd->status.inventory[i].nameid;
c++;
}
}
- if( c > 0 )
+ if (c > 0)
{
- WFIFOW(fd,2) = c * 2 + 4;
- WFIFOSET(fd, WFIFOW(fd, 2));
+ len = c * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ p->packetLength = len;
+ WFIFOSET(fd, len);
sd->menuskill_id = WL_READING_SB;
sd->menuskill_val = c;
- }
- else{
- status_change_end(&sd->bl,SC_STOP,INVALID_TIMER);
+ } else {
+ status_change_end(&sd->bl, SC_STOP, INVALID_TIMER);
clif->skill_fail(sd, WL_READING_SB, USESKILL_FAIL_SPELLBOOK, 0, 0);
}
@@ -19068,17 +19123,18 @@ static int clif_spellbook_list(struct map_session_data *sd)
static int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, short x, short y)
{
int i, c;
- int fd;
nullpo_ret(sd);
- fd = sd->fd;
- WFIFOHEAD(fd, 8 * 8 + 8);
- WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil]
+ int fd = sd->fd;
+ int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ WFIFOHEAD(fd, len);
+ struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0);
+ p->packetType = HEADER_ZC_MAKINGARROW_LIST;
for (i = 0, c = 0; i < sd->status.inventorySize; i ++) {
- if( itemdb_is_element(sd->status.inventory[i].nameid) ) {
- WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
+ if (itemdb_is_element(sd->status.inventory[i].nameid)) {
+ p->items[c].itemId = sd->status.inventory[i].nameid;
c ++;
}
}
@@ -19087,8 +19143,10 @@ static int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, sh
sd->menuskill_val = skill_lv;
sd->sc.comet_x = x;
sd->sc.comet_y = y;
- WFIFOW(fd,2) = c * 2 + 4;
- WFIFOSET(fd, WFIFOW(fd, 2));
+
+ len = c * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ p->packetLength = len;
+ WFIFOSET(fd, len);
} else {
clif->skill_fail(sd, NC_MAGICDECOY, USESKILL_FAIL_LEVEL, 0, 0);
return 0;
@@ -19105,25 +19163,28 @@ static int clif_magicdecoy_list(struct map_session_data *sd, uint16 skill_lv, sh
static int clif_poison_list(struct map_session_data *sd, uint16 skill_lv)
{
int i, c;
- int fd;
nullpo_ret(sd);
- fd = sd->fd;
- WFIFOHEAD(fd, 8 * 8 + 8);
- WFIFOW(fd,0) = 0x1ad; // This is the official packet. [pakpil]
+ int fd = sd->fd;
+ int len = MAX_SKILL_ARROW_DB * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ WFIFOHEAD(fd, len);
+ struct PACKET_ZC_MAKINGARROW_LIST *p = WFIFOP(fd, 0);
+ p->packetType = HEADER_ZC_MAKINGARROW_LIST;
for (i = 0, c = 0; i < sd->status.inventorySize; i ++) {
if( itemdb_is_poison(sd->status.inventory[i].nameid) ) {
- WFIFOW(fd, c * 2 + 4) = sd->status.inventory[i].nameid;
+ p->items[c].itemId = sd->status.inventory[i].nameid;
c ++;
}
}
- if( c > 0 ) {
+ if (c > 0) {
sd->menuskill_id = GC_POISONINGWEAPON;
sd->menuskill_val = skill_lv;
- WFIFOW(fd,2) = c * 2 + 4;
- WFIFOSET(fd, WFIFOW(fd, 2));
+
+ len = c * sizeof(struct PACKET_ZC_MAKINGARROW_LIST_sub) + sizeof(struct PACKET_ZC_MAKINGARROW_LIST);
+ p->packetLength = len;
+ WFIFOSET(fd, len);
} else {
clif->skill_fail(sd, GC_POISONINGWEAPON, USESKILL_FAIL_GUILLONTINE_POISON, 0, 0);
return 0;
@@ -22484,7 +22545,7 @@ static void clif_parse_ping(int fd, struct map_session_data *sd)
static void clif_ping(struct map_session_data *sd)
{
-#if PACKETVER_MAIN_NUM >= 20190213 || PACKETVER_RE_NUM >= 20190213 || PACKETVER_ZERO_NUM >= 20190130
+#if PACKETVER_MAIN_NUM >= 20190227 || PACKETVER_RE_NUM >= 20190220 || PACKETVER_ZERO_NUM >= 20190220
nullpo_retv(sd);
struct PACKET_ZC_PING p;
p.packetType = HEADER_ZC_PING;
@@ -23069,6 +23130,7 @@ void clif_defaults(void)
clif->pRanklist = clif_parse_ranklist;
clif->update_rankingpoint = clif_update_rankingpoint;
clif->hotkeys = clif_hotkeys_send;
+ clif->hotkeysAll = clif_hotkeysAll_send;
clif->insight = clif_insight;
clif->outsight = clif_outsight;
clif->skillcastcancel = clif_skillcastcancel;
@@ -23508,7 +23570,8 @@ void clif_defaults(void)
clif->pWantToConnection = clif_parse_WantToConnection;
clif->pLoadEndAck = clif_parse_LoadEndAck;
clif->pTickSend = clif_parse_TickSend;
- clif->pHotkey = clif_parse_Hotkey;
+ clif->pHotkey1 = clif_parse_Hotkey1;
+ clif->pHotkey2 = clif_parse_Hotkey2;
clif->pProgressbar = clif_parse_progressbar;
clif->pWalkToXY = clif_parse_WalkToXY;
clif->pQuitGame = clif_parse_QuitGame;
@@ -23751,7 +23814,8 @@ void clif_defaults(void)
clif->pNPCMarketPurchase = clif_parse_NPCMarketPurchase;
/* */
clif->add_item_options = clif_add_item_options;
- clif->pHotkeyRowShift = clif_parse_HotkeyRowShift;
+ clif->pHotkeyRowShift1 = clif_parse_HotkeyRowShift1;
+ clif->pHotkeyRowShift2 = clif_parse_HotkeyRowShift2;
clif->dressroom_open = clif_dressroom_open;
clif->pOneClick_ItemIdentify = clif_parse_OneClick_ItemIdentify;
/* Achievements [Smokexyz/Hercules] */
diff --git a/src/map/clif.h b/src/map/clif.h
index 19c321ed3..5c28f80dd 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -851,7 +851,8 @@ struct clif_interface {
void (*ranklist) (struct map_session_data *sd, enum fame_list_type type);
void (*update_rankingpoint) (struct map_session_data *sd, enum fame_list_type type, int points);
void (*pRanklist) (int fd, struct map_session_data *sd);
- void (*hotkeys) (struct map_session_data *sd);
+ void (*hotkeys) (struct map_session_data *sd, int tab);
+ void (*hotkeysAll) (struct map_session_data *sd);
int (*insight) (struct block_list *bl,va_list ap);
int (*outsight) (struct block_list *bl,va_list ap);
void (*skillcastcancel) (struct block_list* bl);
@@ -1288,7 +1289,8 @@ struct clif_interface {
void (*pWantToConnection) (int fd, struct map_session_data *sd);
void (*pLoadEndAck) (int fd,struct map_session_data *sd);
void (*pTickSend) (int fd, struct map_session_data *sd);
- void (*pHotkey) (int fd, struct map_session_data *sd);
+ void (*pHotkey1) (int fd, struct map_session_data *sd);
+ void (*pHotkey2) (int fd, struct map_session_data *sd);
void (*pProgressbar) (int fd, struct map_session_data * sd);
void (*pWalkToXY) (int fd, struct map_session_data *sd);
void (*pQuitGame) (int fd, struct map_session_data *sd);
@@ -1526,7 +1528,8 @@ struct clif_interface {
void (*pNPCMarketPurchase) (int fd, struct map_session_data *sd);
/* */
int (*add_item_options) (struct ItemOptions *buf, const struct item *it);
- void (*pHotkeyRowShift) (int fd, struct map_session_data *sd);
+ void (*pHotkeyRowShift1) (int fd, struct map_session_data *sd);
+ void (*pHotkeyRowShift2) (int fd, struct map_session_data *sd);
void (*dressroom_open) (struct map_session_data *sd, int view);
void (*pOneClick_ItemIdentify) (int fd,struct map_session_data *sd);
/* Cart Deco */
diff --git a/src/map/instance.c b/src/map/instance.c
index 1e83b0b76..e87cc03bb 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -295,13 +295,6 @@ static int instance_add_map(const char *name, int instance_id, bool usebasename,
}
}
- //Mimic questinfo
- VECTOR_INIT(map->list[im].qi_data);
- VECTOR_ENSURE(map->list[im].qi_data, VECTOR_LENGTH(map->list[m].qi_data), 1);
- for (i = 0; i < VECTOR_LENGTH(map->list[m].qi_data); i++) {
- VECTOR_PUSH(map->list[im].qi_data, VECTOR_INDEX(map->list[m].qi_data, i));
- }
-
map->list[im].m = im;
map->list[im].instance_id = instance_id;
map->list[im].instance_src_map = m;
@@ -518,7 +511,7 @@ static void instance_del_map(int16 m)
aFree(map->list[m].zone_mf);
}
- quest->questinfo_vector_clear(m);
+ VECTOR_CLEAR(map->list[m].qi_list);
// Remove from instance
for( i = 0; i < instance->list[map->list[m].instance_id].num_map; i++ ) {
diff --git a/src/map/itemdb.c b/src/map/itemdb.c
index 11d778f8a..8caf88a4e 100644
--- a/src/map/itemdb.c
+++ b/src/map/itemdb.c
@@ -2449,6 +2449,8 @@ static void itemdb_read(bool minimal)
itemdb->other->foreach(itemdb->other, itemdb->addname_sub);
+ itemdb->read_options();
+
if (minimal)
return;
@@ -2458,7 +2460,6 @@ static void itemdb_read(bool minimal)
itemdb->read_groups();
itemdb->read_chains();
itemdb->read_packages();
- itemdb->read_options();
}
/**
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index e032def0c..f66abe066 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -521,7 +521,8 @@ struct item_data {
unsigned no_refine : 1; // [celest]
unsigned delay_consume : 1; ///< Signifies items that are not consumed immediately upon double-click [Skotlex]
unsigned trade_restriction : 9; ///< Item trade restrictions mask (@see enum ItemTradeRestrictions)
- unsigned autoequip: 1;
+ unsigned autoequip : 1;
+ unsigned auto_favorite : 1;
unsigned buyingstore : 1;
unsigned bindonequip : 1;
unsigned keepafteruse : 1;
diff --git a/src/map/map.c b/src/map/map.c
index 2b95ec27a..f92be52e9 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -3586,23 +3586,27 @@ static void map_zone_db_clear(void)
}
static void map_clean(int i)
{
- int v;
Assert_retv(i >= 0 && i < map->count);
- if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf) aFree(map->list[i].cell);
- if(map->list[i].block) aFree(map->list[i].block);
- if(map->list[i].block_mob) aFree(map->list[i].block_mob);
- if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
- int j;
- if(map->list[i].mob_delete_timer != INVALID_TIMER)
+ if (map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf)
+ aFree(map->list[i].cell);
+ if (map->list[i].block)
+ aFree(map->list[i].block);
+ if (map->list[i].block_mob)
+ aFree(map->list[i].block_mob);
+
+ if (battle_config.dynamic_mobs != 0) { //Dynamic mobs flag by [random]
+ if (map->list[i].mob_delete_timer != INVALID_TIMER)
timer->delete(map->list[i].mob_delete_timer, map->removemobs_timer);
- for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
- if (map->list[i].moblist[j]) aFree(map->list[i].moblist[j]);
+ for (int j = 0; j < MAX_MOB_LIST_PER_MAP; j++) {
+ if (map->list[i].moblist[j] != NULL)
+ aFree(map->list[i].moblist[j]);
+ }
}
- if( map->list[i].unit_count ) {
- if( map->list[i].units ) {
- for(v = 0; v < map->list[i].unit_count; v++) {
+ if (map->list[i].unit_count != 0) {
+ if (map->list[i].units != NULL) {
+ for (int v = 0; v < map->list[i].unit_count; v++) {
aFree(map->list[i].units[v]);
}
aFree(map->list[i].units);
@@ -3611,98 +3615,44 @@ static void map_clean(int i)
map->list[i].unit_count = 0;
}
- if( map->list[i].skill_count ) {
- if( map->list[i].skills ) {
- for(v = 0; v < map->list[i].skill_count; v++) {
- aFree(map->list[i].skills[v]);
- }
+ if (map->list[i].skill_count != 0) {
+ if (map->list[i].skills != NULL) {
+ for (int v = 0; v < map->list[i].skill_count; v++) {
+ aFree(map->list[i].skills[v]);
+ }
aFree(map->list[i].skills);
map->list[i].skills = NULL;
}
map->list[i].skill_count = 0;
}
- if( map->list[i].zone_mf_count ) {
- if( map->list[i].zone_mf ) {
- for(v = 0; v < map->list[i].zone_mf_count; v++) {
- aFree(map->list[i].zone_mf[v]);
- }
+ if (map->list[i].zone_mf_count != 0) {
+ if (map->list[i].zone_mf != NULL) {
+ for (int v = 0; v < map->list[i].zone_mf_count; v++) {
+ aFree(map->list[i].zone_mf[v]);
+ }
aFree(map->list[i].zone_mf);
map->list[i].zone_mf = NULL;
}
map->list[i].zone_mf_count = 0;
}
- if( map->list[i].channel )
+ if (map->list[i].drop_list_count != 0)
+ map->list[i].drop_list_count = 0;
+ if (map->list[i].drop_list != NULL)
+ aFree(map->list[i].drop_list);
+
+ if (map->list[i].channel != NULL)
channel->delete(map->list[i].channel);
+
+ VECTOR_CLEAR(map->list[i].qi_list);
+ HPM->data_store_destroy(&map->list[i].hdata);
}
static void do_final_maps(void)
{
- int i, v = 0;
-
- for( i = 0; i < map->count; i++ ) {
-
- if(map->list[i].cell && map->list[i].cell != (struct mapcell *)0xdeadbeaf ) aFree(map->list[i].cell);
- if(map->list[i].block) aFree(map->list[i].block);
- if(map->list[i].block_mob) aFree(map->list[i].block_mob);
-
- if(battle_config.dynamic_mobs) { //Dynamic mobs flag by [random]
- int j;
- if(map->list[i].mob_delete_timer != INVALID_TIMER)
- timer->delete(map->list[i].mob_delete_timer, map->removemobs_timer);
- for (j=0; j<MAX_MOB_LIST_PER_MAP; j++)
- if (map->list[i].moblist[j]) aFree(map->list[i].moblist[j]);
- }
-
- if( map->list[i].unit_count ) {
- if( map->list[i].units ) {
- for(v = 0; v < map->list[i].unit_count; v++) {
- aFree(map->list[i].units[v]);
- }
- aFree(map->list[i].units);
- map->list[i].units = NULL;
- }
- map->list[i].unit_count = 0;
- }
-
- if( map->list[i].skill_count ) {
- if( map->list[i].skills ) {
- for(v = 0; v < map->list[i].skill_count; v++) {
- aFree(map->list[i].skills[v]);
- }
- aFree(map->list[i].skills);
- map->list[i].skills = NULL;
- }
- map->list[i].skill_count = 0;
- }
-
- if( map->list[i].zone_mf_count ) {
- if( map->list[i].zone_mf ) {
- for(v = 0; v < map->list[i].zone_mf_count; v++) {
- aFree(map->list[i].zone_mf[v]);
- }
- aFree(map->list[i].zone_mf);
- map->list[i].zone_mf = NULL;
- }
- map->list[i].zone_mf_count = 0;
- }
-
- if( map->list[i].drop_list_count ) {
- map->list[i].drop_list_count = 0;
- }
- if( map->list[i].drop_list != NULL )
- aFree(map->list[i].drop_list);
-
- if( map->list[i].channel )
- channel->delete(map->list[i].channel);
-
- quest->questinfo_vector_clear(i);
-
- HPM->data_store_destroy(&map->list[i].hdata);
- }
-
+ for (int i = 0; i < map->count; i++)
+ map->clean(i);
map->zone_db_clear();
-
}
static void map_zonedb_reload(void)
@@ -3793,7 +3743,8 @@ static void map_flags_init(void)
map->list[i].short_damage_rate = 100;
map->list[i].long_damage_rate = 100;
- VECTOR_INIT(map->list[i].qi_data);
+ VECTOR_CLEAR(map->list[i].qi_list);
+ VECTOR_INIT(map->list[i].qi_list);
}
}
@@ -5428,6 +5379,32 @@ static bool map_zone_mf_cache(int m, char *flag, char *params)
else if( map->list[m].flag.nocashshop )
map_zone_mf_cache_add(m,"nocashshop");
}
+ } else if (strcmpi(flag, "nostorage") == 0) {
+ if (!state) {
+ if (map->list[m].flag.nostorage != 0) {
+ sprintf(rflag, "nostorage\t%d", map->list[m].flag.nostorage);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
+ if (sscanf(params, "%d", &state) == 1) {
+ if (state != map->list[m].flag.nostorage) {
+ sprintf(rflag, "nostorage\t%d", state);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
+ } else if (strcmpi(flag, "nogstorage") == 0) {
+ if (!state) {
+ if (map->list[m].flag.nogstorage != 0) {
+ sprintf(rflag, "nogstorage\t%d", map->list[m].flag.nogstorage);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
+ if (sscanf(params, "%d", &state) == 1) {
+ if (state != map->list[m].flag.nogstorage) {
+ sprintf(rflag, "nogstorage\t%d", state);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
}
return false;
@@ -6029,28 +6006,30 @@ static int map_get_new_bonus_id(void)
return map->bonus_id++;
}
-static void map_add_questinfo(int m, struct questinfo *qi)
+static bool map_add_questinfo(int m, struct npc_data *nd)
{
- nullpo_retv(qi);
- Assert_retv(m >= 0 && m < map->count);
+ nullpo_retr(false, nd);
+ Assert_retr(false, m >= 0 && m < map->count);
- VECTOR_ENSURE(map->list[m].qi_data, 1, 1);
- VECTOR_PUSH(map->list[m].qi_data, *qi);
+ if (&VECTOR_LAST(map->list[m].qi_list) == nd)
+ return false;
+
+ VECTOR_ENSURE(map->list[m].qi_list, 1, 1);
+ VECTOR_PUSH(map->list[m].qi_list, *nd);
+ return true;
}
static bool map_remove_questinfo(int m, struct npc_data *nd)
{
- unsigned short i;
nullpo_retr(false, nd);
Assert_retr(false, m >= 0 && m < map->count);
- for (i = 0; i < VECTOR_LENGTH(map->list[m].qi_data); i++) {
- struct questinfo *qi_data = &VECTOR_INDEX(map->list[m].qi_data, i);
- if (qi_data->nd == nd) {
- VECTOR_ERASE(map->list[m].qi_data, i);
- return true;
- }
+ int i;
+ ARR_FIND(0, VECTOR_LENGTH(map->list[m].qi_list), i, &VECTOR_INDEX(map->list[m].qi_list, i) == nd);
+ if (i != VECTOR_LENGTH(map->list[m].qi_list)) {
+ VECTOR_ERASE(map->list[m].qi_list, i);
+ return true;
}
return false;
}
diff --git a/src/map/map.h b/src/map/map.h
index 1f70680e8..39eb07e4c 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -705,41 +705,6 @@ struct map_drop_list {
int drop_per;
};
-struct questinfo_qreq {
- int id;
- int state;
-};
-
-struct questinfo_itemreq {
- int nameid;
- int min;
- int max;
-};
-
-struct questinfo {
- struct npc_data *nd;
- unsigned short icon;
- unsigned char color;
- bool hasJob;
- unsigned int job;/* perhaps a mapid mask would be most flexible? */
- bool sex_enabled;
- int sex;
- struct {
- int min;
- int max;
- } base_level;
- struct {
- int min;
- int max;
- } job_level;
- VECTOR_DECL(struct questinfo_itemreq) items;
- struct s_homunculus homunculus;
- int homunculus_type;
- VECTOR_DECL(struct questinfo_qreq) quest_requirement;
- int mercenary_class;
-};
-
-
struct map_data {
char name[MAP_NAME_LENGTH];
uint16 index; // The map index used by the mapindex* functions.
@@ -820,6 +785,8 @@ struct map_data {
unsigned noautoloot : 1;
unsigned pairship_startable : 1;
unsigned pairship_endable : 1;
+ unsigned nostorage : 2;
+ unsigned nogstorage : 2;
uint32 noviewid; ///< noviewid (bitmask - @see enum equip_pos)
} flag;
struct point save;
@@ -877,8 +844,8 @@ struct map_data {
int len;
} cell_buf;
- /* ShowEvent Data Cache */
- VECTOR_DECL(struct questinfo) qi_data;
+ /* questinfo entries list */
+ VECTOR_DECL(struct npc_data) qi_list;
/* speeds up clif_updatestatus processing by causing hpmeter to run only when someone with the permission can view it */
unsigned short hpmeter_visible;
@@ -1312,7 +1279,7 @@ END_ZEROED_BLOCK;
int (*abort_sub) (struct map_session_data *sd, va_list ap);
void (*update_cell_bl) (struct block_list *bl, bool increase);
int (*get_new_bonus_id) (void);
- void (*add_questinfo) (int m, struct questinfo *qi);
+ bool (*add_questinfo) (int m, struct npc_data *nd);
bool (*remove_questinfo) (int m, struct npc_data *nd);
struct map_zone_data *(*merge_zone) (struct map_zone_data *main, struct map_zone_data *other);
void (*zone_clear_single) (struct map_zone_data *zone);
diff --git a/src/map/messages_main.h b/src/map/messages_main.h
index 802621eb2..5057071a8 100644
--- a/src/map/messages_main.h
+++ b/src/map/messages_main.h
@@ -24,7 +24,7 @@
/* This file is autogenerated, please do not commit manual changes
-Latest version: 20190418
+Latest version: 20190619
*/
enum clif_messages {
@@ -21615,6 +21615,127 @@ Please try again in a moment.
*/
MSG_ID_E19 = 0xe19,
#endif
+#if PACKETVER >= 20190508
+/*20190508 to latest
+자유이동권
+*/
+ MSG_ID_E1A = 0xe1a,
+/*20190508 to latest
+%d시간 이용, %s %d개
+*/
+ MSG_ID_E1B = 0xe1b,
+/*20190508 to latest
+자유이용권 사용중
+*/
+ MSG_ID_E1C = 0xe1c,
+/*20190508 to latest
+특성 스테이터스
+*/
+ MSG_ID_E1D = 0xe1d,
+/*20190508 to latest
+파워 파라메터
+^cc0000물리 공격력, 특성 공격력^ffffff 증가
+*/
+ MSG_ID_E1E = 0xe1e,
+/*20190508 to latest
+스테미나 파라메터
+^cc0000물리 저항력^ffffff 증가
+*/
+ MSG_ID_E1F = 0xe1f,
+/*20190508 to latest
+위즈덤 파라메터
+^cc0000마법 저항력^ffffff 증가
+*/
+ MSG_ID_E20 = 0xe20,
+/*20190508 to latest
+스펠 파라메터
+^cc0000마법 공격력, 마법 공격력^ffffff 증가
+*/
+ MSG_ID_E21 = 0xe21,
+/*20190508 to latest
+컨센트레이션 파라메터
+^cc0000명중률, 회피율, 특성 물리/마법 공격력^ffffff 증가
+*/
+ MSG_ID_E22 = 0xe22,
+/*20190508 to latest
+크리에이티브 파라메터
+^cc0000특성 힐 회복량, 크리티컬 데미지 비율^ffffff 증가
+*/
+ MSG_ID_E23 = 0xe23,
+/*20190508 to latest
+특성 물리 공격력
+*/
+ MSG_ID_E24 = 0xe24,
+/*20190508 to latest
+특성 마법 공격력
+*/
+ MSG_ID_E25 = 0xe25,
+/*20190508 to latest
+물리 저항력
+*/
+ MSG_ID_E26 = 0xe26,
+/*20190508 to latest
+마법 저항력
+*/
+ MSG_ID_E27 = 0xe27,
+/*20190508 to latest
+특성 힐 회복량
+*/
+ MSG_ID_E28 = 0xe28,
+/*20190508 to latest
+크리티컬 데미지 비율
+*/
+ MSG_ID_E29 = 0xe29,
+/*20190508 to latest
+특성 파라메터 레벨업에 사용되는 포인트
+*/
+ MSG_ID_E2A = 0xe2a,
+/*20190508 to latest
+J.Lv
+*/
+ MSG_ID_E2B = 0xe2b,
+/*20190508 to latest
+AP
+*/
+ MSG_ID_E2C = 0xe2c,
+#endif
+#if PACKETVER >= 20190522
+/*20190522 to latest
+영지로 이동
+*/
+ MSG_ID_E2D = 0xe2d,
+/*20190522 to latest
+상업도/방어도 확인
+*/
+ MSG_ID_E2E = 0xe2e,
+/*20190522 to 20190605
+관리영지 "%s"(으)로 이동하시겠습니까?
+(1회 이동 시 마다 1,000제니가 소모됩니다.
+공성전 시간에는 제니의 소모가 100배로 증가합니다.)
+20190619 to latest
+관리영지 "%s"(으)로 이동하시겠습니까?
+이동 시 마다 %d제니가 소모됩니다.
+*/
+ MSG_ID_E2F = 0xe2f,
+/*20190522 to latest
+
+관리영지 "%s"
+
+방어도: %d / %d
+상업도: %d / %d
+*/
+ MSG_ID_E30 = 0xe30,
+/*20190522 to latest
+공성 영지 내에서는 다른 공성 영지로 이동 할 수 없습니다.
+*/
+ MSG_ID_E31 = 0xe31,
+#endif
+#if PACKETVER >= 20190619
+/*20190619 to latest
+기본 기능 스킬을 습득하지 않은 캐릭터입니다.
+*/
+ MSG_ID_E32 = 0xe32,
+#endif
};
#endif /* MAP_MESSAGES_MAIN_H */
diff --git a/src/map/messages_re.h b/src/map/messages_re.h
index b81476f9c..ad3766101 100644
--- a/src/map/messages_re.h
+++ b/src/map/messages_re.h
@@ -24,7 +24,7 @@
/* This file is autogenerated, please do not commit manual changes
-Latest version: 20190418
+Latest version: 20190619
*/
enum clif_messages {
@@ -21094,6 +21094,127 @@ Please try again in a moment.
*/
MSG_ID_E19 = 0xe19,
#endif
+#if PACKETVER >= 20190508
+/*20190508 to latest
+자유이동권
+*/
+ MSG_ID_E1A = 0xe1a,
+/*20190508 to latest
+%d시간 이용, %s %d개
+*/
+ MSG_ID_E1B = 0xe1b,
+/*20190508 to latest
+자유이용권 사용중
+*/
+ MSG_ID_E1C = 0xe1c,
+/*20190508 to latest
+특성 스테이터스
+*/
+ MSG_ID_E1D = 0xe1d,
+/*20190508 to latest
+파워 파라메터
+^cc0000물리 공격력, 특성 공격력^ffffff 증가
+*/
+ MSG_ID_E1E = 0xe1e,
+/*20190508 to latest
+스테미나 파라메터
+^cc0000물리 저항력^ffffff 증가
+*/
+ MSG_ID_E1F = 0xe1f,
+/*20190508 to latest
+위즈덤 파라메터
+^cc0000마법 저항력^ffffff 증가
+*/
+ MSG_ID_E20 = 0xe20,
+/*20190508 to latest
+스펠 파라메터
+^cc0000마법 공격력, 마법 공격력^ffffff 증가
+*/
+ MSG_ID_E21 = 0xe21,
+/*20190508 to latest
+컨센트레이션 파라메터
+^cc0000명중률, 회피율, 특성 물리/마법 공격력^ffffff 증가
+*/
+ MSG_ID_E22 = 0xe22,
+/*20190508 to latest
+크리에이티브 파라메터
+^cc0000특성 힐 회복량, 크리티컬 데미지 비율^ffffff 증가
+*/
+ MSG_ID_E23 = 0xe23,
+/*20190508 to latest
+특성 물리 공격력
+*/
+ MSG_ID_E24 = 0xe24,
+/*20190508 to latest
+특성 마법 공격력
+*/
+ MSG_ID_E25 = 0xe25,
+/*20190508 to latest
+물리 저항력
+*/
+ MSG_ID_E26 = 0xe26,
+/*20190508 to latest
+마법 저항력
+*/
+ MSG_ID_E27 = 0xe27,
+/*20190508 to latest
+특성 힐 회복량
+*/
+ MSG_ID_E28 = 0xe28,
+/*20190508 to latest
+크리티컬 데미지 비율
+*/
+ MSG_ID_E29 = 0xe29,
+/*20190508 to latest
+특성 파라메터 레벨업에 사용되는 포인트
+*/
+ MSG_ID_E2A = 0xe2a,
+/*20190508 to latest
+J.Lv
+*/
+ MSG_ID_E2B = 0xe2b,
+/*20190508 to latest
+AP
+*/
+ MSG_ID_E2C = 0xe2c,
+#endif
+#if PACKETVER >= 20190522
+/*20190522 to latest
+영지로 이동
+*/
+ MSG_ID_E2D = 0xe2d,
+/*20190522 to latest
+상업도/방어도 확인
+*/
+ MSG_ID_E2E = 0xe2e,
+/*20190522 to 20190605
+관리영지 "%s"(으)로 이동하시겠습니까?
+(1회 이동 시 마다 1,000제니가 소모됩니다.
+공성전 시간에는 제니의 소모가 100배로 증가합니다.)
+20190619 to latest
+관리영지 "%s"(으)로 이동하시겠습니까?
+이동 시 마다 %d제니가 소모됩니다.
+*/
+ MSG_ID_E2F = 0xe2f,
+/*20190522 to latest
+
+관리영지 "%s"
+
+방어도: %d / %d
+상업도: %d / %d
+*/
+ MSG_ID_E30 = 0xe30,
+/*20190522 to latest
+공성 영지 내에서는 다른 공성 영지로 이동 할 수 없습니다.
+*/
+ MSG_ID_E31 = 0xe31,
+#endif
+#if PACKETVER >= 20190619
+/*20190619 to latest
+기본 기능 스킬을 습득하지 않은 캐릭터입니다.
+*/
+ MSG_ID_E32 = 0xe32,
+#endif
};
#endif /* MAP_MESSAGES_RE_H */
diff --git a/src/map/messages_zero.h b/src/map/messages_zero.h
index ab48ae4ab..601c065a9 100644
--- a/src/map/messages_zero.h
+++ b/src/map/messages_zero.h
@@ -24,7 +24,7 @@
/* This file is autogenerated, please do not commit manual changes
-Latest version: 20190502
+Latest version: 20190626
*/
enum clif_messages {
@@ -17784,6 +17784,49 @@ AP
*/
MSG_ID_E2C = 0xe2c,
#endif
+#if PACKETVER >= 20190515
+/*20190515 to latest
+영지로 이동
+*/
+ MSG_ID_E2D = 0xe2d,
+/*20190515 to latest
+상업도/방어도 확인
+*/
+ MSG_ID_E2E = 0xe2e,
+/*20190515 to 20190605
+관리영지 "%s"(으)로 이동하시겠습니까?
+(1회 이동 시 마다 1,000제니가 소모됩니다.
+공성전 시간에는 제니의 소모가 100배로 증가합니다.)
+20190626 to latest
+관리영지 "%s"(으)로 이동하시겠습니까?
+이동 시 마다 %d제니가 소모됩니다.
+(공성전 시간에는 %d제니가 소모됩니다.)
+*/
+ MSG_ID_E2F = 0xe2f,
+/*20190515 to latest
+
+관리영지 "%s"
+
+방어도: %d / %d
+상업도: %d / %d
+*/
+ MSG_ID_E30 = 0xe30,
+/*20190515 to latest
+공성 영지 내에서는 다른 공성 영지로 이동 할 수 없습니다.
+*/
+ MSG_ID_E31 = 0xe31,
+#endif
+#if PACKETVER >= 20190626
+/*20190626 to latest
+기본 기능 스킬을 습득하지 않은 캐릭터입니다.
+*/
+ MSG_ID_E32 = 0xe32,
+/*20190626 to latest
+접속하신 IP는 라그나로크 제로 이용이 불가능합니다.
+고객센터 또는 홈페이지로 문의해 주십시오.
+*/
+ MSG_ID_E33 = 0xe33,
+#endif
};
#endif /* MAP_MESSAGES_ZERO_H */
diff --git a/src/map/mob.c b/src/map/mob.c
index aa938a1e7..8511f8523 100644
--- a/src/map/mob.c
+++ b/src/map/mob.c
@@ -5519,7 +5519,8 @@ static bool mob_readdb_itemratio(char *str[], int columns, int current)
static void mob_load(bool minimal)
{
if (minimal) {
- // Only read the mob db in minimal mode
+ // Only read the mob db and option drops in minimal mode
+ mob->read_optdrops_db();
mob->readdb();
return;
}
diff --git a/src/map/npc.c b/src/map/npc.c
index 4b79a9fed..fea82c873 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -36,6 +36,7 @@
#include "map/mob.h"
#include "map/pc.h"
#include "map/pet.h"
+#include "map/quest.h"
#include "map/script.h"
#include "map/skill.h"
#include "map/status.h"
@@ -2638,8 +2639,9 @@ static int npc_unload(struct npc_data *nd, bool single)
nd->path = NULL;
}
- if( single && nd->bl.m != -1 )
- map->remove_questinfo(nd->bl.m,nd);
+ if (single && nd->bl.m != -1)
+ map->remove_questinfo(nd->bl.m, nd);
+ npc->questinfo_clear(nd);
if (nd->src_id == 0 && ( nd->subtype == SHOP || nd->subtype == CASHSHOP)) {
//src check for duplicate shops [Orcao]
@@ -2978,6 +2980,7 @@ static struct npc_data *npc_create_npc(enum npc_subtype subtype, int m, int x, i
nd->class_ = class_;
nd->speed = 200;
nd->vd = npc_viewdb[0]; // Copy INVISIBLE_CLASS view data. Actual view data is set by npc->add_to_location() later.
+ VECTOR_INIT(nd->qi_data);
return nd;
}
@@ -4365,8 +4368,7 @@ static const char *npc_parse_mapflag(const char *w1, const char *w2, const char
if (!strcmpi(w3, "nosave")) {
char savemap[32];
int savex, savey;
- if (state == 0)
- ; //Map flag disabled.
+ if (state == 0); //Map flag disabled.
else if (w4 && !strcmpi(w4, "SavePoint")) {
map->list[m].save.map = 0;
map->list[m].save.x = -1;
@@ -4659,7 +4661,8 @@ static const char *npc_parse_mapflag(const char *w1, const char *w2, const char
}
}
- if( modifier[0] == '\0' ) {
+ if (state == 0); //Map flag disabled.
+ else if (modifier[0] == '\0') {
ShowWarning("npc_parse_mapflag: Missing 5th param for 'adjust_unit_duration' flag! removing flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer));
if (retval) *retval = EXIT_FAILURE;
} else if( !( skill_id = skill->name2id(skill_name) ) || !skill->get_unit_id( skill->name2id(skill_name), 0) ) {
@@ -4718,7 +4721,8 @@ static const char *npc_parse_mapflag(const char *w1, const char *w2, const char
}
}
- if( modifier[0] == '\0' ) {
+ if (state == 0); //Map flag disabled.
+ else if (modifier[0] == '\0') {
ShowWarning("npc_parse_mapflag: Missing 5th param for 'adjust_skill_damage' flag! removing flag from %s in file '%s', line '%d'.\n", map->list[m].name, filepath, strline(buffer,start-buffer));
if (retval) *retval = EXIT_FAILURE;
} else if( !( skill_id = skill->name2id(skill_name) ) ) {
@@ -4794,6 +4798,10 @@ static const char *npc_parse_mapflag(const char *w1, const char *w2, const char
map->list[m].flag.pairship_startable = (state) ? 1 : 0;
} else if (!strcmpi(w3, "pairship_endable")) {
map->list[m].flag.pairship_endable = (state) ? 1 : 0;
+ } else if (!strcmpi(w3, "nostorage")) {
+ map->list[m].flag.nostorage = (state) ? cap_value(atoi(w4), 1, 3) : 0;
+ } else if (!strcmpi(w3, "nogstorage")) {
+ map->list[m].flag.nogstorage = (state) ? cap_value(atoi(w4), 1, 3) : 0;
} else {
npc->parse_unknown_mapflag(mapname, w3, w4, start, buffer, filepath, retval);
}
@@ -5331,6 +5339,18 @@ static void npc_debug_warps(void)
npc->debug_warps_sub(map->list[m].npc[i]);
}
+static void npc_questinfo_clear(struct npc_data *nd)
+{
+ nullpo_retv(nd);
+
+ for (int i = 0; i < VECTOR_LENGTH(nd->qi_data); i++) {
+ struct questinfo *qi = &VECTOR_INDEX(nd->qi_data, i);
+ VECTOR_CLEAR(qi->items);
+ VECTOR_CLEAR(qi->quest_requirement);
+ }
+ VECTOR_CLEAR(nd->qi_data);
+}
+
/*==========================================
* npc initialization
*------------------------------------------*/
@@ -5551,4 +5571,5 @@ void npc_defaults(void)
npc->barter_delfromsql_sub = npc_barter_delfromsql_sub;
npc->db_checkid = npc_db_checkid;
npc->refresh = npc_refresh;
+ npc->questinfo_clear = npc_questinfo_clear;
}
diff --git a/src/map/npc.h b/src/map/npc.h
index 0eb8befd1..2819cbd87 100644
--- a/src/map/npc.h
+++ b/src/map/npc.h
@@ -129,6 +129,7 @@ struct npc_data {
int spawn_timer;
} tomb;
} u;
+ VECTOR_DECL(struct questinfo) qi_data;
struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
@@ -322,6 +323,7 @@ struct npc_interface {
void (*barter_delfromsql_sub) (const char *npcname, int itemId, int itemId2, int amount2);
bool (*db_checkid) (const int id);
void (*refresh) (struct npc_data* nd);
+ void (*questinfo_clear) (struct npc_data *nd);
/**
* For the Secure NPC Timeout option (check config/Secure.h) [RR]
**/
diff --git a/src/map/packets.h b/src/map/packets.h
index bffec4f43..83a9d0322 100644
--- a/src/map/packets.h
+++ b/src/map/packets.h
@@ -589,7 +589,6 @@ packet(0x96e,clif->ackmergeitems);
#if PACKETVER >= 20070227
packet(0x0288,clif->pcashshop_buy,2,4,6);
packet(0x02b6,clif->pquestStateAck,2,6);
- packet(0x02ba,clif->pHotkey,2,4,5,9);
packet(0x02c4,clif->pPartyInvite2,2); // CZ_PARTY_JOIN_REQ
packet(0x02c7,clif->pReplyPartyInvite2,2,6);
packet(0x02c8,clif->pPartyTick,2);
@@ -599,6 +598,10 @@ packet(0x96e,clif->ackmergeitems);
packet(0x02db,clif->pBattleChat,2,4);
#endif
+#if PACKETVER_MAIN_NUM >= 20070618 || defined(PACKETVER_RE) || defined(PACKETVER_ZERO) || PACKETVER_AD_NUM >= 20070618 || PACKETVER_SAK_NUM >= 20070618
+ packet(0x02ba,clif->pHotkey1);
+#endif
+
//2008-01-02aSakexe
#if PACKETVER >= 20080102
packet(0x01df,clif->pGMReqAccountName,2);
@@ -1664,10 +1667,8 @@ packet(0x96e,clif->ackmergeitems);
// changed packet sizes
#endif
-// 2014-01-29bRagexeRE
-#if PACKETVER >= 20140129
-// new packets
- packet(0x0a01,clif->pHotkeyRowShift,2); // CZ_SHORTCUTKEYBAR_ROTATE
+#if PACKETVER_MAIN_NUM >= 20140129 || PACKETVER_RE_NUM >= 20140129 || defined(PACKETVER_ZERO)
+ packet(0x0a01,clif->pHotkeyRowShift1); // CZ_SHORTCUTKEYBAR_ROTATE
#endif
// 2014-02-12aRagexeRE
@@ -1948,4 +1949,9 @@ packet(0x96e,clif->ackmergeitems);
packet(0x0b1c,clif->pPing);
#endif
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+ packet(0x0b21,clif->pHotkey2);
+ packet(0x0b22,clif->pHotkeyRowShift2); // CZ_SHORTCUTKEYBAR_ROTATE
+#endif
+
#endif /* MAP_PACKETS_H */
diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h
index 8a6f32a54..5bd66d66b 100644
--- a/src/map/packets_keys_main.h
+++ b/src/map/packets_keys_main.h
@@ -37,7 +37,7 @@
packetKeys(0x49357d72,0x22c370a1,0x5f836591);
#endif
-// 2010-11-23aRagexeRE, 2010-11-24aRagexeRE, 2010-11-24bRagexeRE, 2010-11-25aRagexeRE, 2010-11-26aRagexeRE, 2010-11-30aRagexeRE, 2010-12-07aRagexeRE, 2010-12-14aRagexeRE, 2010-12-21aRagexeRE, 2010-12-23aRagexeRE, 2010-12-28aRagexeRE, 2011-01-04aRagexeRE, 2011-01-05aRagexeRE, 2011-01-11aRagexeRE, 2011-01-18aRagexeRE, 2011-01-25aRagexeRE, 2011-01-26aRagexeRE, 2011-01-26bRagexeRE, 2011-01-31aRagexeRE, 2011-01-31bRagexeRE, 2011-01-31cRagexeRE, 2011-02-08aRagexeRE, 2011-02-15aRagexeRE, 2011-02-22aRagexeRE, 2011-02-23aRagexeRE, 2011-02-23bRagexeRE, 2011-02-24aRagexeRE, 2011-02-25aRagexeRE, 2011-02-28aRagexeRE, 2011-03-08aRagexeRE, 2011-03-09aRagexeRE, 2011-03-09bRagexeRE, 2011-03-09cRagexeRE, 2011-03-09dRagexeRE, 2011-03-15aRagexeRE, 2011-03-22aRagexeRE, 2011-03-29aRagexeRE, 2011-03-30aRagexeRE, 2011-03-30cRagexeRE, 2011-04-05aRagexeRE, 2011-04-12aRagexeRE, 2011-04-19aRagexeRE, 2011-04-20aRagexeRE, 2011-04-26aRagexeRE, 2011-04-27aRagexeRE, 2011-05-03aRagexeRE, 2011-05-11aRagexeRE, 2011-05-17bRagexeRE, 2011-05-24aRagexeRE, 2011-05-26aRagexeRE, 2011-05-31aRagexeRE, 2011-06-07aRagexeRE, 2011-06-08aRagexeRE, 2011-06-08bRagexeRE, 2011-06-08cRagexeRE, 2011-06-09aRagexeRE, 2011-06-14bRagexeRE, 2011-06-22aRagexeRE, 2011-06-28aRagexeRE, 2011-07-06aRagexeRE, 2011-07-13aRagexeRE, 2011-07-13bRagexeRE, 2011-07-13cRagexeRE, 2011-07-19aRagexeRE, 2011-07-26aRagexeRE, 2011-08-03aRagexeRE, 2011-08-03bRagexeRE, 2011-08-10aRagexeRE, 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17_02aRagexe, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexe, 2018-10-17_03aRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-10-31cRagexeRE, 2018-11-07aRagexe, 2018-11-07aRagexeRE, 2018-11-14cRagexe, 2018-11-14cRagexeRE, 2018-11-14dRagexe, 2018-11-14dRagexeRE, 2018-11-21bRagexe, 2018-11-21cRagexeRE, 2018-11-28aRagexe, 2018-11-28aRagexeRE, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-05bRagexeRE, 2018-12-12aRagexe, 2018-12-12aRagexeRE, 2018-12-12bRagexe, 2018-12-12bRagexeRE, 2018-12-19bRagexe, 2018-12-19bRagexeRE, 2018-12-26aRagexe, 2018-12-26aRagexeRE, 2019-01-09aRagexe, 2019-01-09bRagexeRE, 2019-01-16bRagexe, 2019-01-16bRagexeRE, 2019-01-16cRagexe, 2019-01-16cRagexeRE, 2019-01-23dRagexe, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-20aRagexeRE, 2019-02-27aRagexe, 2019-02-27bRagexeRE, 2019-02-28aRagexe, 2019-02-28aRagexeRE, 2019-03-06bRagexe, 2019-03-06bRagexeRE, 2019-03-06cRagexe, 2019-03-06cRagexeRE, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-20aRagexeRE, 2019-03-22aRagexe, 2019-03-22aRagexeRE, 2019-03-27bRagexe, 2019-03-27bRagexeRE, 2019-04-03aRagexe, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17aRagexe, 2019-04-17cRagexeRE, 2019-04-18aRagexe, 2019-04-18aRagexeRE
+// 2010-11-23aRagexeRE, 2010-11-24aRagexeRE, 2010-11-24bRagexeRE, 2010-11-25aRagexeRE, 2010-11-26aRagexeRE, 2010-11-30aRagexeRE, 2010-12-07aRagexeRE, 2010-12-14aRagexeRE, 2010-12-21aRagexeRE, 2010-12-23aRagexeRE, 2010-12-28aRagexeRE, 2011-01-04aRagexeRE, 2011-01-05aRagexeRE, 2011-01-11aRagexeRE, 2011-01-18aRagexeRE, 2011-01-25aRagexeRE, 2011-01-26aRagexeRE, 2011-01-26bRagexeRE, 2011-01-31aRagexeRE, 2011-01-31bRagexeRE, 2011-01-31cRagexeRE, 2011-02-08aRagexeRE, 2011-02-15aRagexeRE, 2011-02-22aRagexeRE, 2011-02-23aRagexeRE, 2011-02-23bRagexeRE, 2011-02-24aRagexeRE, 2011-02-25aRagexeRE, 2011-02-28aRagexeRE, 2011-03-08aRagexeRE, 2011-03-09aRagexeRE, 2011-03-09bRagexeRE, 2011-03-09cRagexeRE, 2011-03-09dRagexeRE, 2011-03-15aRagexeRE, 2011-03-22aRagexeRE, 2011-03-29aRagexeRE, 2011-03-30aRagexeRE, 2011-03-30cRagexeRE, 2011-04-05aRagexeRE, 2011-04-12aRagexeRE, 2011-04-19aRagexeRE, 2011-04-20aRagexeRE, 2011-04-26aRagexeRE, 2011-04-27aRagexeRE, 2011-05-03aRagexeRE, 2011-05-11aRagexeRE, 2011-05-17bRagexeRE, 2011-05-24aRagexeRE, 2011-05-26aRagexeRE, 2011-05-31aRagexeRE, 2011-06-07aRagexeRE, 2011-06-08aRagexeRE, 2011-06-08bRagexeRE, 2011-06-08cRagexeRE, 2011-06-09aRagexeRE, 2011-06-14bRagexeRE, 2011-06-22aRagexeRE, 2011-06-28aRagexeRE, 2011-07-06aRagexeRE, 2011-07-13aRagexeRE, 2011-07-13bRagexeRE, 2011-07-13cRagexeRE, 2011-07-19aRagexeRE, 2011-07-26aRagexeRE, 2011-08-03aRagexeRE, 2011-08-03bRagexeRE, 2011-08-10aRagexeRE, 2013-12-23aRagexeRE, 2014-05-08aRagexe, 2014-05-08aRagexeRE, 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-21aRagexeRE, 2018-03-28bRagexe, 2018-03-28bRagexeRE, 2018-04-04bRagexe, 2018-04-04cRagexeRE, 2018-04-18aRagexe, 2018-04-18bRagexeRE, 2018-04-25cRagexe, 2018-04-25cRagexeRE, 2018-05-02bRagexe, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-16cRagexeRE, 2018-05-23aRagexe, 2018-05-23aRagexeRE, 2018-05-30aRagexe, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexe, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20cRagexe, 2018-06-20dRagexeRE, 2018-06-20eRagexe, 2018-06-20eRagexeRE, 2018-06-21aRagexe, 2018-06-21aRagexeRE, 2018-07-04aRagexe, 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexe, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexe, 2018-07-18cRagexeRE, 2018-08-01cRagexe, 2018-08-01cRagexeRE, 2018-08-08bRagexe, 2018-08-08bRagexeRE, 2018-08-22cRagexe, 2018-08-22cRagexeRE, 2018-08-29aRagexe, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-12dRagexeRE, 2018-09-19aRagexe, 2018-09-19aRagexeRE, 2018-10-02aRagexe, 2018-10-02aRagexeRE, 2018-10-02bRagexe, 2018-10-02bRagexeRE, 2018-10-17_02aRagexe, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexe, 2018-10-17_03aRagexeRE, 2018-10-17bRagexe, 2018-10-17bRagexeRE, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-10-31cRagexeRE, 2018-11-07aRagexe, 2018-11-07aRagexeRE, 2018-11-14cRagexe, 2018-11-14cRagexeRE, 2018-11-14dRagexe, 2018-11-14dRagexeRE, 2018-11-21bRagexe, 2018-11-21cRagexeRE, 2018-11-28aRagexe, 2018-11-28aRagexeRE, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-05bRagexeRE, 2018-12-12aRagexe, 2018-12-12aRagexeRE, 2018-12-12bRagexe, 2018-12-12bRagexeRE, 2018-12-19bRagexe, 2018-12-19bRagexeRE, 2018-12-26aRagexe, 2018-12-26aRagexeRE, 2019-01-09aRagexe, 2019-01-09bRagexeRE, 2019-01-16bRagexe, 2019-01-16bRagexeRE, 2019-01-16cRagexe, 2019-01-16cRagexeRE, 2019-01-23dRagexe, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-20aRagexeRE, 2019-02-27aRagexe, 2019-02-27bRagexeRE, 2019-02-28aRagexe, 2019-02-28aRagexeRE, 2019-03-06bRagexe, 2019-03-06bRagexeRE, 2019-03-06cRagexe, 2019-03-06cRagexeRE, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-20aRagexeRE, 2019-03-22aRagexe, 2019-03-22aRagexeRE, 2019-03-27bRagexe, 2019-03-27bRagexeRE, 2019-04-03aRagexe, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17aRagexe, 2019-04-17cRagexeRE, 2019-04-18aRagexe, 2019-04-18aRagexeRE, 2019-05-08cRagexe, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexe, 2019-05-22bRagexeRE, 2019-05-22cRagexe, 2019-05-22cRagexeRE, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29bRagexeRE, 2019-05-29cRagexe, 2019-05-29cRagexeRE, 2019-05-30aRagexe, 2019-05-30aRagexeRE, 2019-06-05JRagexeRE, 2019-06-05KRagexe, 2019-06-05LRagexeRE, 2019-06-05fRagexe, 2019-06-05hRagexeRE, 2019-06-19bRagexe, 2019-06-19cRagexeRE, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-06-26bRagexeRE
#if PACKETVER == 20101123 || \
PACKETVER == 20101124 || \
PACKETVER == 20101125 || \
@@ -147,7 +147,15 @@
PACKETVER == 20190327 || \
PACKETVER == 20190403 || \
PACKETVER == 20190417 || \
- PACKETVER >= 20190418
+ PACKETVER == 20190418 || \
+ PACKETVER == 20190508 || \
+ PACKETVER == 20190522 || \
+ PACKETVER == 20190523 || \
+ PACKETVER == 20190529 || \
+ PACKETVER == 20190530 || \
+ PACKETVER == 20190605 || \
+ PACKETVER == 20190619 || \
+ PACKETVER >= 20190626
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h
index 5a9e65f14..458037f6f 100644
--- a/src/map/packets_keys_zero.h
+++ b/src/map/packets_keys_zero.h
@@ -30,7 +30,7 @@
/* This file is autogenerated, please do not commit manual changes */
-// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero, 2018-10-24_2aRagexe_zero, 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero
+// 2017-10-18aRagexe_zero, 2017-10-19aRagexe_zero, 2017-10-23aRagexe_zero, 2017-10-23bRagexe_zero, 2017-10-23cRagexe_zero, 2017-10-24aRagexe_2_zero, 2017-10-24aRagexe_zero, 2017-10-25bRagexe_zero, 2017-10-27aRagexe_zero, 2017-10-27bRagexe_zero, 2017-10-30aRagexe_zero, 2017-10-31aRagexe_zero, 2017-11-09aRagexe_zero, 2017-11-13aRagexe_zero, 2017-11-13bRagexe_zero, 2018-03-15aRagexe_zero, 2018-03-21aRagexe_zero, 2018-03-21bRagexe_zero, 2018-03-28_1aRagexe_zero, 2018-03-28cRagexe_zero, 2018-04-11aRagexe_zero, 2018-04-25_3aRagexe_zero, 2018-05-09_3aRagexe_zero, 2018-05-23aRagexe_zero, 2018-06-05bRagexe_zero, 2018-06-05cRagexe_zero, 2018-06-27aRagexe_zero, 2018-07-03aRagexe_zero, 2018-07-11_2aRagexe_zero, 2018-07-25_2aRagexe_zero, 2018-08-01aRagexe_zero, 2018-08-08_2aRagexe_zero, 2018-08-22aRagexe_zero, 2018-08-29aRagexe_zero, 2018-09-05aRagexe_zero, 2018-09-12aRagexe_zero, 2018-09-19aRagexe_zero, 2018-09-28aRagexe_zero, 2018-10-10_2aRagexe_zero, 2018-10-24_2aRagexe_zero, 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero, 2019-05-08_2aRagexe_zero, 2019-05-08aRagexe_zero, 2019-05-15aRagexe_zero, 2019-05-29aRagexe_zero, 2019-05-30aRagexe_zero, 2019-06-05_2aRagexe_zero, 2019-06-26_2aRagexe_zero
#if PACKETVER == 20171018 || \
PACKETVER == 20171019 || \
PACKETVER == 20171023 || \
@@ -80,7 +80,13 @@
PACKETVER == 20190403 || \
PACKETVER == 20190410 || \
PACKETVER == 20190424 || \
- PACKETVER >= 20190502
+ PACKETVER == 20190502 || \
+ PACKETVER == 20190508 || \
+ PACKETVER == 20190515 || \
+ PACKETVER == 20190529 || \
+ PACKETVER == 20190530 || \
+ PACKETVER == 20190605 || \
+ PACKETVER >= 20190626
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h
index a5ce83ebe..11672ad6d 100644
--- a/src/map/packets_shuffle_main.h
+++ b/src/map/packets_shuffle_main.h
@@ -9727,7 +9727,7 @@
packet(0x0967,clif->pSolveCharName,2); // CZ_REQNAME_BYGID // 6
#endif
-// 2018-11-21bRagexe, 2018-11-28aRagexe, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-12aRagexe, 2018-12-12bRagexe, 2018-12-19bRagexe, 2018-12-26aRagexe, 2019-01-09aRagexe, 2019-01-16bRagexe, 2019-01-16cRagexe, 2019-01-23dRagexe, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-27aRagexe, 2019-02-28aRagexe, 2019-03-06bRagexe, 2019-03-06cRagexe, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-22aRagexe, 2019-03-27bRagexe, 2019-04-03aRagexe, 2019-04-17aRagexe, 2019-04-18aRagexe
+// 2018-11-21bRagexe, 2018-11-28aRagexe, 2018-11-28bRagexe, 2018-11-28cRagexe, 2018-12-05aRagexe, 2018-12-12aRagexe, 2018-12-12bRagexe, 2018-12-19bRagexe, 2018-12-26aRagexe, 2019-01-09aRagexe, 2019-01-16bRagexe, 2019-01-16cRagexe, 2019-01-23dRagexe, 2019-02-13bRagexe, 2019-02-13eRagexe, 2019-02-27aRagexe, 2019-02-28aRagexe, 2019-03-06bRagexe, 2019-03-06cRagexe, 2019-03-13aRagexe, 2019-03-20aRagexe, 2019-03-22aRagexe, 2019-03-27bRagexe, 2019-04-03aRagexe, 2019-04-17aRagexe, 2019-04-18aRagexe, 2019-05-08cRagexe, 2019-05-22bRagexe, 2019-05-22cRagexe, 2019-05-23aRagexe, 2019-05-29aRagexe, 2019-05-29cRagexe, 2019-05-30aRagexe, 2019-06-05fRagexe, 2019-06-05KRagexe, 2019-06-19bRagexe
#if PACKETVER == 20181121 || \
PACKETVER == 20181128 || \
PACKETVER == 20181205 || \
@@ -9747,7 +9747,14 @@
PACKETVER == 20190327 || \
PACKETVER == 20190403 || \
PACKETVER == 20190417 || \
- PACKETVER >= 20190418
+ PACKETVER == 20190418 || \
+ PACKETVER == 20190508 || \
+ PACKETVER == 20190522 || \
+ PACKETVER == 20190523 || \
+ PACKETVER == 20190529 || \
+ PACKETVER == 20190530 || \
+ PACKETVER == 20190605 || \
+ PACKETVER >= 20190619
packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26
packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5
packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36
diff --git a/src/map/packets_shuffle_re.h b/src/map/packets_shuffle_re.h
index 5808e4c17..d45782743 100644
--- a/src/map/packets_shuffle_re.h
+++ b/src/map/packets_shuffle_re.h
@@ -9663,7 +9663,7 @@
packet(0x083c,clif->pSearchStoreInfoListItemClick,2,6,10); // CZ_SSILIST_ITEM_CLICK // 12
#endif
-// 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexeRE, 2018-08-01cRagexeRE, 2018-08-08bRagexeRE, 2018-08-22cRagexeRE, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-09-12dRagexeRE, 2018-09-19aRagexeRE, 2018-10-02aRagexeRE, 2018-10-02bRagexeRE, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexeRE, 2018-10-17bRagexeRE, 2018-10-31cRagexeRE, 2018-11-07aRagexeRE, 2018-11-14cRagexeRE, 2018-11-14dRagexeRE, 2018-11-21cRagexeRE, 2018-11-28aRagexeRE, 2018-12-05bRagexeRE, 2018-12-12aRagexeRE, 2018-12-12bRagexeRE, 2018-12-19bRagexeRE, 2018-12-26aRagexeRE, 2019-01-09bRagexeRE, 2019-01-16bRagexeRE, 2019-01-16cRagexeRE, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-20aRagexeRE, 2019-02-27bRagexeRE, 2019-02-28aRagexeRE, 2019-03-06bRagexeRE, 2019-03-06cRagexeRE, 2019-03-20aRagexeRE, 2019-03-22aRagexeRE, 2019-03-27bRagexeRE, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17cRagexeRE, 2019-04-18aRagexeRE
+// 2018-07-04aRagexeRE, 2018-07-11aRagexeRE, 2018-07-18bRagexeRE, 2018-07-18bRagexeRE1, 2018-07-18cRagexeRE, 2018-08-01cRagexeRE, 2018-08-08bRagexeRE, 2018-08-22cRagexeRE, 2018-08-29aRagexeRE, 2018-08-29bRagexeRE, 2018-09-12dRagexeRE, 2018-09-19aRagexeRE, 2018-10-02aRagexeRE, 2018-10-02bRagexeRE, 2018-10-17_02aRagexeRE, 2018-10-17_03aRagexeRE, 2018-10-17bRagexeRE, 2018-10-31cRagexeRE, 2018-11-07aRagexeRE, 2018-11-14cRagexeRE, 2018-11-14dRagexeRE, 2018-11-21cRagexeRE, 2018-11-28aRagexeRE, 2018-12-05bRagexeRE, 2018-12-12aRagexeRE, 2018-12-12bRagexeRE, 2018-12-19bRagexeRE, 2018-12-26aRagexeRE, 2019-01-09bRagexeRE, 2019-01-16bRagexeRE, 2019-01-16cRagexeRE, 2019-01-23dRagexeRE, 2019-02-13IRagexeRE, 2019-02-20aRagexeRE, 2019-02-27bRagexeRE, 2019-02-28aRagexeRE, 2019-03-06bRagexeRE, 2019-03-06cRagexeRE, 2019-03-20aRagexeRE, 2019-03-22aRagexeRE, 2019-03-27bRagexeRE, 2019-04-03bRagexeRE, 2019-04-03cRagexeRE, 2019-04-17cRagexeRE, 2019-04-18aRagexeRE, 2019-05-08dRagexeRE, 2019-05-08eRagexeRE, 2019-05-22bRagexeRE, 2019-05-22cRagexeRE, 2019-05-29bRagexeRE, 2019-05-29cRagexeRE, 2019-05-30aRagexeRE, 2019-06-05hRagexeRE, 2019-06-05JRagexeRE, 2019-06-05LRagexeRE, 2019-06-19cRagexeRE, 2019-06-26bRagexeRE
#if PACKETVER == 20180704 || \
PACKETVER == 20180711 || \
PACKETVER == 20180718 || \
@@ -9697,7 +9697,14 @@
PACKETVER == 20190327 || \
PACKETVER == 20190403 || \
PACKETVER == 20190417 || \
- PACKETVER >= 20190418
+ PACKETVER == 20190418 || \
+ PACKETVER == 20190508 || \
+ PACKETVER == 20190522 || \
+ PACKETVER == 20190529 || \
+ PACKETVER == 20190530 || \
+ PACKETVER == 20190605 || \
+ PACKETVER == 20190619 || \
+ PACKETVER >= 20190626
packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26
packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5
packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36
diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h
index 7fd34a51b..74afda803 100644
--- a/src/map/packets_shuffle_zero.h
+++ b/src/map/packets_shuffle_zero.h
@@ -742,7 +742,7 @@
packet(0x0968,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36
#endif
-// 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero
+// 2018-11-14aRagexe_zero, 2018-11-20aRagexe_zero, 2018-11-28aRagexe_zero, 2018-12-12aRagexe_zero, 2018-12-19aRagexe_zero, 2018-12-26_2aRagexe_zero, 2019-01-16_2aRagexe_zero, 2019-01-17_1aRagexe_zero, 2019-01-30_2aRagexe_zero, 2019-02-13aRagexe_zero, 2019-02-20aRagexe_zero, 2019-02-27aRagexe_zero, 2019-03-13aRagexe_zero, 2019-03-27_2aRagexe_zero, 2019-03-27_3aRagexe_zero, 2019-04-03aRagexe_zero, 2019-04-10bRagexe_zero, 2019-04-24aRagexe_zero, 2019-05-02aRagexe_zero, 2019-05-08_2aRagexe_zero, 2019-05-08aRagexe_zero, 2019-05-15aRagexe_zero, 2019-05-29aRagexe_zero, 2019-05-30aRagexe_zero, 2019-06-05_2aRagexe_zero, 2019-06-26_2aRagexe_zero
#if PACKETVER == 20181114 || \
PACKETVER == 20181120 || \
PACKETVER == 20181128 || \
@@ -760,7 +760,13 @@
PACKETVER == 20190403 || \
PACKETVER == 20190410 || \
PACKETVER == 20190424 || \
- PACKETVER >= 20190502
+ PACKETVER == 20190502 || \
+ PACKETVER == 20190508 || \
+ PACKETVER == 20190515 || \
+ PACKETVER == 20190529 || \
+ PACKETVER == 20190530 || \
+ PACKETVER == 20190605 || \
+ PACKETVER >= 20190626
packet(0x0202,clif->pFriendsListAdd,2); // CZ_ADD_FRIENDS // 26
packet(0x022d,clif->pHomMenu,2,4); // CZ_COMMAND_MER // 5
packet(0x023b,clif->pStoragePassword,0); // CZ_ACK_STORE_PASSWORD // 36
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 33b7759ce..9022dd66d 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -39,13 +39,6 @@ enum packet_headers {
banking_checkType = 0x9a6,
cart_additem_ackType = 0x12c,
sc_notickType = 0x196,
-#if PACKETVER >= 20141022
- hotkeyType = 0xa00,
-#elif PACKETVER >= 20090603
- hotkeyType = 0x7d9,
-#else
- hotkeyType = 0x2b9,
-#endif
#if PACKETVER >= 20150226
cartaddType = 0xa0b,
#elif PACKETVER >= 5
@@ -1423,21 +1416,90 @@ struct packet_party_leader_changed {
uint32 new_leader_aid;
} __attribute__((packed));
-struct packet_hotkey {
#ifdef HOTKEY_SAVING
- int16 PacketType;
-#if PACKETVER >= 20141022
- int8 Rotate;
+struct hotkey_data {
+ int8 isSkill; // 0: Item, 1:Skill
+ uint32 id; // Item/Skill ID
+ int16 count; // Item Quantity/Skill Level
+} __attribute__((packed));
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+#define MAX_HOTKEYS_PACKET 38
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+ int16 packetType;
+ int8 rotate;
+ int16 tab;
+ struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x0b20);
+#elif PACKETVER_MAIN_NUM >= 20141022 || PACKETVER_RE_NUM >= 20141015 || defined(PACKETVER_ZERO)
+#define MAX_HOTKEYS_PACKET 38
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+ int16 packetType;
+ int8 rotate;
+ struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x0a00);
+#elif PACKETVER_MAIN_NUM >= 20090617 || PACKETVER_RE_NUM >= 20090617 || PACKETVER_SAK_NUM >= 20090617
+#define MAX_HOTKEYS_PACKET 38
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+ int16 packetType;
+ struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x07d9);
+#elif PACKETVER_MAIN_NUM >= 20090603 || PACKETVER_RE_NUM >= 20090603 || PACKETVER_SAK_NUM >= 20090603
+#define MAX_HOTKEYS_PACKET 36
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+ int16 packetType;
+ struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x07d9);
+#elif PACKETVER_MAIN_NUM >= 20070711 || PACKETVER_RE_NUM >= 20080827 || PACKETVER_AD_NUM >= 20070711 || PACKETVER_SAK_NUM >= 20070628
+#define MAX_HOTKEYS_PACKET 27
+struct PACKET_ZC_SHORTCUT_KEY_LIST {
+ int16 packetType;
+ struct hotkey_data hotkey[MAX_HOTKEYS_PACKET];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_SHORTCUT_KEY_LIST, 0x02b9);
#endif
- struct {
- int8 isSkill; // 0: Item, 1:Skill
- uint32 ID; // Item/Skill ID
- int16 count; // Item Quantity/Skill Level
- } hotkey[MAX_HOTKEYS];
-#else // not HOTKEY_SAVING
- UNAVAILABLE_STRUCT;
-#endif // HOTKEY_SAVING
+
+#if PACKETVER_MAIN_NUM >= 20070618 || defined(PACKETVER_RE) || defined(PACKETVER_ZERO) || PACKETVER_AD_NUM >= 20070618 || PACKETVER_SAK_NUM >= 20070618
+struct PACKET_CZ_SHORTCUT_KEY_CHANGE1 {
+ int16 packetType;
+ uint16 index;
+ struct hotkey_data hotkey;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SHORTCUT_KEY_CHANGE1, 0x02ba);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+struct PACKET_CZ_SHORTCUT_KEY_CHANGE2 {
+ int16 packetType;
+ uint16 tab;
+ uint16 index;
+ struct hotkey_data hotkey;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SHORTCUT_KEY_CHANGE2, 0x0b21);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20140129 || PACKETVER_RE_NUM >= 20140129 || defined(PACKETVER_ZERO)
+struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE1 {
+ int16 packetType;
+ uint8 rowshift;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SHORTCUTKEYBAR_ROTATE1, 0x0a01);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20190522 || PACKETVER_RE_NUM >= 20190508 || PACKETVER_ZERO_NUM >= 20190605
+struct PACKET_CZ_SHORTCUTKEYBAR_ROTATE2 {
+ int16 packetType;
+ uint16 tab;
+ uint8 rowshift;
} __attribute__((packed));
+DEFINE_PACKET_HEADER(CZ_SHORTCUTKEYBAR_ROTATE2, 0x0b22);
+#endif
+
+#endif // HOTKEY_SAVING
/**
* MISSION_HUNT_INFO (PACKETVER >= 20141022)
@@ -2264,7 +2326,35 @@ struct PACKET_ZC_ACK_WEAPONREFINE {
#endif
} __attribute__((packed));
-#if PACKETVER_MAIN_NUM >= 20131230 || PACKETVER_RE_NUM >= 20131230 || defined(PACKETVER_ZERO)
+#if PACKETVER_MAIN_NUM >= 20190619 || PACKETVER_RE_NUM >= 20190605 || PACKETVER_ZERO_NUM >= 20190626
+// PACKET_ZC_PROPERTY_HOMUN3
+struct PACKET_ZC_PROPERTY_HOMUN {
+ int16 packetType;
+ char name[NAME_LENGTH];
+ // Bit field, bit 0 : rename_flag (1 = already renamed), bit 1 : homunc vaporized (1 = true), bit 2 : homunc dead (1 = true)
+ uint8 flags;
+ uint16 level;
+ uint16 hunger;
+ uint16 intimacy;
+ uint16 atk2;
+ uint16 matk;
+ uint16 hit;
+ uint16 crit;
+ uint16 def;
+ uint16 mdef;
+ uint16 flee;
+ uint16 amotion;
+ uint32 hp;
+ uint32 maxHp;
+ uint16 sp;
+ uint16 maxSp;
+ uint32 exp;
+ uint32 expNext;
+ uint16 skillPoints;
+ uint16 range;
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_PROPERTY_HOMUN, 0x0b2f);
+#elif PACKETVER_MAIN_NUM >= 20131230 || PACKETVER_RE_NUM >= 20131230 || defined(PACKETVER_ZERO)
// PACKET_ZC_PROPERTY_HOMUN2
struct PACKET_ZC_PROPERTY_HOMUN {
int16 packetType;
@@ -2589,6 +2679,7 @@ struct PACKET_ZC_MAKINGARROW_LIST {
int16 packetLength;
struct PACKET_ZC_MAKINGARROW_LIST_sub items[];
} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_MAKINGARROW_LIST, 0x01ad);
struct PACKET_ZC_REPAIRITEMLIST_sub {
int16 index;
@@ -3191,7 +3282,7 @@ struct PACKET_CZ_PING {
DEFINE_PACKET_HEADER(CZ_PING, 0x0b1c);
#endif
-#if PACKETVER_MAIN_NUM >= 20190213 || PACKETVER_RE_NUM >= 20190213 || PACKETVER_ZERO_NUM >= 20190130
+#if PACKETVER_MAIN_NUM >= 20190227 || PACKETVER_RE_NUM >= 20190220 || PACKETVER_ZERO_NUM >= 20190220
struct PACKET_ZC_PING {
int16 packetType;
} __attribute__((packed));
@@ -3389,6 +3480,7 @@ struct PACKET_ZC_REFINE_STATUS {
DEFINE_PACKET_HEADER(ZC_REFINE_STATUS, 0x0ada);
#endif
+
#if !defined(sun) && (!defined(__NETBSD__) || __NetBSD_Version__ >= 600000000) // NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
#pragma pack(pop)
#endif // not NetBSD < 6 / Solaris
diff --git a/src/map/pc.c b/src/map/pc.c
index 5416fbec2..fb023b2a4 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -4778,6 +4778,13 @@ static int pc_additem(struct map_session_data *sd, const struct item *item_data,
sd->weight += w;
clif->updatestatus(sd,SP_WEIGHT);
+
+ // auto-favorite
+ if (data->flag.auto_favorite > 0) {
+ sd->status.inventory[i].favorite = 1;
+ clif->favorite_item(sd, i);
+ }
+
//Auto-equip
if(data->flag.autoequip)
pc->equipitem(sd, i, data->equip);
diff --git a/src/map/pc.h b/src/map/pc.h
index 42c9d204e..7c89f7f32 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -274,6 +274,9 @@ struct map_session_data {
int npc_item_flag; //Marks the npc_id with which you can change equipments during interactions with said npc (see script command enable_itemuse)
int npc_menu; // internal variable, used in npc menu handling
int npc_amount;
+ int npc_amount_min;
+ int npc_amount_max;
+ int npc_input_capped_range;
struct script_state *st;
char npc_str[CHATBOX_SIZE]; // for passing npc input box text to script engine
int npc_timer_id; //For player attached npc timers. [Skotlex]
diff --git a/src/map/pc_groups.c b/src/map/pc_groups.c
index 887c946e3..8d55897b8 100644
--- a/src/map/pc_groups.c
+++ b/src/map/pc_groups.c
@@ -449,6 +449,7 @@ static void do_init_pc_groups(void)
{ "disable_store", PC_PERM_DISABLE_STORE },
{ "disable_exp", PC_PERM_DISABLE_EXP },
{ "disable_skill_usage", PC_PERM_DISABLE_SKILL_USAGE },
+ { "bypass_nostorage", PC_PERM_BYPASS_NOSTORAGE },
};
unsigned char i, len = ARRAYLENGTH(pc_g_defaults);
diff --git a/src/map/pc_groups.h b/src/map/pc_groups.h
index 6070809e0..f3994b9c4 100644
--- a/src/map/pc_groups.h
+++ b/src/map/pc_groups.h
@@ -57,6 +57,7 @@ enum e_pc_permission {
PC_PERM_DISABLE_STORE = 0x1000000,
PC_PERM_DISABLE_EXP = 0x2000000,
PC_PERM_DISABLE_SKILL_USAGE = 0x4000000,
+ PC_PERM_BYPASS_NOSTORAGE = 0x8000000,
};
// Cached config settings for quick lookup
diff --git a/src/map/quest.c b/src/map/quest.c
index 7a216095e..9540b411d 100644
--- a/src/map/quest.c
+++ b/src/map/quest.c
@@ -672,21 +672,22 @@ static int quest_questinfo_validate_icon(int icon)
*/
static void quest_questinfo_refresh(struct map_session_data *sd)
{
- int i;
-
nullpo_retv(sd);
- for (i = 0; i < VECTOR_LENGTH(map->list[sd->bl.m].qi_data); i++) {
- struct questinfo *qi = &VECTOR_INDEX(map->list[sd->bl.m].qi_data, i);
- // Remove the bubbles if one of the conditions is no longer valid.
- if (quest->questinfo_validate(sd, qi) == false) {
+ for (int i = 0; i < VECTOR_LENGTH(map->list[sd->bl.m].qi_list); i++) {
+ struct npc_data *nd = &VECTOR_INDEX(map->list[sd->bl.m].qi_list, i);
+
+ int j;
+ ARR_FIND(0, VECTOR_LENGTH(nd->qi_data), j, quest->questinfo_validate(sd, &VECTOR_INDEX(nd->qi_data, j)) == true);
+ if (j != VECTOR_LENGTH(nd->qi_data)) {
+ struct questinfo *qi = &VECTOR_INDEX(nd->qi_data, j);
+ clif->quest_show_event(sd, &nd->bl, qi->icon, qi->color);
+ } else {
#if PACKETVER >= 20120410
- clif->quest_show_event(sd, &qi->nd->bl, 9999, 0);
+ clif->quest_show_event(sd, &nd->bl, 9999, 0);
#else
- clif->quest_show_event(sd, &qi->nd->bl, 0, 0);
+ clif->quest_show_event(sd, &nd->bl, 0, 0);
#endif
- } else {
- clif->quest_show_event(sd, &qi->nd->bl, qi->icon, qi->color);
}
}
}
@@ -927,26 +928,6 @@ static bool quest_questinfo_validate_mercenary_class(struct map_session_data *sd
}
/**
- * Clears the questinfo data vector
- *
- * @param m mapindex.
- *
- */
-static void quest_questinfo_vector_clear(int m)
-{
- int i;
-
- Assert_retv(m >= 0 && m < map->count);
-
- for (i = 0; i < VECTOR_LENGTH(map->list[m].qi_data); i++) {
- struct questinfo *qi_data = &VECTOR_INDEX(map->list[m].qi_data, i);
- VECTOR_CLEAR(qi_data->items);
- VECTOR_CLEAR(qi_data->quest_requirement);
- }
- VECTOR_CLEAR(map->list[m].qi_data);
-}
-
-/**
* Initializes the quest interface.
*
* @param minimal Run in minimal mode (skips most of the loading)
@@ -1020,5 +1001,4 @@ void quest_defaults(void)
quest->questinfo_validate_homunculus_type = quest_questinfo_validate_homunculus_type;
quest->questinfo_validate_quests = quest_questinfo_validate_quests;
quest->questinfo_validate_mercenary_class = quest_questinfo_validate_mercenary_class;
- quest->questinfo_vector_clear = quest_questinfo_vector_clear;
}
diff --git a/src/map/quest.h b/src/map/quest.h
index 206a7902f..d60b9b33c 100644
--- a/src/map/quest.h
+++ b/src/map/quest.h
@@ -60,6 +60,39 @@ enum quest_check_type {
HUNTING, ///< Check if the given hunting quest's requirements have been met
};
+struct questinfo_qreq {
+ int id;
+ int state;
+};
+
+struct questinfo_itemreq {
+ int nameid;
+ int min;
+ int max;
+};
+
+struct questinfo {
+ unsigned short icon;
+ unsigned char color;
+ bool hasJob;
+ unsigned int job;/* perhaps a mapid mask would be most flexible? */
+ bool sex_enabled;
+ int sex;
+ struct {
+ int min;
+ int max;
+ } base_level;
+ struct {
+ int min;
+ int max;
+ } job_level;
+ VECTOR_DECL(struct questinfo_itemreq) items;
+ struct s_homunculus homunculus;
+ int homunculus_type;
+ VECTOR_DECL(struct questinfo_qreq) quest_requirement;
+ int mercenary_class;
+};
+
struct quest_interface {
struct quest_db **db_data; ///< Quest database
struct quest_db dummy; ///< Dummy entry for invalid quest lookups
@@ -93,7 +126,6 @@ struct quest_interface {
bool (*questinfo_validate_homunculus_type) (struct map_session_data *sd, struct questinfo *qi);
bool (*questinfo_validate_quests) (struct map_session_data *sd, struct questinfo *qi);
bool (*questinfo_validate_mercenary_class) (struct map_session_data *sd, struct questinfo *qi);
- void (*questinfo_vector_clear) (int m);
};
#ifdef HERCULES_CORE
diff --git a/src/map/refine.c b/src/map/refine.c
index 1ff893c56..4fe6e73c4 100644
--- a/src/map/refine.c
+++ b/src/map/refine.c
@@ -528,7 +528,7 @@ static int refine_readdb_refine_libconfig_sub(struct config_setting_t *r, const
chance[i][j] = 100; // default value for all rates.
struct config_setting_t *t = NULL;
- for (int i = 0; (t = libconfig->setting_get_elem(rate, i++)) != NULL && config_setting_is_group(t); ++i) {
+ for (int i = 0; (t = libconfig->setting_get_elem(rate, i)) != NULL && config_setting_is_group(t); ++i) {
int level = 0, i32;
char *rlvl = config_setting_name(t);
memset(&lv, 0, sizeof(lv));
diff --git a/src/map/script.c b/src/map/script.c
index 5843ac292..35217a4d7 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -5962,6 +5962,19 @@ static BUILDIN(next)
return true;
}
+/// Clears the NPC dialog and continues the script without press next button.
+///
+/// mesclear();
+static BUILDIN(mesclear)
+{
+ struct map_session_data *sd = script->rid2sd(st);
+
+ if (sd != NULL)
+ clif->scriptclear(sd, st->oid);
+
+ return true;
+}
+
/// Ends the script and displays the button 'close' on the npc dialog.
/// The dialog is closed when the button is pressed.
///
@@ -6948,59 +6961,60 @@ static BUILDIN(jobname)
return true;
}
-/// Get input from the player.
-/// For numeric inputs the value is capped to the range [min,max]. Returns 1 if
-/// the value was higher than 'max', -1 if lower than 'min' and 0 otherwise.
-/// For string inputs it returns 1 if the string was longer than 'max', -1 is
-/// shorter than 'min' and 0 otherwise.
-///
-/// input(<var>{,<min>{,<max>}}) -> <int>
+/*
+ * Get input from the player.
+ * For numeric inputs the value is capped to the range [min,max]. Returns 1 if
+ * the value was higher than 'max', -1 if lower than 'min' and 0 otherwise.
+ * For string inputs it returns 1 if the string was longer than 'max', -1 is
+ * shorter than 'min' and 0 otherwise.
+ *
+ * input(<var>{,<min>{,<max>}}) -> <int>
+ */
static BUILDIN(input)
{
- struct script_data* data;
- int64 uid;
- const char* name;
- int min;
- int max;
struct map_session_data *sd = script->rid2sd(st);
if (sd == NULL)
return true;
- data = script_getdata(st,2);
- if( !data_isreference(data) ) {
+ struct script_data *data = script_getdata(st, 2);
+ if (!data_isreference(data)) {
ShowError("script:input: not a variable\n");
script->reportdata(data);
st->state = END;
return false;
}
- uid = reference_getuid(data);
- name = reference_getname(data);
- min = (script_hasdata(st,3) ? script_getnum(st,3) : script->config.input_min_value);
- max = (script_hasdata(st,4) ? script_getnum(st,4) : script->config.input_max_value);
+
+ int64 uid = reference_getuid(data);
+ const char *name = reference_getname(data);
+ int min = (script_hasdata(st, 3) ? script_getnum(st, 3) : script->config.input_min_value);
+ int max = (script_hasdata(st, 4) ? script_getnum(st, 4) : script->config.input_max_value);
#ifdef SECURE_NPCTIMEOUT
sd->npc_idle_type = NPCT_WAIT;
#endif
- if( !sd->state.menu_or_input ) {
+ if (!sd->state.menu_or_input) {
// first invocation, display npc input box
sd->state.menu_or_input = 1;
st->state = RERUNLINE;
- if( is_string_variable(name) )
- clif->scriptinputstr(sd,st->oid);
- else
- clif->scriptinput(sd,st->oid);
+ if (is_string_variable(name)) {
+ clif->scriptinputstr(sd, st->oid);
+ } else {
+ sd->npc_amount_min = min;
+ sd->npc_amount_max = max;
+ clif->scriptinput(sd, st->oid);
+ }
} else {
// take received text/value and store it in the designated variable
sd->state.menu_or_input = 0;
if (is_string_variable(name)) {
int len = (int)strlen(sd->npc_str);
- script->set_reg(st, sd, uid, name, sd->npc_str, script_getref(st,2));
+ script->set_reg(st, sd, uid, name, sd->npc_str, script_getref(st, 2));
script_pushint(st, (len > max ? 1 : len < min ? -1 : 0));
} else {
int amount = sd->npc_amount;
script->set_reg(st, sd, uid, name, (const void *)h64BPTRSIZE(cap_value(amount,min,max)), script_getref(st,2));
- script_pushint(st, (amount > max ? 1 : amount < min ? -1 : 0));
+ script_pushint(st, sd->npc_input_capped_range);
}
st->state = RUN;
}
@@ -8617,6 +8631,48 @@ static BUILDIN(delitem2)
return false;
}
+/**
+ * Deletes item at given index.
+ * delitem(<index>{, <amount{, <account id>}});
+ */
+static BUILDIN(delitemidx)
+{
+ struct map_session_data *sd;
+
+ if (script_hasdata(st, 4)) {
+ if ((sd = script->id2sd(st, script_getnum(st, 4))) == NULL) {
+ st->state = END;
+ return true;
+ }
+ } else {
+ if ((sd = script->rid2sd(st)) == NULL)
+ return true;
+ }
+
+ int i = script_getnum(st, 2);
+ if (i < 0 || i >= sd->status.inventorySize) {
+ ShowError("buildin_delitemidx: Index (%d) should be from 0-%d.\n", i, sd->status.inventorySize - 1);
+ st->state = END;
+ return false;
+ }
+
+ if (itemdb->exists(sd->status.inventory[i].nameid) == NULL)
+ ShowWarning("buildin_delitemidx: Deleting invalid Item ID (%d).\n", sd->status.inventory[i].nameid);
+
+ int amount = 0;
+ if (script_hasdata(st, 3)) {
+ if ((amount = script_getnum(st, 3)) > sd->status.inventory[i].amount)
+ amount = sd->status.inventory[i].amount;
+ } else {
+ amount = sd->status.inventory[i].amount;
+ }
+
+ if (amount > 0)
+ script->buildin_delitem_delete(sd, i, &amount, true);
+
+ return true;
+}
+
/*==========================================
* Enables/Disables use of items while in an NPC [Skotlex]
*------------------------------------------*/
@@ -8987,6 +9043,63 @@ static BUILDIN(getguildmember)
return true;
}
+/**
+ * getguildonline(<Guild ID>{, type})
+ * Returns amount of guild members online.
+**/
+
+enum script_getguildonline_types {
+ GUILD_ONLINE_ALL = 0,
+ GUILD_ONLINE_VENDOR,
+ GUILD_ONLINE_NO_VENDOR
+};
+
+BUILDIN(getguildonline)
+{
+ struct guild *g;
+ int guild_id = script_getnum(st, 2);
+ int type = GUILD_ONLINE_ALL, j = 0;
+
+ if ((g = guild->search(guild_id)) == NULL) {
+ script_pushint(st, -1);
+ return true;
+ }
+
+ if (script_hasdata(st, 3)) {
+ type = script_getnum(st, 3);
+
+ if (type < GUILD_ONLINE_ALL || type > GUILD_ONLINE_NO_VENDOR) {
+ ShowWarning("buildin_getguildonline: Invalid type specified. Defaulting to GUILD_ONLINE_ALL.\n");
+ type = GUILD_ONLINE_ALL;
+ }
+ }
+
+ struct map_session_data *sd;
+ for (int i = 0; i < MAX_GUILD; i++) {
+ if (g->member[i].online && (sd = g->member[i].sd) != NULL) {
+ switch (type) {
+ case GUILD_ONLINE_VENDOR:
+ if (sd->state.vending > 0)
+ j++;
+ break;
+
+ case GUILD_ONLINE_NO_VENDOR:
+ if (sd->state.vending == 0)
+ j++;
+ break;
+
+ default:
+ j++;
+ break;
+ }
+ }
+ }
+
+ script_pushint(st, j);
+
+ return true;
+}
+
/*==========================================
* Get char string information by type :
* Return by @type :
@@ -10653,6 +10766,12 @@ static BUILDIN(openstorage)
return false;
}
+ // Mapflag preventing from openstorage here
+ if (!pc_has_permission(sd, PC_PERM_BYPASS_NOSTORAGE) && (map->list[sd->bl.m].flag.nostorage & 2)) {
+ script_pushint(st, 0);
+ return true;
+ }
+
storage->open(sd);
script_pushint(st, 1); // success flag.
@@ -10666,6 +10785,12 @@ static BUILDIN(guildopenstorage)
if (sd == NULL)
return true;
+ // Mapflag preventing from openstorage here
+ if (!pc_has_permission(sd, PC_PERM_BYPASS_NOSTORAGE) && (map->list[sd->bl.m].flag.nogstorage & 2)) {
+ script_pushint(st, 1);
+ return true;
+ }
+
ret = gstorage->open(sd);
script_pushint(st,ret);
return true;
@@ -11044,10 +11169,16 @@ static BUILDIN(killmonster)
int16 m,allflag=0;
mapname=script_getstr(st,2);
event=script_getstr(st,3);
- if(strcmp(event,"All")==0)
+
+ if (strcmpi(event, "all") == 0) {
+ if (strcmp(event, "all") != 0) {
+ ShowWarning("buildin_killmonster: \"%s\" deprecated! Please use \"all\" instead.\n", event);
+ script->reportsrc(st);
+ }
allflag = 1;
- else
+ } else {
script->check_event(st, event);
+ }
if( (m=map->mapname2mapid(mapname))<0 )
return true;
@@ -13052,7 +13183,8 @@ enum mapinfo_info {
MAPINFO_ID,
MAPINFO_SIZE_X,
MAPINFO_SIZE_Y,
- MAPINFO_ZONE
+ MAPINFO_ZONE,
+ MAPINFO_NPC_COUNT
};
static BUILDIN(getmapinfo)
@@ -13077,7 +13209,7 @@ static BUILDIN(getmapinfo)
}
if (bl == NULL) {
- ShowError("script:getmapinfo: map not supplied and NPC/PC not attached!\n");
+ ShowError("buildin_getmapinfo: map not supplied and NPC/PC not attached!\n");
script_pushint(st, -3);
return false;
}
@@ -13108,8 +13240,11 @@ static BUILDIN(getmapinfo)
case MAPINFO_ZONE:
script_pushstrcopy(st, map->list[m].zone->name);
break;
+ case MAPINFO_NPC_COUNT:
+ script_pushint(st, map->list[m].npc_num);
+ break;
default:
- ShowError("script:getmapinfo: unknown option in second argument (%u).\n", mode);
+ ShowError("buildin_getmapinfo: unknown option in second argument (%u).\n", mode);
script_pushint(st, -2);
return false;
}
@@ -13183,6 +13318,8 @@ static BUILDIN(getmapflag)
case MF_NOVIEWID: script_pushint(st, map->list[m].flag.noviewid); break;
case MF_PAIRSHIP_STARTABLE: script_pushint(st, map->list[m].flag.pairship_startable); break;
case MF_PAIRSHIP_ENDABLE: script_pushint(st, map->list[m].flag.pairship_endable); break;
+ case MF_NOSTORAGE: script_pushint(st, map->list[m].flag.nostorage); break;
+ case MF_NOGSTORAGE: script_pushint(st, map->list[m].flag.nogstorage); break;
}
}
@@ -13313,6 +13450,8 @@ static BUILDIN(setmapflag)
case MF_NOVIEWID: map->list[m].flag.noviewid = (val <= 0) ? EQP_NONE : val; break;
case MF_PAIRSHIP_STARTABLE: map->list[m].flag.pairship_startable = 1; break;
case MF_PAIRSHIP_ENDABLE: map->list[m].flag.pairship_endable = 1; break;
+ case MF_NOSTORAGE: map->list[m].flag.nostorage = cap_value(val, 0, 3); break;
+ case MF_NOGSTORAGE: map->list[m].flag.nogstorage = cap_value(val, 0, 3); break;
}
}
@@ -13404,6 +13543,8 @@ static BUILDIN(removemapflag)
case MF_NOCASHSHOP: map->list[m].flag.nocashshop = 0; break;
case MF_NOAUTOLOOT: map->list[m].flag.noautoloot = 0; break;
case MF_NOVIEWID: map->list[m].flag.noviewid = EQP_NONE; break;
+ case MF_NOSTORAGE: map->list[m].flag.nostorage = 0; break;
+ case MF_NOGSTORAGE: map->list[m].flag.nogstorage = 0; break;
}
}
@@ -13915,7 +14056,8 @@ static BUILDIN(failedremovecards)
if (sd->status.inventory[i].card[c] > 0 && itemdb_type(sd->status.inventory[i].card[c]) == IT_CARD) {
cardflag = 1;
- sd->status.inventory[i].card[c] = 0;
+ if (typefail == 1)
+ sd->status.inventory[i].card[c] = 0;
if (typefail == 2) { // add cards to inventory, clear
int flag;
@@ -15918,37 +16060,41 @@ static BUILDIN(npctalk)
// change npc walkspeed [Valaris]
static BUILDIN(npcspeed)
{
- struct npc_data* nd;
- int speed;
-
- speed = script_getnum(st,2);
- nd = map->id2nd(st->oid);
+ struct npc_data *nd = map->id2nd(st->oid);
+ int speed = script_getnum(st, 2);
if (nd != NULL) {
unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit
+ if (nd->ud == NULL) {
+ ShowWarning("buildin_npcspeed: floating NPC don't have unit data.\n");
+ return false;
+ }
nd->speed = speed;
nd->ud->state.speed_changed = 1;
}
return true;
}
+
// make an npc walk to a position [Valaris]
static BUILDIN(npcwalkto)
{
struct npc_data *nd = map->id2nd(st->oid);
- int x=0,y=0;
-
- x=script_getnum(st,2);
- y=script_getnum(st,3);
+ int x = script_getnum(st, 2);
+ int y = script_getnum(st, 3);
if (nd != NULL) {
unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit
+ if (nd->ud == NULL) {
+ ShowWarning("buildin_npcwalkto: floating NPC don't have unit data.\n");
+ return false;
+ }
if (!nd->status.hp) {
status_calc_npc(nd, SCO_FIRST);
} else {
status_calc_npc(nd, SCO_NONE);
}
- unit->walktoxy(&nd->bl,x,y,0);
+ unit->walktoxy(&nd->bl, x, y, 0);
}
return true;
@@ -15960,6 +16106,10 @@ static BUILDIN(npcstop)
if (nd != NULL) {
unit->bl2ud2(&nd->bl); // ensure nd->ud is safe to edit
+ if (nd->ud == NULL) {
+ ShowWarning("buildin_npcstop: floating NPC don't have unit data.\n");
+ return false;
+ }
unit->stop_walking(&nd->bl, STOPWALKING_FLAG_FIXPOS|STOPWALKING_FLAG_NEXTCELL);
}
@@ -17778,6 +17928,17 @@ static BUILDIN(max)
return true;
}
+static BUILDIN(cap_value)
+{
+ int value = script_getnum(st, 2);
+ int min = script_getnum(st, 3);
+ int max = script_getnum(st, 4);
+
+ script_pushint(st, (int)cap_value(value, min, max));
+
+ return true;
+}
+
static BUILDIN(md5)
{
const char *tmpstr;
@@ -20443,24 +20604,28 @@ static BUILDIN(getunittitle)
/// unitwalk(<unit_id>,<target_id>) -> <bool>
static BUILDIN(unitwalk)
{
- struct block_list* bl;
+ struct block_list *bl = map->id2bl(script_getnum(st, 2));
- bl = map->id2bl(script_getnum(st,2));
- if( bl == NULL ) {
+ if (bl == NULL) {
script_pushint(st, 0);
return true;
}
- if( bl->type == BL_NPC ) {
- unit->bl2ud2(bl); // ensure the ((struct npc_data*)bl)->ud is safe to edit
+ if (bl->type == BL_NPC) {
+ struct unit_data *ud = unit->bl2ud2(bl); // ensure the ((struct npc_data*)bl)->ud is safe to edit
+ if (ud == NULL) {
+ ShowWarning("buildin_unitwalk: floating NPC don't have unit data.\n");
+ return false;
+ }
}
- if( script_hasdata(st,4) ) {
- int x = script_getnum(st,3);
- int y = script_getnum(st,4);
- script_pushint(st, unit->walktoxy(bl,x,y,0));// We'll use harder calculations.
- } else {
- int target_id = script_getnum(st,3);
- script_pushint(st, unit->walktobl(bl,map->id2bl(target_id),1,1));
+ if (script_hasdata(st, 4)) {
+ int x = script_getnum(st, 3);
+ int y = script_getnum(st, 4);
+ script_pushint(st, unit->walktoxy(bl, x, y, 0));// We'll use harder calculations.
+ }
+ else {
+ int target_id = script_getnum(st, 3);
+ script_pushint(st, unit->walktobl(bl, map->id2bl(target_id), 1, 1));
}
return true;
@@ -20484,32 +20649,34 @@ static BUILDIN(unitkill)
/// unitwarp(<unit_id>,"<map name>",<x>,<y>) -> <bool>
static BUILDIN(unitwarp)
{
- int unit_id;
+ int unit_id = script_getnum(st, 2);
+ const char *mapname = script_getstr(st, 3);
+ short x = (short)script_getnum(st, 4);
+ short y = (short)script_getnum(st, 5);
int mapid;
- short x;
- short y;
- struct block_list* bl;
- const char *mapname;
-
- unit_id = script_getnum(st,2);
- mapname = script_getstr(st, 3);
- x = (short)script_getnum(st,4);
- y = (short)script_getnum(st,5);
+ struct block_list *bl;
if (!unit_id) //Warp the script's runner
bl = map->id2bl(st->rid);
else
bl = map->id2bl(unit_id);
- if( strcmp(mapname,"this") == 0 )
- mapid = bl?bl->m:-1;
+ if (strcmp(mapname, "this") == 0)
+ mapid = bl ? bl->m : -1;
else
mapid = map->mapname2mapid(mapname);
- if( mapid >= 0 && bl != NULL ) {
- unit->bl2ud2(bl); // ensure ((struct npc_data *)bl)->ud is safe to edit
- script_pushint(st, unit->warp(bl,mapid,x,y,CLR_OUTSIGHT));
- } else {
+ if (mapid >= 0 && bl != NULL) {
+ struct unit_data *ud = unit->bl2ud2(bl); // ensure ((struct npc_data *)bl)->ud is safe to edit
+ if (bl->type == BL_NPC) {
+ if (ud == NULL) {
+ ShowWarning("buildin_unitwarp: floating NPC don't have unit data.\n");
+ return false;
+ }
+ }
+ script_pushint(st, unit->warp(bl, mapid, x, y, CLR_OUTSIGHT));
+ }
+ else {
script_pushint(st, 0);
}
@@ -20580,17 +20747,19 @@ static BUILDIN(unitattack)
/// unitstop <unit_id>;
static BUILDIN(unitstop)
{
- int unit_id;
- struct block_list* bl;
-
- unit_id = script_getnum(st,2);
+ struct block_list *bl = map->id2bl(script_getnum(st, 2));
- bl = map->id2bl(unit_id);
- if( bl != NULL ) {
- unit->bl2ud2(bl); // ensure ((struct npc_data *)bl)->ud is safe to edit
+ if (bl != NULL) {
+ struct unit_data *ud = unit->bl2ud2(bl); // ensure ((struct npc_data *)bl)->ud is safe to edit
+ if (bl->type == BL_NPC) {
+ if (ud == NULL) {
+ ShowWarning("buildin_unitstop: floating NPC don't have unit data.\n");
+ return false;
+ }
+ }
unit->stop_attack(bl);
unit->stop_walking(bl, STOPWALKING_FLAG_NEXTCELL);
- if( bl->type == BL_MOB )
+ if (bl->type == BL_MOB)
BL_UCAST(BL_MOB, bl)->target_id = 0;
}
@@ -21256,7 +21425,6 @@ static BUILDIN(questinfo)
return false;
}
- qi.nd = nd;
qi.icon = quest->questinfo_validate_icon(icon);
if (script_hasdata(st, 3)) {
int color = script_getnum(st, 3);
@@ -21268,7 +21436,9 @@ static BUILDIN(questinfo)
qi.color = (unsigned char)color;
}
- map->add_questinfo(nd->bl.m, &qi);
+ VECTOR_ENSURE(nd->qi_data, 1, 1);
+ VECTOR_PUSH(nd->qi_data, qi);
+ map->add_questinfo(nd->bl.m, nd);
return true;
}
@@ -21286,15 +21456,12 @@ static BUILDIN(setquestinfo)
return false;
}
- qi = &VECTOR_LAST(map->list[nd->bl.m].qi_data);
+ qi = &VECTOR_LAST(nd->qi_data);
if (qi == NULL) {
ShowWarning("buildin_setquestinfo: no valide questinfo data has been found for this npc.\n");
return false;
}
- if (qi->nd != nd) {
- ShowWarning("buildin_setquestinfo: invalid usage, setquestinfo must be used only after questinfo.\n");
- return false;
- }
+
switch (type) {
case QINFO_JOB:
{
@@ -24681,6 +24848,49 @@ static BUILDIN(consolemes)
return true;
}
+static BUILDIN(setfavoriteitemidx)
+{
+ struct map_session_data *sd = script_rid2sd(st);
+ int idx = script_getnum(st, 2);
+ int value = script_getnum(st, 3);
+
+ if (sd == NULL) {
+ ShowError("buildin_setfavoriteitemidx: No player attached.\n");
+ return false;
+ }
+
+ if (idx < 0 || idx >= sd->status.inventorySize) {
+ ShowError("buildin_setfavoriteitemidx: Invalid inventory index %d (min: %d, max: %d).\n", idx, 0, (sd->status.inventorySize - 1));
+ return false;
+ } else if (sd->inventory_data[idx] == NULL || sd->inventory_data[idx]->nameid <= 0) {
+ ShowWarning("buildin_setfavoriteitemidx: Current inventory index %d has no data.\n", idx);
+ return false;
+ } else if (sd->status.inventory[idx].equip > 0) {
+ ShowWarning("buildin_setfavoriteitemidx: Cant change favorite flag of an equipped item.\n");
+ return false;
+ } else {
+ sd->status.inventory[idx].favorite = cap_value(value, 0, 1);
+ clif->favorite_item(sd, idx);
+ }
+
+ return true;
+}
+
+static BUILDIN(autofavoriteitem)
+{
+ int nameid = script_getnum(st, 2);
+ int flag = script_getnum(st, 3);
+ struct item_data *item_data;
+
+ if ((item_data = itemdb->exists(nameid)) == NULL) {
+ ShowError("buildin_autofavoriteitem: Invalid item '%d'.\n", nameid);
+ return false;
+ }
+
+ item_data->flag.auto_favorite = cap_value(flag, 0, 1);
+ return true;
+}
+
/** place holder for the translation macro **/
static BUILDIN(_)
{
@@ -25233,7 +25443,7 @@ static BUILDIN(enchantitem)
}
// send ack to inventory expand request
-static BUILDIN(expandInventoryAck)
+static BUILDIN(expandinventoryack)
{
struct map_session_data *sd = script_rid2sd(st);
if (sd == NULL)
@@ -25247,7 +25457,7 @@ static BUILDIN(expandInventoryAck)
}
// send final ack to inventory expand request
-static BUILDIN(expandInventoryResult)
+static BUILDIN(expandinventoryresult)
{
struct map_session_data *sd = script_rid2sd(st);
if (sd == NULL)
@@ -25257,7 +25467,7 @@ static BUILDIN(expandInventoryResult)
}
// adjust player inventory size to given value positive or negative
-static BUILDIN(expandInventory)
+static BUILDIN(expandinventory)
{
struct map_session_data *sd = script_rid2sd(st);
if (sd == NULL)
@@ -25267,7 +25477,7 @@ static BUILDIN(expandInventory)
}
// return current player inventory size
-static BUILDIN(getInventorySize)
+static BUILDIN(getinventorysize)
{
struct map_session_data *sd = script_rid2sd(st);
if (sd == NULL)
@@ -25469,6 +25679,7 @@ static void script_parse_builtin(void)
BUILDIN_DEF(mes, "?"),
BUILDIN_DEF(mesf, "s*"),
BUILDIN_DEF(next,""),
+ BUILDIN_DEF(mesclear,""),
BUILDIN_DEF(close,""),
BUILDIN_DEF(close2,""),
BUILDIN_DEF(menu,"sl*"),
@@ -25507,6 +25718,7 @@ static void script_parse_builtin(void)
BUILDIN_DEF(makeitem2,"viiiiiiii????"),
BUILDIN_DEF(delitem,"vi?"),
BUILDIN_DEF(delitem2,"viiiiiiii?"),
+ BUILDIN_DEF(delitemidx, "i??"),
BUILDIN_DEF2(enableitemuse,"enable_items",""),
BUILDIN_DEF2(disableitemuse,"disable_items",""),
BUILDIN_DEF(cutin,"si"),
@@ -25531,6 +25743,7 @@ static void script_parse_builtin(void)
BUILDIN_DEF(getguildmaster,"i"),
BUILDIN_DEF(getguildmasterid,"i"),
BUILDIN_DEF(getguildmember,"i?"),
+ BUILDIN_DEF(getguildonline, "i?"),
BUILDIN_DEF(strcharinfo,"i??"),
BUILDIN_DEF(strnpcinfo,"i??"),
BUILDIN_DEF(charid2rid,"i"),
@@ -25797,6 +26010,7 @@ static void script_parse_builtin(void)
// <--- List of mathematics commands
BUILDIN_DEF(min, "i*"),
BUILDIN_DEF(max, "i*"),
+ BUILDIN_DEF(cap_value, "iii"),
BUILDIN_DEF(md5,"s"),
BUILDIN_DEF(swap,"rr"),
// [zBuffer] List of dynamic var commands --->
@@ -26052,13 +26266,15 @@ static void script_parse_builtin(void)
BUILDIN_DEF(itempreview, "i"),
BUILDIN_DEF(enchantitem, "iii"),
- BUILDIN_DEF(expandInventoryAck, "i?"),
- BUILDIN_DEF(expandInventoryResult, "i"),
- BUILDIN_DEF(expandInventory, "i"),
- BUILDIN_DEF(getInventorySize, ""),
+ BUILDIN_DEF(expandinventoryack, "i?"),
+ BUILDIN_DEF(expandinventoryresult, "i"),
+ BUILDIN_DEF(expandinventory, "i"),
+ BUILDIN_DEF(getinventorysize, ""),
BUILDIN_DEF(closeroulette, ""),
BUILDIN_DEF(openrefineryui, ""),
+ BUILDIN_DEF(setfavoriteitemidx, "ii"),
+ BUILDIN_DEF(autofavoriteitem, "ii"),
};
int i, len = ARRAYLENGTH(BUILDIN);
RECREATE(script->buildin, char *, script->buildin_count + len); // Pre-alloc to speed up
@@ -26111,6 +26327,7 @@ static void script_hardcoded_constants(void)
script->set_constant("MAX_MENU_LENGTH", MAX_MENU_LENGTH, false, false);
script->set_constant("MOB_CLONE_START", MOB_CLONE_START, false, false);
script->set_constant("MOB_CLONE_END", MOB_CLONE_END, false, false);
+ script->set_constant("MAX_NPC_PER_MAP", MAX_NPC_PER_MAP, false, false);
script->constdb_comment("status options");
script->set_constant("Option_Nothing",OPTION_NOTHING,false, false);
@@ -26290,6 +26507,7 @@ static void script_hardcoded_constants(void)
script->set_constant("PERM_DISABLE_STORE", PC_PERM_DISABLE_STORE, false, false);
script->set_constant("PERM_DISABLE_EXP", PC_PERM_DISABLE_EXP, false, false);
script->set_constant("PERM_DISABLE_SKILL_USAGE", PC_PERM_DISABLE_SKILL_USAGE, false, false);
+ script->set_constant("PERM_BYPASS_NOSTORAGE", PC_PERM_BYPASS_NOSTORAGE, false, false);
script->constdb_comment("Data types");
script->set_constant("DATATYPE_NIL", DATATYPE_NIL, false, false);
@@ -26361,6 +26579,7 @@ static void script_hardcoded_constants(void)
script->set_constant("MAPINFO_SIZE_X", MAPINFO_SIZE_X, false, false);
script->set_constant("MAPINFO_SIZE_Y", MAPINFO_SIZE_Y, false, false);
script->set_constant("MAPINFO_ZONE", MAPINFO_ZONE, false, false);
+ script->set_constant("MAPINFO_NPC_COUNT", MAPINFO_NPC_COUNT, false, false);
script->constdb_comment("consolemes options");
script->set_constant("CONSOLEMES_DEBUG", CONSOLEMES_DEBUG, false, false);
@@ -26600,6 +26819,11 @@ static void script_hardcoded_constants(void)
script->set_constant("UDT_BODY2", UDT_BODY2, false, false);
script->set_constant("UDT_GROUP", UDT_GROUP, false, false);
+ script->constdb_comment("getguildonline types");
+ script->set_constant("GUILD_ONLINE_ALL", GUILD_ONLINE_ALL, false, false);
+ script->set_constant("GUILD_ONLINE_VENDOR", GUILD_ONLINE_VENDOR, false, false);
+ script->set_constant("GUILD_ONLINE_NO_VENDOR", GUILD_ONLINE_NO_VENDOR, false, false);
+
script->constdb_comment("Renewal");
#ifdef RENEWAL
script->set_constant("RENEWAL", 1, false, false);
diff --git a/src/map/script.h b/src/map/script.h
index 4c1cc168d..62950ba8d 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -343,7 +343,9 @@ enum {
MF_NOAUTOLOOT,
MF_NOVIEWID,
MF_PAIRSHIP_STARTABLE,
- MF_PAIRSHIP_ENDABLE
+ MF_PAIRSHIP_ENDABLE,
+ MF_NOSTORAGE,
+ MF_NOGSTORAGE
};
enum navigation_service {
diff --git a/src/map/status.h b/src/map/status.h
index 5f53b715a..853a7a1a6 100644
--- a/src/map/status.h
+++ b/src/map/status.h
@@ -2058,8 +2058,9 @@ typedef struct weapon_atk {
struct status_data {
uint32
hp, sp, // see status_cpy before adding members before hp and sp
- max_hp, max_sp,
- str, agi, vit, int_, dex, luk,
+ max_hp, max_sp;
+ uint16 str, agi, vit, int_, dex, luk;
+ uint32
batk,
matk_min, matk_max,
speed,
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index 920f81ca5..b59d80b9c 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -1300,8 +1300,10 @@ typedef void (*HPMHOOK_pre_clif_update_rankingpoint) (struct map_session_data **
typedef void (*HPMHOOK_post_clif_update_rankingpoint) (struct map_session_data *sd, enum fame_list_type type, int points);
typedef void (*HPMHOOK_pre_clif_pRanklist) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pRanklist) (int fd, struct map_session_data *sd);
-typedef void (*HPMHOOK_pre_clif_hotkeys) (struct map_session_data **sd);
-typedef void (*HPMHOOK_post_clif_hotkeys) (struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_hotkeys) (struct map_session_data **sd, int *tab);
+typedef void (*HPMHOOK_post_clif_hotkeys) (struct map_session_data *sd, int tab);
+typedef void (*HPMHOOK_pre_clif_hotkeysAll) (struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_hotkeysAll) (struct map_session_data *sd);
typedef int (*HPMHOOK_pre_clif_insight) (struct block_list **bl, va_list ap);
typedef int (*HPMHOOK_post_clif_insight) (int retVal___, struct block_list *bl, va_list ap);
typedef int (*HPMHOOK_pre_clif_outsight) (struct block_list **bl, va_list ap);
@@ -2086,8 +2088,10 @@ typedef void (*HPMHOOK_pre_clif_pLoadEndAck) (int *fd, struct map_session_data *
typedef void (*HPMHOOK_post_clif_pLoadEndAck) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_pTickSend) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pTickSend) (int fd, struct map_session_data *sd);
-typedef void (*HPMHOOK_pre_clif_pHotkey) (int *fd, struct map_session_data **sd);
-typedef void (*HPMHOOK_post_clif_pHotkey) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_pHotkey1) (int *fd, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_pHotkey1) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_pHotkey2) (int *fd, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_pHotkey2) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_pProgressbar) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pProgressbar) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_pWalkToXY) (int *fd, struct map_session_data **sd);
@@ -2546,8 +2550,10 @@ typedef void (*HPMHOOK_pre_clif_pNPCMarketPurchase) (int *fd, struct map_session
typedef void (*HPMHOOK_post_clif_pNPCMarketPurchase) (int fd, struct map_session_data *sd);
typedef int (*HPMHOOK_pre_clif_add_item_options) (struct ItemOptions **buf, const struct item **it);
typedef int (*HPMHOOK_post_clif_add_item_options) (int retVal___, struct ItemOptions *buf, const struct item *it);
-typedef void (*HPMHOOK_pre_clif_pHotkeyRowShift) (int *fd, struct map_session_data **sd);
-typedef void (*HPMHOOK_post_clif_pHotkeyRowShift) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_pHotkeyRowShift1) (int *fd, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_pHotkeyRowShift1) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_pHotkeyRowShift2) (int *fd, struct map_session_data **sd);
+typedef void (*HPMHOOK_post_clif_pHotkeyRowShift2) (int fd, struct map_session_data *sd);
typedef void (*HPMHOOK_pre_clif_dressroom_open) (struct map_session_data **sd, int *view);
typedef void (*HPMHOOK_post_clif_dressroom_open) (struct map_session_data *sd, int view);
typedef void (*HPMHOOK_pre_clif_pOneClick_ItemIdentify) (int *fd, struct map_session_data **sd);
@@ -4816,8 +4822,8 @@ typedef void (*HPMHOOK_pre_map_update_cell_bl) (struct block_list **bl, bool *in
typedef void (*HPMHOOK_post_map_update_cell_bl) (struct block_list *bl, bool increase);
typedef int (*HPMHOOK_pre_map_get_new_bonus_id) (void);
typedef int (*HPMHOOK_post_map_get_new_bonus_id) (int retVal___);
-typedef void (*HPMHOOK_pre_map_add_questinfo) (int *m, struct questinfo **qi);
-typedef void (*HPMHOOK_post_map_add_questinfo) (int m, struct questinfo *qi);
+typedef bool (*HPMHOOK_pre_map_add_questinfo) (int *m, struct npc_data **nd);
+typedef bool (*HPMHOOK_post_map_add_questinfo) (bool retVal___, int m, struct npc_data *nd);
typedef bool (*HPMHOOK_pre_map_remove_questinfo) (int *m, struct npc_data **nd);
typedef bool (*HPMHOOK_post_map_remove_questinfo) (bool retVal___, int m, struct npc_data *nd);
typedef struct map_zone_data* (*HPMHOOK_pre_map_merge_zone) (struct map_zone_data **main, struct map_zone_data **other);
@@ -5794,6 +5800,8 @@ typedef bool (*HPMHOOK_pre_npc_db_checkid) (const int *id);
typedef bool (*HPMHOOK_post_npc_db_checkid) (bool retVal___, const int id);
typedef void (*HPMHOOK_pre_npc_refresh) (struct npc_data **nd);
typedef void (*HPMHOOK_post_npc_refresh) (struct npc_data *nd);
+typedef void (*HPMHOOK_pre_npc_questinfo_clear) (struct npc_data **nd);
+typedef void (*HPMHOOK_post_npc_questinfo_clear) (struct npc_data *nd);
typedef int (*HPMHOOK_pre_npc_secure_timeout_timer) (int *tid, int64 *tick, int *id, intptr_t *data);
typedef int (*HPMHOOK_post_npc_secure_timeout_timer) (int retVal___, int tid, int64 tick, int id, intptr_t data);
#endif // MAP_NPC_H
@@ -6626,8 +6634,6 @@ typedef bool (*HPMHOOK_pre_quest_questinfo_validate_quests) (struct map_session_
typedef bool (*HPMHOOK_post_quest_questinfo_validate_quests) (bool retVal___, struct map_session_data *sd, struct questinfo *qi);
typedef bool (*HPMHOOK_pre_quest_questinfo_validate_mercenary_class) (struct map_session_data **sd, struct questinfo **qi);
typedef bool (*HPMHOOK_post_quest_questinfo_validate_mercenary_class) (bool retVal___, struct map_session_data *sd, struct questinfo *qi);
-typedef void (*HPMHOOK_pre_quest_questinfo_vector_clear) (int *m);
-typedef void (*HPMHOOK_post_quest_questinfo_vector_clear) (int m);
#endif // MAP_QUEST_H
#ifdef MAP_REFINE_H /* refine */
typedef int (*HPMHOOK_pre_refine_init) (bool *minimal);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 9c0b1905e..454a5229c 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -892,6 +892,8 @@ struct {
struct HPMHookPoint *HP_clif_pRanklist_post;
struct HPMHookPoint *HP_clif_hotkeys_pre;
struct HPMHookPoint *HP_clif_hotkeys_post;
+ struct HPMHookPoint *HP_clif_hotkeysAll_pre;
+ struct HPMHookPoint *HP_clif_hotkeysAll_post;
struct HPMHookPoint *HP_clif_insight_pre;
struct HPMHookPoint *HP_clif_insight_post;
struct HPMHookPoint *HP_clif_outsight_pre;
@@ -1676,8 +1678,10 @@ struct {
struct HPMHookPoint *HP_clif_pLoadEndAck_post;
struct HPMHookPoint *HP_clif_pTickSend_pre;
struct HPMHookPoint *HP_clif_pTickSend_post;
- struct HPMHookPoint *HP_clif_pHotkey_pre;
- struct HPMHookPoint *HP_clif_pHotkey_post;
+ struct HPMHookPoint *HP_clif_pHotkey1_pre;
+ struct HPMHookPoint *HP_clif_pHotkey1_post;
+ struct HPMHookPoint *HP_clif_pHotkey2_pre;
+ struct HPMHookPoint *HP_clif_pHotkey2_post;
struct HPMHookPoint *HP_clif_pProgressbar_pre;
struct HPMHookPoint *HP_clif_pProgressbar_post;
struct HPMHookPoint *HP_clif_pWalkToXY_pre;
@@ -2136,8 +2140,10 @@ struct {
struct HPMHookPoint *HP_clif_pNPCMarketPurchase_post;
struct HPMHookPoint *HP_clif_add_item_options_pre;
struct HPMHookPoint *HP_clif_add_item_options_post;
- struct HPMHookPoint *HP_clif_pHotkeyRowShift_pre;
- struct HPMHookPoint *HP_clif_pHotkeyRowShift_post;
+ struct HPMHookPoint *HP_clif_pHotkeyRowShift1_pre;
+ struct HPMHookPoint *HP_clif_pHotkeyRowShift1_post;
+ struct HPMHookPoint *HP_clif_pHotkeyRowShift2_pre;
+ struct HPMHookPoint *HP_clif_pHotkeyRowShift2_post;
struct HPMHookPoint *HP_clif_dressroom_open_pre;
struct HPMHookPoint *HP_clif_dressroom_open_post;
struct HPMHookPoint *HP_clif_pOneClick_ItemIdentify_pre;
@@ -4356,6 +4362,8 @@ struct {
struct HPMHookPoint *HP_npc_db_checkid_post;
struct HPMHookPoint *HP_npc_refresh_pre;
struct HPMHookPoint *HP_npc_refresh_post;
+ struct HPMHookPoint *HP_npc_questinfo_clear_pre;
+ struct HPMHookPoint *HP_npc_questinfo_clear_post;
struct HPMHookPoint *HP_npc_secure_timeout_timer_pre;
struct HPMHookPoint *HP_npc_secure_timeout_timer_post;
struct HPMHookPoint *HP_nullpo_assert_report_pre;
@@ -5136,8 +5144,6 @@ struct {
struct HPMHookPoint *HP_quest_questinfo_validate_quests_post;
struct HPMHookPoint *HP_quest_questinfo_validate_mercenary_class_pre;
struct HPMHookPoint *HP_quest_questinfo_validate_mercenary_class_post;
- struct HPMHookPoint *HP_quest_questinfo_vector_clear_pre;
- struct HPMHookPoint *HP_quest_questinfo_vector_clear_post;
struct HPMHookPoint *HP_refine_init_pre;
struct HPMHookPoint *HP_refine_init_post;
struct HPMHookPoint *HP_refine_final_pre;
@@ -7673,6 +7679,8 @@ struct {
int HP_clif_pRanklist_post;
int HP_clif_hotkeys_pre;
int HP_clif_hotkeys_post;
+ int HP_clif_hotkeysAll_pre;
+ int HP_clif_hotkeysAll_post;
int HP_clif_insight_pre;
int HP_clif_insight_post;
int HP_clif_outsight_pre;
@@ -8457,8 +8465,10 @@ struct {
int HP_clif_pLoadEndAck_post;
int HP_clif_pTickSend_pre;
int HP_clif_pTickSend_post;
- int HP_clif_pHotkey_pre;
- int HP_clif_pHotkey_post;
+ int HP_clif_pHotkey1_pre;
+ int HP_clif_pHotkey1_post;
+ int HP_clif_pHotkey2_pre;
+ int HP_clif_pHotkey2_post;
int HP_clif_pProgressbar_pre;
int HP_clif_pProgressbar_post;
int HP_clif_pWalkToXY_pre;
@@ -8917,8 +8927,10 @@ struct {
int HP_clif_pNPCMarketPurchase_post;
int HP_clif_add_item_options_pre;
int HP_clif_add_item_options_post;
- int HP_clif_pHotkeyRowShift_pre;
- int HP_clif_pHotkeyRowShift_post;
+ int HP_clif_pHotkeyRowShift1_pre;
+ int HP_clif_pHotkeyRowShift1_post;
+ int HP_clif_pHotkeyRowShift2_pre;
+ int HP_clif_pHotkeyRowShift2_post;
int HP_clif_dressroom_open_pre;
int HP_clif_dressroom_open_post;
int HP_clif_pOneClick_ItemIdentify_pre;
@@ -11137,6 +11149,8 @@ struct {
int HP_npc_db_checkid_post;
int HP_npc_refresh_pre;
int HP_npc_refresh_post;
+ int HP_npc_questinfo_clear_pre;
+ int HP_npc_questinfo_clear_post;
int HP_npc_secure_timeout_timer_pre;
int HP_npc_secure_timeout_timer_post;
int HP_nullpo_assert_report_pre;
@@ -11917,8 +11931,6 @@ struct {
int HP_quest_questinfo_validate_quests_post;
int HP_quest_questinfo_validate_mercenary_class_pre;
int HP_quest_questinfo_validate_mercenary_class_post;
- int HP_quest_questinfo_vector_clear_pre;
- int HP_quest_questinfo_vector_clear_post;
int HP_refine_init_pre;
int HP_refine_init_post;
int HP_refine_final_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 6c0b6db36..da2f81541 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -470,6 +470,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->update_rankingpoint, HP_clif_update_rankingpoint) },
{ HP_POP(clif->pRanklist, HP_clif_pRanklist) },
{ HP_POP(clif->hotkeys, HP_clif_hotkeys) },
+ { HP_POP(clif->hotkeysAll, HP_clif_hotkeysAll) },
{ HP_POP(clif->insight, HP_clif_insight) },
{ HP_POP(clif->outsight, HP_clif_outsight) },
{ HP_POP(clif->skillcastcancel, HP_clif_skillcastcancel) },
@@ -862,7 +863,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->pWantToConnection, HP_clif_pWantToConnection) },
{ HP_POP(clif->pLoadEndAck, HP_clif_pLoadEndAck) },
{ HP_POP(clif->pTickSend, HP_clif_pTickSend) },
- { HP_POP(clif->pHotkey, HP_clif_pHotkey) },
+ { HP_POP(clif->pHotkey1, HP_clif_pHotkey1) },
+ { HP_POP(clif->pHotkey2, HP_clif_pHotkey2) },
{ HP_POP(clif->pProgressbar, HP_clif_pProgressbar) },
{ HP_POP(clif->pWalkToXY, HP_clif_pWalkToXY) },
{ HP_POP(clif->pQuitGame, HP_clif_pQuitGame) },
@@ -1092,7 +1094,8 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->pNPCMarketClosed, HP_clif_pNPCMarketClosed) },
{ HP_POP(clif->pNPCMarketPurchase, HP_clif_pNPCMarketPurchase) },
{ HP_POP(clif->add_item_options, HP_clif_add_item_options) },
- { HP_POP(clif->pHotkeyRowShift, HP_clif_pHotkeyRowShift) },
+ { HP_POP(clif->pHotkeyRowShift1, HP_clif_pHotkeyRowShift1) },
+ { HP_POP(clif->pHotkeyRowShift2, HP_clif_pHotkeyRowShift2) },
{ HP_POP(clif->dressroom_open, HP_clif_dressroom_open) },
{ HP_POP(clif->pOneClick_ItemIdentify, HP_clif_pOneClick_ItemIdentify) },
{ HP_POP(clif->selectcart, HP_clif_selectcart) },
@@ -2230,6 +2233,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(npc->barter_delfromsql_sub, HP_npc_barter_delfromsql_sub) },
{ HP_POP(npc->db_checkid, HP_npc_db_checkid) },
{ HP_POP(npc->refresh, HP_npc_refresh) },
+ { HP_POP(npc->questinfo_clear, HP_npc_questinfo_clear) },
{ HP_POP(npc->secure_timeout_timer, HP_npc_secure_timeout_timer) },
/* nullpo_interface */
{ HP_POP(nullpo->assert_report, HP_nullpo_assert_report) },
@@ -2629,7 +2633,6 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(quest->questinfo_validate_homunculus_type, HP_quest_questinfo_validate_homunculus_type) },
{ HP_POP(quest->questinfo_validate_quests, HP_quest_questinfo_validate_quests) },
{ HP_POP(quest->questinfo_validate_mercenary_class, HP_quest_questinfo_validate_mercenary_class) },
- { HP_POP(quest->questinfo_vector_clear, HP_quest_questinfo_vector_clear) },
/* refine_interface */
{ HP_POP(refine->init, HP_refine_init) },
{ HP_POP(refine->final, HP_refine_final) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index 9cc986922..b31959ff4 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -11591,14 +11591,14 @@ void HP_clif_pRanklist(int fd, struct map_session_data *sd) {
}
return;
}
-void HP_clif_hotkeys(struct map_session_data *sd) {
+void HP_clif_hotkeys(struct map_session_data *sd, int tab) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_hotkeys_pre > 0) {
- void (*preHookFunc) (struct map_session_data **sd);
+ void (*preHookFunc) (struct map_session_data **sd, int *tab);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hotkeys_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_clif_hotkeys_pre[hIndex].func;
- preHookFunc(&sd);
+ preHookFunc(&sd, &tab);
}
if (*HPMforce_return) {
*HPMforce_return = false;
@@ -11606,12 +11606,38 @@ void HP_clif_hotkeys(struct map_session_data *sd) {
}
}
{
- HPMHooks.source.clif.hotkeys(sd);
+ HPMHooks.source.clif.hotkeys(sd, tab);
}
if (HPMHooks.count.HP_clif_hotkeys_post > 0) {
- void (*postHookFunc) (struct map_session_data *sd);
+ void (*postHookFunc) (struct map_session_data *sd, int tab);
for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hotkeys_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_clif_hotkeys_post[hIndex].func;
+ postHookFunc(sd, tab);
+ }
+ }
+ return;
+}
+void HP_clif_hotkeysAll(struct map_session_data *sd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_hotkeysAll_pre > 0) {
+ void (*preHookFunc) (struct map_session_data **sd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hotkeysAll_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_hotkeysAll_pre[hIndex].func;
+ preHookFunc(&sd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.hotkeysAll(sd);
+ }
+ if (HPMHooks.count.HP_clif_hotkeysAll_post > 0) {
+ void (*postHookFunc) (struct map_session_data *sd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_hotkeysAll_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_hotkeysAll_post[hIndex].func;
postHookFunc(sd);
}
}
@@ -21858,13 +21884,13 @@ void HP_clif_pTickSend(int fd, struct map_session_data *sd) {
}
return;
}
-void HP_clif_pHotkey(int fd, struct map_session_data *sd) {
+void HP_clif_pHotkey1(int fd, struct map_session_data *sd) {
int hIndex = 0;
- if (HPMHooks.count.HP_clif_pHotkey_pre > 0) {
+ if (HPMHooks.count.HP_clif_pHotkey1_pre > 0) {
void (*preHookFunc) (int *fd, struct map_session_data **sd);
*HPMforce_return = false;
- for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkey_pre; hIndex++) {
- preHookFunc = HPMHooks.list.HP_clif_pHotkey_pre[hIndex].func;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkey1_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_pHotkey1_pre[hIndex].func;
preHookFunc(&fd, &sd);
}
if (*HPMforce_return) {
@@ -21873,12 +21899,38 @@ void HP_clif_pHotkey(int fd, struct map_session_data *sd) {
}
}
{
- HPMHooks.source.clif.pHotkey(fd, sd);
+ HPMHooks.source.clif.pHotkey1(fd, sd);
}
- if (HPMHooks.count.HP_clif_pHotkey_post > 0) {
+ if (HPMHooks.count.HP_clif_pHotkey1_post > 0) {
void (*postHookFunc) (int fd, struct map_session_data *sd);
- for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkey_post; hIndex++) {
- postHookFunc = HPMHooks.list.HP_clif_pHotkey_post[hIndex].func;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkey1_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_pHotkey1_post[hIndex].func;
+ postHookFunc(fd, sd);
+ }
+ }
+ return;
+}
+void HP_clif_pHotkey2(int fd, struct map_session_data *sd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_pHotkey2_pre > 0) {
+ void (*preHookFunc) (int *fd, struct map_session_data **sd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkey2_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_pHotkey2_pre[hIndex].func;
+ preHookFunc(&fd, &sd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.pHotkey2(fd, sd);
+ }
+ if (HPMHooks.count.HP_clif_pHotkey2_post > 0) {
+ void (*postHookFunc) (int fd, struct map_session_data *sd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkey2_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_pHotkey2_post[hIndex].func;
postHookFunc(fd, sd);
}
}
@@ -27839,13 +27891,13 @@ int HP_clif_add_item_options(struct ItemOptions *buf, const struct item *it) {
}
return retVal___;
}
-void HP_clif_pHotkeyRowShift(int fd, struct map_session_data *sd) {
+void HP_clif_pHotkeyRowShift1(int fd, struct map_session_data *sd) {
int hIndex = 0;
- if (HPMHooks.count.HP_clif_pHotkeyRowShift_pre > 0) {
+ if (HPMHooks.count.HP_clif_pHotkeyRowShift1_pre > 0) {
void (*preHookFunc) (int *fd, struct map_session_data **sd);
*HPMforce_return = false;
- for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkeyRowShift_pre; hIndex++) {
- preHookFunc = HPMHooks.list.HP_clif_pHotkeyRowShift_pre[hIndex].func;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkeyRowShift1_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_pHotkeyRowShift1_pre[hIndex].func;
preHookFunc(&fd, &sd);
}
if (*HPMforce_return) {
@@ -27854,12 +27906,38 @@ void HP_clif_pHotkeyRowShift(int fd, struct map_session_data *sd) {
}
}
{
- HPMHooks.source.clif.pHotkeyRowShift(fd, sd);
+ HPMHooks.source.clif.pHotkeyRowShift1(fd, sd);
}
- if (HPMHooks.count.HP_clif_pHotkeyRowShift_post > 0) {
+ if (HPMHooks.count.HP_clif_pHotkeyRowShift1_post > 0) {
void (*postHookFunc) (int fd, struct map_session_data *sd);
- for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkeyRowShift_post; hIndex++) {
- postHookFunc = HPMHooks.list.HP_clif_pHotkeyRowShift_post[hIndex].func;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkeyRowShift1_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_pHotkeyRowShift1_post[hIndex].func;
+ postHookFunc(fd, sd);
+ }
+ }
+ return;
+}
+void HP_clif_pHotkeyRowShift2(int fd, struct map_session_data *sd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_pHotkeyRowShift2_pre > 0) {
+ void (*preHookFunc) (int *fd, struct map_session_data **sd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkeyRowShift2_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_pHotkeyRowShift2_pre[hIndex].func;
+ preHookFunc(&fd, &sd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.pHotkeyRowShift2(fd, sd);
+ }
+ if (HPMHooks.count.HP_clif_pHotkeyRowShift2_post > 0) {
+ void (*postHookFunc) (int fd, struct map_session_data *sd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_pHotkeyRowShift2_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_pHotkeyRowShift2_post[hIndex].func;
postHookFunc(fd, sd);
}
}
@@ -49379,31 +49457,32 @@ int HP_map_get_new_bonus_id(void) {
}
return retVal___;
}
-void HP_map_add_questinfo(int m, struct questinfo *qi) {
+bool HP_map_add_questinfo(int m, struct npc_data *nd) {
int hIndex = 0;
+ bool retVal___ = false;
if (HPMHooks.count.HP_map_add_questinfo_pre > 0) {
- void (*preHookFunc) (int *m, struct questinfo **qi);
+ bool (*preHookFunc) (int *m, struct npc_data **nd);
*HPMforce_return = false;
for (hIndex = 0; hIndex < HPMHooks.count.HP_map_add_questinfo_pre; hIndex++) {
preHookFunc = HPMHooks.list.HP_map_add_questinfo_pre[hIndex].func;
- preHookFunc(&m, &qi);
+ retVal___ = preHookFunc(&m, &nd);
}
if (*HPMforce_return) {
*HPMforce_return = false;
- return;
+ return retVal___;
}
}
{
- HPMHooks.source.map.add_questinfo(m, qi);
+ retVal___ = HPMHooks.source.map.add_questinfo(m, nd);
}
if (HPMHooks.count.HP_map_add_questinfo_post > 0) {
- void (*postHookFunc) (int m, struct questinfo *qi);
+ bool (*postHookFunc) (bool retVal___, int m, struct npc_data *nd);
for (hIndex = 0; hIndex < HPMHooks.count.HP_map_add_questinfo_post; hIndex++) {
postHookFunc = HPMHooks.list.HP_map_add_questinfo_post[hIndex].func;
- postHookFunc(m, qi);
+ retVal___ = postHookFunc(retVal___, m, nd);
}
}
- return;
+ return retVal___;
}
bool HP_map_remove_questinfo(int m, struct npc_data *nd) {
int hIndex = 0;
@@ -57872,6 +57951,32 @@ void HP_npc_refresh(struct npc_data *nd) {
}
return;
}
+void HP_npc_questinfo_clear(struct npc_data *nd) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_npc_questinfo_clear_pre > 0) {
+ void (*preHookFunc) (struct npc_data **nd);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_questinfo_clear_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_npc_questinfo_clear_pre[hIndex].func;
+ preHookFunc(&nd);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.npc.questinfo_clear(nd);
+ }
+ if (HPMHooks.count.HP_npc_questinfo_clear_post > 0) {
+ void (*postHookFunc) (struct npc_data *nd);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_npc_questinfo_clear_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_npc_questinfo_clear_post[hIndex].func;
+ postHookFunc(nd);
+ }
+ }
+ return;
+}
int HP_npc_secure_timeout_timer(int tid, int64 tick, int id, intptr_t data) {
int hIndex = 0;
int retVal___ = 0;
@@ -68395,32 +68500,6 @@ bool HP_quest_questinfo_validate_mercenary_class(struct map_session_data *sd, st
}
return retVal___;
}
-void HP_quest_questinfo_vector_clear(int m) {
- int hIndex = 0;
- if (HPMHooks.count.HP_quest_questinfo_vector_clear_pre > 0) {
- void (*preHookFunc) (int *m);
- *HPMforce_return = false;
- for (hIndex = 0; hIndex < HPMHooks.count.HP_quest_questinfo_vector_clear_pre; hIndex++) {
- preHookFunc = HPMHooks.list.HP_quest_questinfo_vector_clear_pre[hIndex].func;
- preHookFunc(&m);
- }
- if (*HPMforce_return) {
- *HPMforce_return = false;
- return;
- }
- }
- {
- HPMHooks.source.quest.questinfo_vector_clear(m);
- }
- if (HPMHooks.count.HP_quest_questinfo_vector_clear_post > 0) {
- void (*postHookFunc) (int m);
- for (hIndex = 0; hIndex < HPMHooks.count.HP_quest_questinfo_vector_clear_post; hIndex++) {
- postHookFunc = HPMHooks.list.HP_quest_questinfo_vector_clear_post[hIndex].func;
- postHookFunc(m);
- }
- }
- return;
-}
/* refine_interface */
int HP_refine_init(bool minimal) {
int hIndex = 0;
diff --git a/tools/install_mariadb.bat b/tools/install_mariadb.bat
new file mode 100644
index 000000000..cfe2ce3b7
--- /dev/null
+++ b/tools/install_mariadb.bat
@@ -0,0 +1,7 @@
+@echo off
+
+:: this file installs the mariadb service
+
+if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
+mysqld.exe --install "MySQL"
+net start MySQL
diff --git a/tools/setup_mariadb.ps1 b/tools/setup_mariadb.ps1
new file mode 100644
index 000000000..709a5cf93
--- /dev/null
+++ b/tools/setup_mariadb.ps1
@@ -0,0 +1,90 @@
+#Requires -Version 5.1
+
+function Ask-Continue { Write-Output ""; pause; Write-Output "" }
+
+Write-Output "This script will automatically install MariaDB and configure it for you."
+Write-Output "You may interrupt the installation by pressing CTRL+C or closing this window."
+Ask-Continue
+
+if (-Not (Select-String -Quiet -SimpleMatch -Pattern "db_password: ""ragnarok""" -LiteralPath "$PSScriptRoot\..\conf\global\sql_connection.conf")) {
+ Write-Output "WARNING: It seems you already configured the sql connection for your server."
+ Write-Output "If you decide to continue, your settings will be overwritten."
+ Ask-Continue
+}
+
+# step 1: install scoop
+if (-Not (Get-Command scoop -errorAction SilentlyContinue)) {
+ Set-ExecutionPolicy RemoteSigned -scope Process -Force # <= this will trigger a yes/no prompt if not already authorized
+ Invoke-Expression (new-object net.webclient).downloadstring('https://get.scoop.sh')
+ scoop update
+}
+
+# step 2: install mariadb
+if (Test-Path $env:USERPROFILE\scoop\apps\mariadb) {
+ # usually we'd want to capture the output of "scoop list mariadb", but it uses
+ # Write-Host, so we can't, hence why we check manually for the folder
+ Write-Output "WARNING: MariaDB is already installed!"
+ Write-Output "If you decide to continue, your hercules user password will be overwritten."
+ Ask-Continue
+} elseif (Get-Command mysqld -errorAction SilentlyContinue) {
+ Write-Output "ERROR: You already have a MySQL provider installed. To avoid conflict, MariaDB will not be installed."
+ Write-Output "If you wish to continue you will have to uninstall your current MySQL provider."
+ exit 1
+} else {
+ scoop install mariadb
+}
+
+# step 3: add the herc user, set up the new database
+$userpw = -join ((48..57) + (97..122) | Get-Random -Count 32 | % {[char]$_})
+$rootpw = -join ((48..57) + (97..122) | Get-Random -Count 32 | % {[char]$_})
+$maria_job = Start-Process -NoNewWindow -FilePath "mysqld.exe" -ArgumentList "--console" -PassThru -RedirectStandardError "$PSScriptRoot\maria.out"
+
+while (-Not $maria_job.HasExited) {
+ if ($lt -Lt 1 -And (Select-String -Quiet -SimpleMatch -Pattern "ready for connections" -LiteralPath "$PSScriptRoot\maria.out")) {
+@"
+CREATE DATABASE IF NOT EXISTS hercules;
+DROP USER IF EXISTS 'hercules'@'localhost';
+DROP USER IF EXISTS 'hercules'@'127.0.0.1';
+CREATE USER 'hercules'@'localhost' IDENTIFIED BY '$userpw';
+CREATE USER 'hercules'@'127.0.0.1' IDENTIFIED BY '$userpw';
+-- ALTER USER 'root'@'localhost' IDENTIFIED BY '$rootpw';
+GRANT ALTER,CREATE,SELECT,INSERT,UPDATE,DELETE,DROP,INDEX ON `hercules`.* TO 'hercules'@'localhost';
+GRANT ALTER,CREATE,SELECT,INSERT,UPDATE,DELETE,DROP,INDEX ON `hercules`.* TO 'hercules'@'127.0.0.1';
+FLUSH PRIVILEGES;
+USE `hercules`;
+\. $PSScriptRoot\..\sql-files\main.sql
+\. $PSScriptRoot\..\sql-files\logs.sql
+shutdown;
+\q
+"@ | mysql.exe -u root
+ $lt++
+ }
+ Start-Sleep 1
+}
+
+if ($lt -Lt 1) {
+ Write-Output "ERROR: MariaDB could not execute the query."
+ Write-Output "This might happen if your root user already has a password, or if the MySQL service is currently running."
+ $maria_job.close()
+ exit 1
+}
+
+# step 4: finish up
+@"
+sql_connection: {
+ db_username: "hercules"
+ db_password: "$userpw"
+ db_database: "hercules"
+}
+"@ | Out-File -Encoding UTF8 -LiteralPath "$PSScriptRoot\..\conf\global\sql_connection.conf"
+Remove-Item -Force -errorAction SilentlyContinue "$PSScriptRoot\maria.out"
+& "$PSScriptRoot\install_mariadb.bat" # <= we need admin permissions, so we use an external script
+Write-Output "========= ALL DONE ========="
+Write-Output ""
+Write-Output "Your hercules installation is now configured to use MariaDB."
+Write-Output "You can find the password in conf\global\sql_connection.conf."
+Write-Output ""
+Write-Output "If you want to start MariaDB on boot, use services.msc and set ""MySQL"" to Automatic."
+Write-Output ""
+Write-Output "Make sure you set a password for the root user. You can do this from the command line or from HeidiSQL."
+Write-Output "You can obtain HeidiSQL at https://www.microsoft.com/store/productId/9NXPRT2T0ZJF"