summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.github/workflows/build.yml73
-rw-r--r--.github/workflows/clang10_test.yml78
-rw-r--r--.github/workflows/gcc10_test.yml77
-rw-r--r--.github/workflows/gcc9_test.yml77
-rw-r--r--.github/workflows/mariadb.yml80
-rw-r--r--.github/workflows/mysql.yml75
-rw-r--r--.travis.yml92
-rw-r--r--AUTHORS1
-rw-r--r--CHANGELOG.md68
-rw-r--r--conf/map/battle/client.conf36
-rw-r--r--conf/map/battle/guild.conf12
-rw-r--r--conf/map/battle/party.conf27
-rw-r--r--conf/map/battle/pet.conf7
-rw-r--r--conf/map/battle/player.conf7
-rw-r--r--conf/map/battle/skill.conf5
-rw-r--r--conf/messages.conf8
-rwxr-xr-xconfigure31
-rw-r--r--configure.ac2
-rw-r--r--db/constants.conf1
-rw-r--r--db/map_index.txt6
-rw-r--r--db/pre-re/attr_fix.txt4
-rw-r--r--db/pre-re/item_db.conf5
-rw-r--r--db/pre-re/mob_db.conf46
-rw-r--r--db/pre-re/skill_db.conf2
-rw-r--r--db/re/attr_fix.txt4
-rw-r--r--db/re/skill_db.conf2
-rw-r--r--doc/constants.md7
-rw-r--r--doc/script_commands.txt71
-rw-r--r--npc/custom/battleground/bg_common.txt140
-rw-r--r--npc/custom/battleground/bg_kvm01.txt52
-rw-r--r--npc/custom/battleground/bg_kvm02.txt52
-rw-r--r--npc/custom/battleground/bg_kvm03.txt52
-rw-r--r--npc/jobs/2-1/wizard.txt17
-rw-r--r--npc/mapflag/night.txt4
-rw-r--r--npc/mapflag/nobranch.txt4
-rw-r--r--npc/mapflag/nomemo.txt4
-rw-r--r--npc/mapflag/nopet.txt78
-rw-r--r--npc/mapflag/noteleport.txt4
-rw-r--r--npc/quests/quests_amatsu.txt33
-rw-r--r--npc/quests/quests_juperos.txt22
-rw-r--r--npc/quests/quests_lighthalzen.txt12
-rw-r--r--npc/quests/quests_moscovia.txt7
-rw-r--r--npc/quests/seals/god_weapon_creation.txt40
-rw-r--r--npc/quests/the_sign_quest.txt18
-rw-r--r--npc/re/merchants/hd_refiner.txt36
-rw-r--r--npc/scripts.conf3
-rw-r--r--npc/scripts_dev.conf2
-rw-r--r--npc/scripts_mapflags.conf1
-rw-r--r--sql-files/item_db.sql9
-rw-r--r--sql-files/item_db_re.sql48
-rw-r--r--sql-files/mob_db.sql1
-rw-r--r--src/char/char.c139
-rw-r--r--src/char/int_party.c3
-rw-r--r--src/common/atomic.h3
-rw-r--r--src/common/cbasetypes.h10
-rw-r--r--src/common/hercules.h12
-rw-r--r--src/common/packets/packets2020_len_main.h30
-rw-r--r--src/common/packets/packets2020_len_re.h63
-rw-r--r--src/common/packets/packets2020_len_zero.h30
-rw-r--r--src/login/login.c2
-rw-r--r--src/map/atcommand.c132
-rw-r--r--src/map/battle.c15
-rw-r--r--src/map/battle.h9
-rw-r--r--src/map/buyingstore.c13
-rw-r--r--src/map/clif.c642
-rw-r--r--src/map/clif.h9
-rw-r--r--src/map/guild.c13
-rw-r--r--src/map/instance.c4
-rw-r--r--src/map/itemdb.h1
-rw-r--r--src/map/mail.c4
-rw-r--r--src/map/map.c24
-rw-r--r--src/map/map.h1
-rw-r--r--src/map/messages_main.h22
-rw-r--r--src/map/messages_re.h44
-rw-r--r--src/map/messages_zero.h22
-rw-r--r--src/map/npc.c153
-rw-r--r--src/map/packets_keys_main.h9
-rw-r--r--src/map/packets_keys_zero.h7
-rw-r--r--src/map/packets_shuffle_main.h7
-rw-r--r--src/map/packets_shuffle_re.h5
-rw-r--r--src/map/packets_shuffle_zero.h7
-rw-r--r--src/map/packets_struct.h18
-rw-r--r--src/map/party.c39
-rw-r--r--src/map/party.h2
-rw-r--r--src/map/pc.c30
-rw-r--r--src/map/pc.h12
-rw-r--r--src/map/pet.c131
-rw-r--r--src/map/pet.h2
-rw-r--r--src/map/rodex.c3
-rw-r--r--src/map/script.c17
-rw-r--r--src/map/script.h5
-rw-r--r--src/map/skill.c107
-rw-r--r--src/map/skill.h1
-rw-r--r--src/map/trade.c9
-rw-r--r--src/map/vending.c6
-rw-r--r--src/plugins/HPMHooking/HPMHooking.Defs.inc8
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc16
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc4
-rw-r--r--src/plugins/HPMHooking/HPMHooking_map.Hooks.inc107
-rw-r--r--src/plugins/Makefile.in2
-rw-r--r--src/plugins/mapcache.c1
-rwxr-xr-xtools/ci/travis.sh67
-rwxr-xr-xtools/ci/uncomment.sh4
-rwxr-xr-xtools/validateinterfaces.py35
104 files changed, 2628 insertions, 976 deletions
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
new file mode 100644
index 000000000..f136e1bdb
--- /dev/null
+++ b/.github/workflows/build.yml
@@ -0,0 +1,73 @@
+name: build
+
+on: [push, pull_request]
+
+env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ DEBIAN_COMMON_PACKAGES: make zlib1g-dev libpcre3-dev git python
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ # gcc, clang-8, clang-9 removed for reduce number of jobs
+ CC: ["gcc-10", "clang-10"]
+ RENEWAL: [""]
+ CLIENT_TYPE: ["", "--enable-packetver-re", "--enable-packetver-zero"]
+ SANITIZER: [""]
+ PACKET_VERSION: ["--enable-packetver=20100105", "--enable-packetver=20171018"]
+ LTO: ["", "--enable-lto"]
+ exclude:
+ - PACKET_VERSION: "--enable-packetver=20100105"
+ CLIENT_TYPE: "--enable-packetver-zero"
+ - CC: "clang-10"
+ LTO: "--enable-lto"
+ container:
+ image: debian:unstable
+ services:
+ mariadb:
+ image: mariadb:latest
+ ports:
+ - 33306:3306
+ env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+ env:
+ INSTALL_PACKAGES: ${{ matrix.CC }} mariadb-client libmariadbclient-dev-compat
+ SQLHOST: mariadb
+ CC: ${{ matrix.CC }}
+ CONFIGURE_FLAGS: CC=${{ matrix.CC }} --enable-debug --enable-Werror --enable-buildbot ${{ matrix.RENEWAL }} ${{ matrix.CLIENT_TYPE }} ${{ matrix.SANITIZER }} ${{ matrix.PACKET_VERSION }} --enable-epoll
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: info
+ run: |
+ uname -a
+
+ - name: install packages
+ run: |
+ ./tools/ci/retry.sh apt-get update
+ ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES
+
+ - name: init database
+ run: |
+ ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: get plugins
+ run: |
+ ./tools/ci/travis.sh getplugins || true
+
+ - name: build
+ run: |
+ ./tools/ci/travis.sh build $CONFIGURE_FLAGS
+
+ # for run default config will show warnings
diff --git a/.github/workflows/clang10_test.yml b/.github/workflows/clang10_test.yml
new file mode 100644
index 000000000..5fd53c371
--- /dev/null
+++ b/.github/workflows/clang10_test.yml
@@ -0,0 +1,78 @@
+name: clang10_test
+
+on: [push, pull_request]
+
+env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ DEBIAN_COMMON_PACKAGES: make zlib1g-dev libpcre3-dev git python
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ # clang-8, clang-9 removed for reduce number of jobs
+ CC: [clang-10]
+ RENEWAL: ["", "--disable-renewal"]
+ CLIENT_TYPE: ["", "--enable-packetver-re", "--enable-packetver-zero"]
+ SANITIZER: ["--disable-manager", "--disable-manager --enable-sanitize=full"]
+ PACKET_VERSION: ["--enable-packetver=20200304", "--enable-packetver=20130724"]
+ exclude:
+ - PACKET_VERSION: "--enable-packetver=20130724"
+ CLIENT_TYPE: "--enable-packetver-zero"
+ container:
+ image: debian:unstable
+ services:
+ mariadb:
+ image: mariadb:latest
+ ports:
+ - 33306:3306
+ env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+ env:
+ INSTALL_PACKAGES: ${{ matrix.CC }} mariadb-client libmariadbclient-dev-compat
+ SQLHOST: mariadb
+ CC: ${{ matrix.CC }}
+ CONFIGURE_FLAGS: CC=${{ matrix.CC }} --enable-debug --enable-Werror --enable-buildbot ${{ matrix.RENEWAL }} ${{ matrix.CLIENT_TYPE }} ${{ matrix.SANITIZER }} ${{ matrix.PACKET_VERSION }}
+ PACKET_VERSION: ${{ matrix.PACKET_VERSION }}
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: info
+ run: |
+ uname -a
+
+ - name: install packages
+ run: |
+ ./tools/ci/retry.sh apt-get update
+ ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES
+
+ - name: init database
+ run: |
+ ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: get plugins
+ run: |
+ ./tools/ci/travis.sh getplugins || true
+
+ - name: build
+ run: |
+ ./tools/ci/travis.sh build $CONFIGURE_FLAGS
+
+ - name: test
+ run: |
+ ./tools/ci/travis.sh test ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: extra test
+ if: env.PACKET_VERSION != '--enable-packetver=20130724'
+ run: |
+ ./tools/ci/travis.sh extratest
diff --git a/.github/workflows/gcc10_test.yml b/.github/workflows/gcc10_test.yml
new file mode 100644
index 000000000..2225fbba1
--- /dev/null
+++ b/.github/workflows/gcc10_test.yml
@@ -0,0 +1,77 @@
+name: gcc10_test
+
+on: [push, pull_request]
+
+env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ DEBIAN_COMMON_PACKAGES: make zlib1g-dev libpcre3-dev git python
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ CC: [gcc-10]
+ RENEWAL: ["", "--disable-renewal"]
+ CLIENT_TYPE: ["", "--enable-packetver-re", "--enable-packetver-zero"]
+ SANITIZER: ["--disable-manager", "--disable-manager --enable-sanitize=full"]
+ PACKET_VERSION: ["--enable-packetver=20200304", "--enable-packetver=20130724"]
+ exclude:
+ - PACKET_VERSION: "--enable-packetver=20130724"
+ CLIENT_TYPE: "--enable-packetver-zero"
+ container:
+ image: debian:unstable
+ services:
+ mariadb:
+ image: mariadb:latest
+ ports:
+ - 33306:3306
+ env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+ env:
+ INSTALL_PACKAGES: ${{ matrix.CC }} mariadb-client libmariadbclient-dev-compat
+ SQLHOST: mariadb
+ CC: ${{ matrix.CC }}
+ CONFIGURE_FLAGS: CC=${{ matrix.CC }} --enable-debug --enable-Werror --enable-buildbot ${{ matrix.RENEWAL }} ${{ matrix.CLIENT_TYPE }} ${{ matrix.SANITIZER }} ${{ matrix.PACKET_VERSION }} --enable-lto
+ PACKET_VERSION: ${{ matrix.PACKET_VERSION }}
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: info
+ run: |
+ uname -a
+
+ - name: install packages
+ run: |
+ ./tools/ci/retry.sh apt-get update
+ ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES
+
+ - name: init database
+ run: |
+ ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: get plugins
+ run: |
+ ./tools/ci/travis.sh getplugins || true
+
+ - name: build
+ run: |
+ ./tools/ci/travis.sh build $CONFIGURE_FLAGS
+
+ - name: test
+ run: |
+ ./tools/ci/travis.sh test ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: extra test
+ if: env.PACKET_VERSION != '--enable-packetver=20130724'
+ run: |
+ ./tools/ci/travis.sh extratest
diff --git a/.github/workflows/gcc9_test.yml b/.github/workflows/gcc9_test.yml
new file mode 100644
index 000000000..798b6c476
--- /dev/null
+++ b/.github/workflows/gcc9_test.yml
@@ -0,0 +1,77 @@
+name: gcc9_test
+
+on: [push, pull_request]
+
+env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ DEBIAN_COMMON_PACKAGES: make zlib1g-dev libpcre3-dev git python
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ CC: [gcc]
+ RENEWAL: ["", "--disable-renewal"]
+ CLIENT_TYPE: ["", "--enable-packetver-re", "--enable-packetver-zero"]
+ SANITIZER: ["--disable-manager", "--disable-manager --enable-sanitize=full"]
+ PACKET_VERSION: ["--enable-packetver=20200304", "--enable-packetver=20130724"]
+ exclude:
+ - PACKET_VERSION: "--enable-packetver=20130724"
+ CLIENT_TYPE: "--enable-packetver-zero"
+ container:
+ image: debian:unstable
+ services:
+ mariadb:
+ image: mariadb:latest
+ ports:
+ - 33306:3306
+ env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+ env:
+ INSTALL_PACKAGES: ${{ matrix.CC }} mariadb-client libmariadbclient-dev-compat
+ SQLHOST: mariadb
+ CC: ${{ matrix.CC }}
+ CONFIGURE_FLAGS: CC=${{ matrix.CC }} --enable-debug --enable-Werror --enable-buildbot ${{ matrix.RENEWAL }} ${{ matrix.CLIENT_TYPE }} ${{ matrix.SANITIZER }} ${{ matrix.PACKET_VERSION }} --enable-lto
+ PACKET_VERSION: ${{ matrix.PACKET_VERSION }}
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: info
+ run: |
+ uname -a
+
+ - name: install packages
+ run: |
+ ./tools/ci/retry.sh apt-get update
+ ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES
+
+ - name: init database
+ run: |
+ ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: get plugins
+ run: |
+ ./tools/ci/travis.sh getplugins || true
+
+ - name: build
+ run: |
+ ./tools/ci/travis.sh build $CONFIGURE_FLAGS
+
+ - name: test
+ run: |
+ ./tools/ci/travis.sh test ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: extra test
+ if: env.PACKET_VERSION != '--enable-packetver=20130724'
+ run: |
+ ./tools/ci/travis.sh extratest
diff --git a/.github/workflows/mariadb.yml b/.github/workflows/mariadb.yml
new file mode 100644
index 000000000..5293dd98b
--- /dev/null
+++ b/.github/workflows/mariadb.yml
@@ -0,0 +1,80 @@
+name: mariadb
+
+on: [push, pull_request]
+
+env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ DEBIAN_COMMON_PACKAGES: make zlib1g-dev libpcre3-dev git python
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ CC: [gcc]
+ RENEWAL: [""]
+ CLIENT_TYPE: [""]
+ SANITIZER: ["--disable-manager", "--enable-sanitize=full"]
+ PACKET_VERSION: ["--enable-packetver=20200304"]
+ MYSQL: ["10.1", "10.5", "latest"]
+ container:
+ image: debian:unstable
+ services:
+ mysql:
+ image: mariadb:${{ matrix.MYSQL }}
+ ports:
+ - 33306:3306
+ env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+ env:
+ INSTALL_PACKAGES: ${{ matrix.CC }} mariadb-client libmariadbclient-dev-compat
+ SQLHOST: mysql
+ CC: ${{ matrix.CC }}
+ CONFIGURE_FLAGS: CC=${{ matrix.CC }} --enable-debug --enable-Werror --enable-buildbot ${{ matrix.RENEWAL }} ${{ matrix.CLIENT_TYPE }} ${{ matrix.SANITIZER }} ${{ matrix.PACKET_VERSION }}
+ PACKET_VERSION: ${{ matrix.PACKET_VERSION }}
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: info
+ run: |
+ uname -a
+
+ - name: install packages
+ run: |
+ ./tools/ci/retry.sh apt-get update
+ ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES
+
+ - name: init database
+ run: |
+ ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: get plugins
+ run: |
+ ./tools/ci/travis.sh getplugins || true
+
+ - name: build
+ run: |
+ ./tools/ci/travis.sh build $CONFIGURE_FLAGS
+
+ - name: test
+ run: |
+ ./tools/ci/travis.sh test ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: extra test
+ if: env.PACKET_VERSION != '--enable-packetver=20130724'
+ run: |
+ ./tools/ci/travis.sh extratest
+
+ - name: extra test
+ if: env.PACKET_VERSION != '--enable-packetver=20130724'
+ run: |
+ ./tools/ci/travis.sh extratest
diff --git a/.github/workflows/mysql.yml b/.github/workflows/mysql.yml
new file mode 100644
index 000000000..f26f86892
--- /dev/null
+++ b/.github/workflows/mysql.yml
@@ -0,0 +1,75 @@
+name: mysql
+
+on: [push, pull_request]
+
+env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ DEBIAN_COMMON_PACKAGES: make zlib1g-dev libpcre3-dev git python
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ CC: [gcc]
+ RENEWAL: [""]
+ CLIENT_TYPE: [""]
+ SANITIZER: ["--disable-manager", "--enable-sanitize=full"]
+ PACKET_VERSION: ["--enable-packetver=20200304"]
+ MYSQL: ["5.6", "5.7"]
+ container:
+ image: debian:unstable
+ services:
+ mysql:
+ image: mysql:${{ matrix.MYSQL }}
+ ports:
+ - 33306:3306
+ env:
+ MYSQL_DATABASE: 'ragnarok'
+ MYSQL_USER: 'ragnarok'
+ MYSQL_PASSWORD: 'ragnarok'
+ MYSQL_ALLOW_EMPTY_PASSWORD: 'yes'
+ options: --health-cmd="mysqladmin ping" --health-interval=5s --health-timeout=2s --health-retries=3
+ env:
+ INSTALL_PACKAGES: ${{ matrix.CC }} mysql-client libmysqlclient-dev
+ SQLHOST: mysql
+ CC: ${{ matrix.CC }}
+ CONFIGURE_FLAGS: CC=${{ matrix.CC }} --enable-debug --enable-Werror --enable-buildbot ${{ matrix.RENEWAL }} ${{ matrix.CLIENT_TYPE }} ${{ matrix.SANITIZER }} ${{ matrix.PACKET_VERSION }}
+ PACKET_VERSION: ${{ matrix.PACKET_VERSION }}
+ steps:
+ - uses: actions/checkout@v1
+ with:
+ fetch-depth: 1
+
+ - name: info
+ run: |
+ uname -a
+
+ - name: install packages
+ run: |
+ ./tools/ci/retry.sh apt-get update
+ ./tools/ci/retry.sh apt-get install -y -qq $INSTALL_PACKAGES $DEBIAN_COMMON_PACKAGES
+
+ - name: init database
+ run: |
+ ./tools/ci/travis.sh importdb ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: get plugins
+ run: |
+ ./tools/ci/travis.sh getplugins || true
+
+ - name: build
+ run: |
+ ./tools/ci/travis.sh build $CONFIGURE_FLAGS
+
+ - name: test
+ run: |
+ ./tools/ci/travis.sh test ragnarok ragnarok ragnarok $SQLHOST
+
+ - name: extra test
+ if: env.PACKET_VERSION != '--enable-packetver=20130724'
+ run: |
+ ./tools/ci/travis.sh extratest
diff --git a/.travis.yml b/.travis.yml
index 263f66776..77875e490 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -9,12 +9,17 @@ addons:
install:
- ./tools/ci/travis.sh getplugins || true
+arch:
+ - amd64
+
before_script:
- uname -a
+ - env
- ulimit -c unlimited -S
- - ./tools/ci/travis.sh createdb ragnarok root
- - ./tools/ci/travis.sh importdb ragnarok root
- - ./tools/ci/travis.sh adduser ragnarok travis travis root
+ - if [[ "$(uname -m)" != "x86_64" ]]; then $SUDO ./tools/ci/travis.sh startmysql; fi
+ - $SUDO ./tools/ci/travis.sh createdb ragnarok root
+ - $SUDO ./tools/ci/travis.sh importdb ragnarok root
+ - $SUDO ./tools/ci/travis.sh adduser ragnarok travis travis root
script:
- if [[ ! -z "${HPM}" ]]; then ./tools/ci/travis.sh buildhpm $CONFIGURE_FLAGS; fi
@@ -24,6 +29,9 @@ script:
compiler: false # Necessary at the top level because referenced by allow_failures
env: ignore=this # Necessary at the top level because referenced by allow_failures
+git:
+ depth: 1
+
jobs:
allow_failures:
- compiler: clang
@@ -90,33 +98,11 @@ jobs:
- gdb
- clang-4.0
- compiler: clang
- env: CONFIGURE_FLAGS="--enable-debug CC=clang-4.0 --enable-Werror --enable-packetver=20130724 --enable-packetver-re --enable-buildbot"
- addons:
- apt:
- sources:
- - llvm-toolchain-trusty-4.0
- - ubuntu-toolchain-r-test
- packages:
- - gdb
- - clang-4.0
- - compiler: clang
- env: CONFIGURE_FLAGS="--enable-debug CC=clang-4.0 --disable-renewal --enable-Werror --enable-buildbot"
- addons:
- apt:
- sources:
- - llvm-toolchain-trusty-4.0
- - ubuntu-toolchain-r-test
- packages:
- - gdb
- - clang-4.0
- - compiler: clang
env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-buildbot"
- compiler: clang
env: CONFIGURE_FLAGS="--enable-debug --disable-renewal --enable-Werror --enable-buildbot"
- compiler: gcc
- env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot"
- - compiler: gcc
- env: CONFIGURE_FLAGS="--enable-debug --disable-renewal --enable-Werror --enable-buildbot"
+ env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20200304 --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=20200304 --enable-packetver-re --enable-buildbot"
addons:
@@ -127,68 +113,82 @@ jobs:
- gdb
- gcc-5
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-5 --disable-manager --disable-renewal --enable-Werror --enable-buildbot"
+ env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gdb
- - gcc-5
+ - gcc-6
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot"
+ env: CONFIGURE_FLAGS="--enable-debug --disable-manager --disable-renewal --enable-Werror --enable-buildbot"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gdb
- - gcc-6
+ - gcc-7
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-6 --disable-manager --disable-renewal --enable-Werror --enable-buildbot"
+ env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-8 --disable-manager --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gdb
- - gcc-6
+ - gcc-8
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug CC=gcc-7 --disable-manager --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot"
+ env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-8 --disable-manager --disable-renewal --enable-Werror --enable-buildbot"
addons:
apt:
sources:
- ubuntu-toolchain-r-test
packages:
- gdb
- - gcc-7
+ - gcc-8
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-7 --disable-manager --disable-renewal --enable-Werror --enable-buildbot"
+ arch: arm64
+ env: CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-10 --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot --disable-manager" SUDO="sudo"
+ dist: focal
addons:
apt:
- sources:
- - ubuntu-toolchain-r-test
packages:
+ - libpcre3-dev
- gdb
- - gcc-7
+ - mysql-server
+ - gcc-10
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-8 --disable-manager --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot"
+ arch: arm64
+ env: CONFIGURE_FLAGS="--enable-debug --enable-Werror CC=gcc-10 --enable-packetver=20200304 --enable-packetver-re --enable-buildbot --disable-manager" SUDO="sudo"
+ dist: focal
addons:
apt:
- sources:
- - ubuntu-toolchain-r-test
packages:
+ - libpcre3-dev
- gdb
- - gcc-8
+ - mysql-server
+ - gcc-10
- compiler: gcc
- env: LDFLAGS="-fuse-ld=gold" CONFIGURE_FLAGS="--enable-debug --enable-sanitize=full CC=gcc-8 --disable-manager --disable-renewal --enable-Werror --enable-buildbot"
+ arch: ppc64le
+ env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot --disable-manager" SUDO="sudo"
+ dist: bionic
addons:
apt:
- sources:
- - ubuntu-toolchain-r-test
packages:
+ - libpcre3-dev
- gdb
- - gcc-8
+ - mysql-server
+# big endian not supported
+# - compiler: gcc
+# arch: s390x
+# env: CONFIGURE_FLAGS="--enable-debug --enable-Werror --enable-packetver=20200304 --enable-packetver-re --enable-buildbot" ROOT="true"
+# addons:
+# apt:
+# packages:
+# - libpcre3-dev
+# - gdb
notifications:
email: false
diff --git a/AUTHORS b/AUTHORS
index 25a8c89d4..ce72fc223 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -92,6 +92,7 @@ jaBote <j@bot.e>
Jackson <chadfield.jackson@gmail.com>
Jedzkie <jedzkie13@rocketmail.com>
Jenkijo <jenkijo@hrzn.community>
+Jesusaves <jesusalva@themanaworld.org>
jmanfffreak <jmish1987@gmail.com>
Jônatas Andreta <jonataandretta@hotmail.com>
Jorge C <ctt@csnv.es>
diff --git a/CHANGELOG.md b/CHANGELOG.md
index a8c8283af..cc07ad060 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -10,6 +10,73 @@ 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
-->
+## [v2020.06.28] `June 28 2020`
+
+### Added
+
+- Added support to display a pet's intimacy in the egg's item description window. (#2781)
+- Added a convenience macro `pc_has_pet()` to check whether a character has a pet. (part of #2781)
+- Added convenience macros `pc_istrading_except_npc()` and `pc_cant_act_except_npc_chat()`. (part of #2775)
+- Added support for `PACKET_ZC_PERSONAL_INFOMATION`, to replace the old custom status messages about rates and penalties. (#2757)
+- Added a new configuration flag `display_rate_messages` (`conf/map/battle/client.conf`) to control whether and when to display the rate modifiers to players. (part of #2757)
+- Added a new configuration flag `display_config_messages` (`conf/map/battle/client.conf`) to control whether and when to display the configuration messages to players as well as which messages to display. By default, now the pet autofeed and guild urgent call setting are also displayed, along with the others. (part of #2757)
+- Added a new configuration flag `send_party_options` (`conf/map/battle/client.conf`) to control whether and when to display the party option messages to players, including some cases (on login, when options are changed, when a party member is added or removed) that were previously not available. (part of #2757)
+- Added a new configuration flag `display_overweight_messages` (`conf/map/battle/client.conf`) to control whether and when to display the overweight notification message to players. (part of #2757)
+- Added support to display the Tip of the Day message box on login. A new configuration flag `show_tip_window` (`conf/map/battle/client.conf`) is provided, in order to disable this feature. (part of #2757)
+- Added missing plugins to the makefiles. (part of #2778)
+- Added missing mobs and items in the pre-re database, necessary for loading custom scripts. (part of #2778)
+- Added support for GitHub actions and added builds to test different flags and compilers and different MySQL/MariaDB versions. (part of #2778 and 9b89425550)
+- Added/updated packets, encryption keys and message tables for clients up to 2020-06-03. (#2763)
+
+### Changed
+
+- Updated the documentation of the `instance_create()` to clarify the type of ID required to create each type of instance. Notably, instances of type `IOT_CHAR` require an account ID and not a character ID. (part of #2732, issue #2326)
+- Updated the instancing system so that the instance information window is also displayed on login for instances of type `IOT_CHAR`, `IOT_PARTY`, `IOT_GUILD`, even if the instance state is `INSTANCE_IDLE`. (part of #2732)
+- Changed the chatroom creation and trade checks to allow dead characters to perform them. A new configuration flag `allowed_actions_when_dead` (`conf/map/battle/player.conf`) is now available, to allow neither, either or both. (#2755, issue #2740)
+- Changed the behavior when a pet's intimacy drops to 0 to immediately remove the pet rather than leaving it free to roam on the map. A new configuration flag `pet_remove_immediately` (`conf/map/battle/pet.conf`) has been added, to restore the old behavior. (part of #2781)
+- Centralized some repeated code related to pet spawning and consolidated the sending of the pet's intimacy and hunger information to the client when appropriate. (part of #2781)
+- Extended the `guild_notice_changemap` configuration flag with more fine grained settings on when to display the guild notice. Note: if you are currently overriding this setting, you'll need to update its value with the new meaning. (part of #2757)
+- Enforced the use of signed characters on platforms where `char` is unsigned. (part of #2778)
+- Travis-CI scripts and configuration updates: (part of #2778)
+ - Improved the build speed by reducing the clone depth to 1.
+ - Improved error reporting if an error occurs during tests.
+ - Added configurations targeting the arm64 and ppc64le cpu architectures as well as the gcc-10 compiler.
+ - Reduced the total amount of build configurations to improve the CI build time.
+ - Added execution of the servers with all the plugins enabled in order to detect memory violations and errors.
+ - Fixed some build failures caused by a false positive odr violation.
+ - Added execution of the map server with all the custom scripts uncommented.
+ - Disabled asan in the gcc-7 builds, as it's too slow.
+- Converted `validateinterfaces.py` to Python 3. (part of #2778)
+- Changed the plugin handler to call all plugin events even when the server is running in minimal mode. (part of #2778)
+- Updated the friend list related packets for Zero clients. (part of #2763)
+- Changed the storage (account and guild storage) to automatically close when using the teleport skill. A configuration flag `teleport_close_storage` (`conf/map/battle/skill.conf`) has been added to restore the previous behavior. (#2756, issue #1762)
+
+### Fixed
+
+- Fixed an issue when deleting instances of type `IOT_CHAR`. (part of #2732)
+- Fixed an issue that prevented the removal of offline characters from parties to get correctly saved to the database. (#2762)
+- Fixed the deletion of skill units belonging to an NPC when it gets unloaded. (#2712, issue #768)
+- Fixed the selection of required items for various skills, such as Slim Potion Pitcher, for skill levels greater than 2. Required items are now selected through the `skill->get_item_index()` function. (#2774)
+- Fixed the description of the meaning of rows and columns in the documentation for `db/*/attr_fix.txt`. (#2765)
+- Fixed the behavior of the Megaphone item script to remove the normal script restrictions (walking, attacking, using skills and items, dropping and picking up items, trading, etc) while the message input box is present and not to be cancelled on death. (#2775, issue #2751)
+- Fixed a client freeze when talking with an NPC or using a Megaphone while the Rodex window is open. Rodex and NPC scripts (or megaphones) are now mutually exclusive. (part of #2775)
+- Added a workaround in the CI scripts to support MySQL/MariaDB setups where the normal grant code does not work. (part of #2778)
+- Fixed a memory violation between core and plugins in the HPMDataCheck code. (part of #2778)
+- Fixed warnings in the skill database parser when running in minimal mode. The battle configuration is now read in minimal mode. (part of #2778, issue #2776)
+- Fixed warnings about missing maps that were present in the map index and scripts. (part of #2778)
+- Fixed a duplicated `fclose()` call in the mapcache plugin. (part of #2778)
+- Fixed conflicting NPC names in `re/merchants/hd_refiner.txt` and in various custom scripts. (part of #2778)
+- Fixed builds on ARMv8, some ARMv7 versions and PPC64. (part of #2778)
+- Fixed the field size of `struct script_state::npc_item_flag` to support all the possible values and reduced the maximum value of the `item_enabled_npc` configuration flag to 3. (#2784)
+- Fixed the width of the path affected by Focused Arrow Strike to be 1 cell wide instead of 2 on each side. (part of #2785)
+- Fixed a missing character ID in name requests. (part of #2763)
+- Fixed an issue that caused loss of items when selling items to an NPC fails because of the character zeny cap. (#2782, issue #2780)
+- Fixed the disappearance of status icon timers when the character spawns. (#2786, issue #580)
+
+### Removed
+
+- Removed a duplicated function `time2str` from `bg_common.txt`. (part of #2778)
+
## [v2020.05.31+1] `May 31 2020` `PATCH 1`
### Fixed
@@ -1445,6 +1512,7 @@ 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
+[v2020.06.28]: https://github.com/HerculesWS/Hercules/compare/v2020.05.31+1...v2020.06.28
[v2020.05.31+1]: https://github.com/HerculesWS/Hercules/compare/v2020.05.31...v2020.05.31+1
[v2020.05.31]: https://github.com/HerculesWS/Hercules/compare/v2020.05.03...v2020.05.31
[v2020.05.03]: https://github.com/HerculesWS/Hercules/compare/v2020.04.05+1...v2020.05.03
diff --git a/conf/map/battle/client.conf b/conf/map/battle/client.conf
index 5601dbc9e..d4c0f3e1a 100644
--- a/conf/map/battle/client.conf
+++ b/conf/map/battle/client.conf
@@ -202,3 +202,39 @@ ping_time: 20
// Drop or not connection after client send disconnect request packet
// Official is false
drop_connection_on_quit: false
+
+// When to display the rate modifier messages?
+// 0x0 - Never display rate modifier messages.
+// 0x1 - Display rate modifier messages upon login.
+// 0x2 - Display rate modifier messages upon map change.
+// 0x4 - Display rate modifier messages upon teleporting (regardless of changing maps).
+// Default: 0x1 (Official behavior.)
+display_rate_messages: 0x1
+
+// When to display the configuration messages and which? (Note 3)
+//
+// Flags for when to display the configuration messages:
+// 0x000 - Never display configuration messages.
+// 0x001 - Display configuration messages upon login. (Default. Should always be set.)
+// 0x002 - Display configuration messages upon map change.
+// 0x004 - Display configuration messages upon teleporting (regardless of changing maps).
+//
+// Flags for which configuration messages are displayed:
+// 0x010 - Character's party invitation state. (Default.)
+// 0x020 - Character's view equipment state. (Default.)
+// 0x040 - Character's Urgent Call state. (Default.)
+// 0x080 - Character's pet auto-feed state. (Default.)
+// 0x100 - Character's homunculus auto-feed state. (Default.)
+//
+// Default: 0x1F1 (Official behavior.)
+display_config_messages: 0x1F1
+
+// When to display the overweight messages?
+// 0x0 - Never display overweight messages.
+// 0x1 - Display overweight messages upon login. (Default.)
+// 0x2 - Display overweight messages upon map change. (Default.)
+// Default: 0x3 (Official behavior.)
+display_overweight_messages: 0x3
+
+// Show tip of the day window upon login?
+show_tip_window: true
diff --git a/conf/map/battle/guild.conf b/conf/map/battle/guild.conf
index 781f6555b..204c295c3 100644
--- a/conf/map/battle/guild.conf
+++ b/conf/map/battle/guild.conf
@@ -59,11 +59,13 @@ require_glory_guild: false
// Default is 3
max_guild_alliance: 3
-// When to re-display the guild notice
-// Upon teleporting (regardless of changing maps): 2 (official)
-// Upon changing maps: 1
-// Do not re-display: 0 (disabled)
-guild_notice_changemap: 2
+// When to display the guild notice?
+// 0x0 - Never display guild notice.
+// 0x1 - Display guild notice upon login.
+// 0x2 - Display guild notice upon map change.
+// 0x4 - Display guild notice upon teleporting (regardless of changing maps).
+// Default: 0x7 (Official behavior.)
+guild_notice_changemap: 0x7
// Can guild members invite/expel members inside guild castles in WoE/GvG? (Note 1)
// default: false
diff --git a/conf/map/battle/party.conf b/conf/map/battle/party.conf
index e27a709fd..7713d5376 100644
--- a/conf/map/battle/party.conf
+++ b/conf/map/battle/party.conf
@@ -80,3 +80,30 @@ party_even_share_bonus: 0
// Display party name regardless if player is in a guild.
// Official servers do not display party name unless the user is in a guild. (Note 1)
display_party_name: false
+
+// When and how to send the party options? (Note 3)
+//
+// Flags for when to display the party options:
+// 0x00000 - Never send party options.
+// 0x00001 - Send party options upon login. (Default. Should always be set.)
+// 0x00002 - Send party options upon map change.
+// 0x00004 - Send party options upon teleporting (regardless of changing maps).
+// 0x00008 - Send party options upon successfully changing options manually. (Default. Should always be set.)
+// 0x00010 - Send party options upon unsuccessfully changing options manually. (Tried to enable EXP sharing if not allowed.) (Default.)
+// 0x00020 - Send party options upon changing options automatically. (Default. Should always be set.)
+// 0x00040 - Send party options upon joining party. (Default. Should always be set.)
+// 0x00080 - Send party options upon leaving party. (Default.)
+//
+// Flags for how to send the party options:
+// 0x00100 - Send party options to all party members upon unsuccessfully changing options manually. (Tried to enable EXP sharing if not allowed.) (Default.)
+// 0x00200 - Send all party options upon login.
+// 0x00400 - Send all party options upon map change.
+// 0x00800 - Send all party options upon teleporting (regardless of changing maps).
+// 0x01000 - Send all party options upon successfully changing options manually. (Default.)
+// 0x02000 - Send all party options upon unsuccessfully changing options manually. (Tried to enable EXP sharing if not allowed.) (Default.)
+// 0x04000 - Send all party options upon changing options automatically.
+// 0x08000 - Send all party options upon joining party.
+// 0x10000 - Send all party options upon leaving party.
+//
+// Default: 0x31F9 (Official behavior.)
+send_party_options: 0x31F9
diff --git a/conf/map/battle/pet.conf b/conf/map/battle/pet.conf
index 5797bb2a5..6d013b0ef 100644
--- a/conf/map/battle/pet.conf
+++ b/conf/map/battle/pet.conf
@@ -95,7 +95,6 @@ pet_max_stats: 99
pet_max_atk1: 500
pet_max_atk2: 1000
-// Are pets disabled during Guild Wars?
-// If set to true, pets are automatically returned to egg when entering castles during WoE times
-// and hatching is forbidden within as well.
-pet_disable_in_gvg: false
+// Should the pet immediately be removed when its intimacy drops to 0? (Note 1)
+// If set to false the pet will randomly walk around the map before being removed.
+pet_remove_immediately: true
diff --git a/conf/map/battle/player.conf b/conf/map/battle/player.conf
index c25159717..e30c3c134 100644
--- a/conf/map/battle/player.conf
+++ b/conf/map/battle/player.conf
@@ -226,3 +226,10 @@ shadow_refine_atk: true
// Keep player facing direction after warping?
// Default: false (on official servers players always faces north)
player_warp_keep_direction: false
+
+// Can dead players do actions like trading, open a chat room, etc.?
+// 0x0 - Don't allow trading and open chat rooms.
+// 0x1 - Allow trading when dead.
+// 0x2 - Allow open chat room when dead.
+// default: 0x3 (Official)
+allowed_actions_when_dead: 0x3
diff --git a/conf/map/battle/skill.conf b/conf/map/battle/skill.conf
index fe9ca638a..080ca6517 100644
--- a/conf/map/battle/skill.conf
+++ b/conf/map/battle/skill.conf
@@ -355,3 +355,8 @@ magicrod_type: 0
// Official RE: 0 (Default value.)
// Official Pre-RE: 1
skill_enabled_npc: 0
+
+// Close the storage/gstorage when teleported? (Note 1)
+// true : (Official)
+// false : (Athena)
+teleport_close_storage: true
diff --git a/conf/messages.conf b/conf/messages.conf
index c9ae8cc66..3c381142d 100644
--- a/conf/messages.conf
+++ b/conf/messages.conf
@@ -646,8 +646,10 @@
668: Shadow Chaser T
669: Summoner
-//670-853 FREE (please start using from the top if you need, leave the 670+ range for new jobs)
+//670-852 FREE (please start using from the top if you need, leave the 670+ range for new jobs)
+
+853: NoPet |
// Mapflag to disable Autoloot Commands
854: Auto loot item are disabled on this map.
@@ -667,7 +669,7 @@
863: Duel: Can't use this item in duel.
864: You cannot use this command when dead.
865: Can't create chat rooms in this area.
-866: Pets are not allowed in Guild Wars.
+866: Pets are disabled in this map.
867: You're not dead.
868: Your current memo positions are:
869: You broke the target's weapon.
@@ -694,7 +696,7 @@
886: Gained %dz.
887: %s stole an Unknown Item (id: %i).
888: %s stole %s.
-889: Experience Gained Base:%"PRIu64" (%.2f%%) Job:%"PRIu64" (%.2f%%)
+889: Experience Gained Base:%llu (%.2f%%) Job:%llu (%.2f%%)
890: [KS Warning!! - Owner : %s]
891: [Watch out! %s is trying to KS you!]
892: Growth: hp:%d sp:%d str(%.2f) agi(%.2f) vit(%.2f) int(%.2f) dex(%.2f) luk(%.2f)
diff --git a/configure b/configure
index a8ca071cb..9341c504a 100755
--- a/configure
+++ b/configure
@@ -1,5 +1,5 @@
#! /bin/sh
-# From configure.ac 2b51b41ab.
+# From configure.ac 6d5542195.
# Guess values for system-dependent variables and create Makefiles.
# Generated by GNU Autoconf 2.69.
#
@@ -6460,7 +6460,6 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -fsanitize=pointer-compare" >&5
$as_echo_n "checking whether $CC supports -fsanitize=pointer-compare... " >&6; }
OLD_CFLAGS="$CFLAGS"
@@ -6708,6 +6707,34 @@ fi
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -fsigned-char" >&5
+$as_echo_n "checking whether $CC supports -fsigned-char... " >&6; }
+ OLD_CFLAGS="$CFLAGS"
+ CFLAGS="$CFLAGS -fsigned-char"
+ OLD_LDFLAGS="$LDFLAGS"
+ LDFLAGS="$LDFLAGS -fsigned-char"
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+int foo;
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
+
+else
+
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+ CFLAGS="$OLD_CFLAGS"
+ LDFLAGS="$OLD_LDFLAGS"
+
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+
+
+
+
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC supports -Wno-unused-parameter" >&5
$as_echo_n "checking whether $CC supports -Wno-unused-parameter... " >&6; }
OLD_CFLAGS="$CFLAGS"
diff --git a/configure.ac b/configure.ac
index 1d02fdf79..09a5ad6ad 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1098,6 +1098,8 @@ AC_DEFUN([AC_CHECK_COMPILER_WNOFLAG],
]
)
+AC_CHECK_FLAG(-fsigned-char)
+
AC_CHECK_COMPILER_WNOFLAG(unused-parameter, [int foo(int bar) { return 0; }])
AC_CHECK_COMPILER_WNOFLAG(clobbered)
AC_CHECK_COMPILER_WFLAG(empty-body)
diff --git a/db/constants.conf b/db/constants.conf
index bb50cd308..60528f598 100644
--- a/db/constants.conf
+++ b/db/constants.conf
@@ -438,6 +438,7 @@ constants_db: {
mf_pairship_endable: 58
mf_nostorage: 59
mf_nogstorage: 60
+ mf_nopet: 61
comment__: "Cell Properties"
cell_walkable: 0
diff --git a/db/map_index.txt b/db/map_index.txt
index fbbf4d25a..6e77cb838 100644
--- a/db/map_index.txt
+++ b/db/map_index.txt
@@ -642,9 +642,9 @@ ve_fild04
ve_fild05
ve_fild06
ve_fild07
-poring_c01
-poring_c02
-que_ng
+//poring_c01 628
+//poring_c02 629
+que_ng 630
nameless_i
nameless_n
nameless_in
diff --git a/db/pre-re/attr_fix.txt b/db/pre-re/attr_fix.txt
index 134eec5cd..d1f59068e 100644
--- a/db/pre-re/attr_fix.txt
+++ b/db/pre-re/attr_fix.txt
@@ -1,7 +1,7 @@
// Elemental attribute damage adjustment tables
//
-// Row: target's defense element
-// Column: attacker's weapon element
+// Row: attacker's weapon element
+// Column: target's defense element
1,10 // lv1 Attribute table
//Neut Watr Erth Fire Wind Pois Holy Shdw Gho Und
diff --git a/db/pre-re/item_db.conf b/db/pre-re/item_db.conf
index cc7f5040d..c548209c8 100644
--- a/db/pre-re/item_db.conf
+++ b/db/pre-re/item_db.conf
@@ -98799,6 +98799,11 @@ item_db: (
Name: "Ein_1HMAGGER"
},
{
+ Id: 28900
+ AegisName: "Praetorian_Shield"
+ Name: "Praetorian Shield"
+},
+{
Id: 28922
AegisName: "Herald_Of_GOD_IL"
Name: "Herald_Of_GOD_IL"
diff --git a/db/pre-re/mob_db.conf b/db/pre-re/mob_db.conf
index 92fd149f3..eb0cf663b 100644
--- a/db/pre-re/mob_db.conf
+++ b/db/pre-re/mob_db.conf
@@ -50153,4 +50153,50 @@ mob_db: (
DamageMotion: 480
MvpExp: 0
},
+{
+ Id: 2248
+ SpriteName: "GOLDPORING"
+ Name: "Golden Poring"
+ Lv: 1
+ Hp: 15
+ Sp: 1
+ Exp: 0
+ JExp: 0
+ AttackRange: 0
+ Attack: [0, 0]
+ Def: 127
+ Mdef: 5
+ Stats: {
+ Str: 1
+ Agi: 1
+ Vit: 1
+ Int: 1
+ Dex: 999
+ Luk: 1
+ }
+ ViewRange: 10
+ ChaseRange: 12
+ Size: "Size_Medium"
+ Race: "RC_Plant"
+ Element: ("Ele_Water", 1)
+ Mode: {
+ CanMove: true
+ CanAttack: true
+ }
+ MoveSpeed: 400
+ AttackDelay: 1872
+ AttackMotion: 672
+ DamageMotion: 480
+ MvpExp: 0
+// Drops: {
+// Blue_Card_C: 4000
+// BlueCard_2: 4000
+// BlueCard_0: 4000
+// BlueCard_1: 4000
+// BlueCard_W: 4000
+// BlueCard_R: 4000
+// RWC_Cele_Fire: 10000
+// RWC_Cele_Fire2: 10000
+// }
+},
)
diff --git a/db/pre-re/skill_db.conf b/db/pre-re/skill_db.conf
index 36b877f94..21fb933f4 100644
--- a/db/pre-re/skill_db.conf
+++ b/db/pre-re/skill_db.conf
@@ -11346,7 +11346,7 @@ skill_db: (
}
AttackType: "Weapon"
Element: "Ele_Weapon"
- SplashRange: 2
+ SplashRange: 1
InterruptCast: true
SkillInstances: 13
CastTime: 2000
diff --git a/db/re/attr_fix.txt b/db/re/attr_fix.txt
index 96d6b37d1..79c55aeca 100644
--- a/db/re/attr_fix.txt
+++ b/db/re/attr_fix.txt
@@ -1,7 +1,7 @@
// Elemental attribute damage adjustment tables
//
-// Row: target's defense element
-// Column: attacker's weapon element
+// Row: attacker's weapon element
+// Column: target's defense element
1,10 // lv1 Attribute table
//Neut Watr Erth Fire Wind Pois Holy Shdw Gho Und
diff --git a/db/re/skill_db.conf b/db/re/skill_db.conf
index 467dd0c38..2992aa103 100644
--- a/db/re/skill_db.conf
+++ b/db/re/skill_db.conf
@@ -11664,7 +11664,7 @@ skill_db: (
}
AttackType: "Weapon"
Element: "Ele_Weapon"
- SplashRange: 2
+ SplashRange: 1
InterruptCast: true
SkillInstances: 13
CastTime: 1000
diff --git a/doc/constants.md b/doc/constants.md
index 07a4d8a6d..d1c926c29 100644
--- a/doc/constants.md
+++ b/doc/constants.md
@@ -364,6 +364,7 @@
- `mf_pairship_endable`: 58
- `mf_nostorage`: 59
- `mf_nogstorage`: 60
+- `mf_nopet`: 61
### Cell Properties
@@ -5154,6 +5155,12 @@
- `P_AIRSHIP_ITEM_NOT_ENOUGH`: 2
- `P_AIRSHIP_ITEM_INVALID`: 5
+### player allowed actions when dead
+
+- `PCALLOWACTION_NONE`: 0
+- `PCALLOWACTION_TRADE`: 1
+- `PCALLOWACTION_CHAT`: 2
+
### questinfo types
- `QINFO_JOB`: 0
diff --git a/doc/script_commands.txt b/doc/script_commands.txt
index cc23da4ca..ee56087b2 100644
--- a/doc/script_commands.txt
+++ b/doc/script_commands.txt
@@ -3195,23 +3195,24 @@ This command sets a bunch of arrays with a complete list of whatever the
invoking character has in its inventory, including all the data needed to
recreate these items perfectly if they are destroyed. Here's what you get:
-@inventorylist_id[] - array of item ids.
-@inventorylist_idx[] - array of item inventory index.
-@inventorylist_amount[] - their corresponding item amounts.
-@inventorylist_equip[] - will return the slot the item is equipped on, if at all.
-@inventorylist_refine[] - for how much it is refined.
-@inventorylist_identify[] - whether it is identified.
-@inventorylist_attribute[] - whether it is broken.
-@inventorylist_card1[] - These four arrays contain card data for the
-@inventorylist_card2[] items. These data slots are also used to store
-@inventorylist_card3[] names inscribed on the items, so you can
-@inventorylist_card4[] explicitly check if the character owns an item
- made by a specific craftsman.
-@inventorylist_expire[] - expire time (Unix time stamp). 0 means never
- expires.
-@inventorylist_bound[] - whether it is an account bounded item or not.
-@inventorylist_favorite[] - whether it is favorite (inside favorite tab) or not.
-@inventorylist_count - the number of items in these lists.
+@inventorylist_id[] - array of item ids.
+@inventorylist_idx[] - array of item inventory index.
+@inventorylist_amount[] - their corresponding item amounts.
+@inventorylist_equip[] - will return the slot the item is equipped on, if at all.
+@inventorylist_refine[] - for how much it is refined.
+@inventorylist_identify[] - whether it is identified.
+@inventorylist_attribute[] - whether it is broken.
+@inventorylist_card1[] - These four arrays contain card data for the items.
+@inventorylist_card2[] These data slots are also used to store names inscribed
+@inventorylist_card3[] on the items, so you can explicitly check if the character
+@inventorylist_card4[] owns an item made by a specific craftsman.
+@inventorylist_expire[] - expire time (Unix time stamp). 0 means never expires.
+@inventorylist_bound[] - whether it is an account bounded item or not.
+@inventorylist_favorite[] - whether it is favorite (inside favorite tab) or not.
+@inventorylist_opt_id1~5[] - array of random option id.
+@inventorylist_opt_val1~5[] - array of random option val.
+@inventorylist_opt_param1~5[] - array of random option param.
+@inventorylist_count - the number of items in these lists.
This could be handy to save/restore a character's inventory, since no
other command returns such a complete set of data, and could also be the
@@ -3239,14 +3240,15 @@ recreate these items perfectly if they are destroyed. Here's what you get:
@cartinventorylist_refine[] - for how much it is refined.
@cartinventorylist_identify[] - whether it is identified.
@cartinventorylist_attribute[] - whether it is broken.
-@cartinventorylist_card1[] - These four arrays contain card data for the
-@cartinventorylist_card2[] items. These data slots are also used to store
-@cartinventorylist_card3[] names inscribed on the items, so you can
-@cartinventorylist_card4[] explicitly check if the character owns an item
- made by a specific craftsman.
-@cartinventorylist_expire[] - expire time (Unix time stamp). 0 means never
- expires.
+@cartinventorylist_card1[] - These four arrays contain card data for the items.
+@cartinventorylist_card2[] These data slots are also used to store names inscribed on the items,
+@cartinventorylist_card3[] so you can explicitly check if the character owns an item
+@cartinventorylist_card4[] made by a specific craftsman.
+@cartinventorylist_expire[] - expire time (Unix time stamp). 0 means never expires.
@cartinventorylist_bound - whether it is an account bound item or not.
+@inventorylist_opt_id1~5[] - array of random option id.
+@inventorylist_opt_val1~5[] - array of random option val.
+@inventorylist_opt_param1~5[] - array of random option param.
@cartinventorylist_count - the number of items in these lists.
This could be handy to save/restore a character's cart_inventory, since no
@@ -3626,7 +3628,7 @@ If the player is not found, returns -1.
*gettimetick(<type>)
Valid types are :
- 0 - server's tick (milleseconds), unsigned int, loops every ~50 days
+ 0 - server's tick (milleseconds), unsigned int, loops every ~25 days
1 - time since the start of the current day in seconds
2 - UNIX epoch time (number of seconds elapsed since 1st of January 1970)
@@ -7656,7 +7658,8 @@ In the OnBuyItem, two arrays are filled (@bought_nameid and
and the amount sold of it. Same goes for the OnSellItem label, only the
variables are named different (@sold_nameid, @sold_quantity, @sold_refine,
@sold_attribute, @sold_identify, @sold_card1, @sold_card2, @sold_card3,
-@sold_card4). An example on a shop comes with Hercules, and can be found
+@sold_card4, @sold_opt_id1~5, @sold_opt_val1~5, @sold_opt_param1~5).
+An example on a shop comes with Hercules, and can be found
in the doc/sample/npc_dynamic_shop.txt file.
This example shows how to use the labels and their set variables to create
@@ -9656,13 +9659,19 @@ Check getitem2 command for more information of the extra parameters.
//=====================================
---------------------------------------
-*instance_create("<instance name>", <owner id>{, <optional owner_type>})
+*instance_create("<instance_name>", <owner_id>{, <owner_type>})
-Create an instance using the name "<instance name>" for the <owner_id> of
-owner_type (when not provided, defaults to IOT_PARTY). Most instance_*
+Creates an instance using the name "<instance_name>" for the <owner_id> of
+<owner_type> (when not provided, defaults to IOT_PARTY). Most instance_*
commands are used in conjunction with this command and depend on the
ID this command returns.
+Valid <owner_type> values:
+- IOT_NONE (0) - <owner_id> can be any arbitrary number.
+- IOT_CHAR (1) - <owner_id> is account ID.
+- IOT_PARTY (2) - <owner_id> is party ID.
+- IOT_GUILD (3) - <owner_id> is guild ID.
+
Example:
// Store the Party ID of the invoking character.
.@party_id = getcharid(CHAR_ID_PARTY);
@@ -9673,11 +9682,9 @@ Example:
// ...
} else if (.@id == -2) { // Invalid Party ID
// ...
- } else if (.@id == -3) { // No free instances (MAX_INSTANCE exceeded)
- // ...
} else if (.@id == -4) { // Already exists
// ...
- } else (.@id < 0) { // Unspecified error while queuing instance.
+ } else if (.@id < 0) { // Unspecified error while queuing instance.
// ...
}
diff --git a/npc/custom/battleground/bg_common.txt b/npc/custom/battleground/bg_common.txt
index 7ba3eecb0..d997263e6 100644
--- a/npc/custom/battleground/bg_common.txt
+++ b/npc/custom/battleground/bg_common.txt
@@ -5,7 +5,7 @@
// BattleGround Warper - Entrance
// *********************************************************************
-- script Maroll Battle Recruiter::BatRecruit 4_F_JOB_KNIGHT,{
+- script Maroll Battle Recruiter::BatRecruit#custom 4_F_JOB_KNIGHT,{
mes "[Maroll Battle Recruiter]";
mes "Good day, adventurer.";
mes "I'm a knight from a far country called Maroll Kingdom.";
@@ -26,12 +26,12 @@
end;
}
-payon,189,104,3 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit1 4_F_JOB_KNIGHT
-prontera,123,83,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit2 4_F_JOB_KNIGHT
-rachel,149,138,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit3 4_F_JOB_KNIGHT
-moc_ruins,75,162,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit4 4_F_JOB_KNIGHT
-aldebaran,146,109,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit5 4_F_JOB_KNIGHT
-lighthalzen,153,86,5 duplicate(BatRecruit) Maroll Battle Recruiter::BatRecruit6 4_F_JOB_KNIGHT
+payon,189,104,3 duplicate(BatRecruit#custom) Maroll Battle Recruiter::BatRecruit1#custom 4_F_JOB_KNIGHT
+prontera,123,83,5 duplicate(BatRecruit#custom) Maroll Battle Recruiter::BatRecruit2#custom 4_F_JOB_KNIGHT
+rachel,149,138,5 duplicate(BatRecruit#custom) Maroll Battle Recruiter::BatRecruit3#custom 4_F_JOB_KNIGHT
+moc_ruins,75,162,5 duplicate(BatRecruit#custom) Maroll Battle Recruiter::BatRecruit4#custom 4_F_JOB_KNIGHT
+aldebaran,146,109,5 duplicate(BatRecruit#custom) Maroll Battle Recruiter::BatRecruit5#custom 4_F_JOB_KNIGHT
+lighthalzen,153,86,5 duplicate(BatRecruit#custom) Maroll Battle Recruiter::BatRecruit6#custom 4_F_JOB_KNIGHT
// BattleGround Warper - Exit
// *********************************************************************
@@ -59,14 +59,14 @@ bat_room,148,150,4 script Teleporter#bat 4_F_TELEPORTER,{
// Kafra
// *********************************************************************
-bat_room,148,147,4 script Kafra Staff::kaf_bat 4_F_KAFRA9,{
+bat_room,148,147,4 script Kafra Staff::kaf_bat#custom 4_F_KAFRA9,{
cutin "kafra_09",2;
callfunc "F_Kafra",0,2,1,150,0;
}
// General Guillaume
// *********************************************************************
-bat_room,160,159,3 script General Guillaume 4_M_KY_KIYOM,{
+bat_room,160,159,3 script General Guillaume#custom 4_M_KY_KIYOM,{
cutin "bat_kiyom2",2;
mes "[General Guillaume]";
mes "Hot-blooded adventurer, we need your ability to win this battle.";
@@ -105,7 +105,7 @@ bat_room,160,159,3 script General Guillaume 4_M_KY_KIYOM,{
// General Croix
// *********************************************************************
-bat_room,160,140,3 script Prince Croix 4_M_CRU_CRUA,{
+bat_room,160,140,3 script Prince Croix#custom 4_M_CRU_CRUA,{
cutin "bat_crua1",2;
mes "[Prince Croix]";
mes "Wise adventurer, why don't you lend us your power for victory?";
@@ -133,45 +133,9 @@ bat_room,160,140,3 script Prince Croix 4_M_CRU_CRUA,{
end;
}
-// Time calculation Function
-// *********************************************************************
-function script Time2Str {
- set .@time_left, getarg(0) - gettimetick(2);
-
- set .@Days, .@time_left / 86400;
- set .@time_left, .@time_left - (.@Days * 86400);
- set .@Hours, .@time_left / 3600;
- set .@time_left, .@time_left - (.@Hours * 3600);
- set .@Minutes, .@time_left / 60;
- set .@time_left, .@time_left - (.@Minutes * 60);
-
- set .@Time$, "";
- if( .@Days > 1 )
- set .@Time$, .@Time$ + .@Days + " days, ";
- else if( .@Days > 0 )
- set .@Time$, .@Time$ + .@Days + " day, ";
-
- if( .@Hours > 1 )
- set .@Time$, .@Time$ + .@Hours + " hours, ";
- else if( .@Hours > 0 )
- set .@Time$, .@Time$ + .@Hours + " hour, ";
-
- if( .@Minutes > 1 )
- set .@Time$, .@Time$ + .@Minutes + " minutes, ";
- else if( .@Minutes > 0 )
- set .@Time$, .@Time$ + .@Minutes + " minute, ";
-
- if( .@time_left > 1 || .@time_left == 0 )
- set .@Time$, .@Time$ + .@time_left + " seconds.";
- else if( .@time_left == 1 )
- set .@Time$, .@Time$ + .@time_left + " second.";
-
- return .@Time$;
-}
-
// Guillaume Knight - Tierra Valley
// *********************************************************************
-bat_room,159,178,5 script Guillaume Knight#1 4_M_KY_SOLD,{
+bat_room,159,178,5 script Guillaume Knight#1c 4_M_KY_SOLD,{
mes "[Guillaume Knight]";
mes "Tierra Gorge is a very steep canyon with two forts residing in the north and south ends of the map.";
next;
@@ -241,7 +205,7 @@ bat_room,156,178,5 script Tierra Valley Officer#1 4_M_KY_KNT,{
// Croix Knight - Tierra Valley
// *********************************************************************
-bat_room,159,121,1 script Croix Knight#1 4_M_CRU_SOLD,{
+bat_room,159,121,1 script Croix Knight#1c 4_M_CRU_SOLD,{
mes "[Croix Knight]";
mes "Tierra Gorge is a very steep canyon with two forts residing in the north and south ends of the map.";
next;
@@ -311,7 +275,7 @@ bat_room,156,121,1 script Tierra Valley Officer#2 4_M_CRU_KNT,{
// Guillaume Knight - Tierra
// *********************************************************************
-bat_room,167,178,5 script Guillaume Knight#2 4_M_KY_SOLD,{
+bat_room,167,178,5 script Guillaume Knight#2c 4_M_KY_SOLD,{
mes "[Guillaume Knight]";
mes "Tierra Gorge is a very steep canyon with two forts residing in the north and south ends of the map.";
next;
@@ -381,7 +345,7 @@ bat_room,164,178,5 script Tierra Valley Officer#3 4_M_KY_KNT,{
// Croix Knight - Tierra
// *********************************************************************
-bat_room,167,121,1 script Croix Knight#2 4_M_CRU_SOLD,{
+bat_room,167,121,1 script Croix Knight#2c 4_M_CRU_SOLD,{
mes "[Croix Knight]";
mes "Tierra Gorge is a very steep canyon with two forts residing in the north and south ends of the map.";
next;
@@ -451,7 +415,7 @@ bat_room,164,121,1 script Tierra Valley Officer#4 4_M_CRU_KNT,{
// Guillaune Knight - Flavius
// *********************************************************************
-bat_room,175,178,5 script Guillaume Knight#3 4_M_KY_SOLD,{
+bat_room,175,178,5 script Guillaume Knight#3c 4_M_KY_SOLD,{
mes "[Guillaume Knight]";
mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal.";
next;
@@ -522,7 +486,7 @@ bat_room,172,178,5 script Flavius Officer#1 4_M_KY_KNT,{
// Croix Knight - Flavius
// *********************************************************************
-bat_room,175,121,1 script Croix Knight#3 4_M_CRU_SOLD,{
+bat_room,175,121,1 script Croix Knight#3c 4_M_CRU_SOLD,{
mes "[Croix Knight]";
mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal.";
next;
@@ -593,7 +557,7 @@ bat_room,172,121,1 script Flavius Officer#2 4_M_CRU_KNT,{
// Guillaune Knight - Flavius
// *********************************************************************
-bat_room,151,178,5 script Guillaume Knight#4 4_M_KY_SOLD,{
+bat_room,151,178,5 script Guillaume Knight#4c 4_M_KY_SOLD,{
mes "[Guillaume Knight]";
mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal.";
next;
@@ -664,7 +628,7 @@ bat_room,148,178,5 script Flavius Officer#3 4_M_KY_KNT,{
// Croix Knight - Flavius
// *********************************************************************
-bat_room,151,121,1 script Croix Knight#4 4_M_CRU_SOLD,{
+bat_room,151,121,1 script Croix Knight#4c 4_M_CRU_SOLD,{
mes "[Croix Knight]";
mes "The objective of the Flavius Battle is to score 2 points before your enemy by destroying their crystal.";
next;
@@ -1167,58 +1131,58 @@ OnTouch:
}
// Flavius bat_b02
-bat_room,57,81,0 duplicate(warp2bat_room) bat1 WARPNPC,1,1
-bat_room,57,90,0 duplicate(warp2bat_room) bat2 WARPNPC,1,1
+bat_room,57,81,0 duplicate(warp2bat_room) bat1#custom WARPNPC,1,1
+bat_room,57,90,0 duplicate(warp2bat_room) bat2#custom WARPNPC,1,1
// Free BG
-bat_room,57,220,0 duplicate(warp2bat_room) bat3 WARPNPC,1,1
-bat_room,57,211,0 duplicate(warp2bat_room) bat4 WARPNPC,1,1
+bat_room,57,220,0 duplicate(warp2bat_room) bat3#custom WARPNPC,1,1
+bat_room,57,211,0 duplicate(warp2bat_room) bat4#custom WARPNPC,1,1
// Tierra Valley bat_a02
-bat_room,85,81,0 duplicate(warp2bat_room) bat5 WARPNPC,1,1
-bat_room,85,90,0 duplicate(warp2bat_room) bat6 WARPNPC,1,1
+bat_room,85,81,0 duplicate(warp2bat_room) bat5#custom WARPNPC,1,1
+bat_room,85,90,0 duplicate(warp2bat_room) bat6#custom WARPNPC,1,1
// Tierra Valley bat_a01
-bat_room,85,220,0 duplicate(warp2bat_room) bat7 WARPNPC,1,1
-bat_room,85,211,0 duplicate(warp2bat_room) bat8 WARPNPC,1,1
+bat_room,85,220,0 duplicate(warp2bat_room) bat7#custom WARPNPC,1,1
+bat_room,85,211,0 duplicate(warp2bat_room) bat8#custom WARPNPC,1,1
// Free BG
-bat_room,113,81,0 duplicate(warp2bat_room) bat9 WARPNPC,1,1
-bat_room,113,90,0 duplicate(warp2bat_room) bat10 WARPNPC,1,1
+bat_room,113,81,0 duplicate(warp2bat_room) bat9#custom WARPNPC,1,1
+bat_room,113,90,0 duplicate(warp2bat_room) bat10#custom WARPNPC,1,1
// Free BG
-bat_room,113,220,0 duplicate(warp2bat_room) bat11 WARPNPC,1,1
-bat_room,113,211,0 duplicate(warp2bat_room) bat12 WARPNPC,1,1
+bat_room,113,220,0 duplicate(warp2bat_room) bat11#custom WARPNPC,1,1
+bat_room,113,211,0 duplicate(warp2bat_room) bat12#custom WARPNPC,1,1
// Free BG
-bat_room,141,81,0 duplicate(warp2bat_room) bat13 WARPNPC,1,1
-bat_room,141,90,0 duplicate(warp2bat_room) bat14 WARPNPC,1,1
+bat_room,141,81,0 duplicate(warp2bat_room) bat13#custom WARPNPC,1,1
+bat_room,141,90,0 duplicate(warp2bat_room) bat14#custom WARPNPC,1,1
// Free BG
-bat_room,141,220,0 duplicate(warp2bat_room) bat15 WARPNPC,1,1
-bat_room,141,211,0 duplicate(warp2bat_room) bat16 WARPNPC,1,1
+bat_room,141,220,0 duplicate(warp2bat_room) bat15#custom WARPNPC,1,1
+bat_room,141,211,0 duplicate(warp2bat_room) bat16#custom WARPNPC,1,1
// Free BG
-bat_room,169,81,0 duplicate(warp2bat_room) bat17 WARPNPC,1,1
-bat_room,169,90,0 duplicate(warp2bat_room) bat18 WARPNPC,1,1
+bat_room,169,81,0 duplicate(warp2bat_room) bat17#custom WARPNPC,1,1
+bat_room,169,90,0 duplicate(warp2bat_room) bat18#custom WARPNPC,1,1
// Free BG
-bat_room,169,220,0 duplicate(warp2bat_room) bat19 WARPNPC,1,1
-bat_room,169,211,0 duplicate(warp2bat_room) bat20 WARPNPC,1,1
+bat_room,169,220,0 duplicate(warp2bat_room) bat19#custom WARPNPC,1,1
+bat_room,169,211,0 duplicate(warp2bat_room) bat20#custom WARPNPC,1,1
// Free BG
-bat_room,197,81,0 duplicate(warp2bat_room) bat21 WARPNPC,1,1
-bat_room,197,90,0 duplicate(warp2bat_room) bat22 WARPNPC,1,1
+bat_room,197,81,0 duplicate(warp2bat_room) bat21#custom WARPNPC,1,1
+bat_room,197,90,0 duplicate(warp2bat_room) bat22#custom WARPNPC,1,1
// KvM bat_c03
-bat_room,197,220,0 duplicate(warp2bat_room) bat23 WARPNPC,1,1
-bat_room,197,211,0 duplicate(warp2bat_room) bat24 WARPNPC,1,1
+bat_room,197,220,0 duplicate(warp2bat_room) bat23#custom WARPNPC,1,1
+bat_room,197,211,0 duplicate(warp2bat_room) bat24#custom WARPNPC,1,1
// Free BG
-bat_room,225,81,0 duplicate(warp2bat_room) bat25 WARPNPC,1,1
-bat_room,225,90,0 duplicate(warp2bat_room) bat26 WARPNPC,1,1
+bat_room,225,81,0 duplicate(warp2bat_room) bat25#custom WARPNPC,1,1
+bat_room,225,90,0 duplicate(warp2bat_room) bat26#custom WARPNPC,1,1
// KvM bat_c02
-bat_room,225,220,0 duplicate(warp2bat_room) bat27 WARPNPC,1,1
-bat_room,225,211,0 duplicate(warp2bat_room) bat28 WARPNPC,1,1
+bat_room,225,220,0 duplicate(warp2bat_room) bat27#custom WARPNPC,1,1
+bat_room,225,211,0 duplicate(warp2bat_room) bat28#custom WARPNPC,1,1
// Flavius bat_b01
-bat_room,253,81,0 duplicate(warp2bat_room) bat29 WARPNPC,1,1
-bat_room,253,90,0 duplicate(warp2bat_room) bat30 WARPNPC,1,1
+bat_room,253,81,0 duplicate(warp2bat_room) bat29#custom WARPNPC,1,1
+bat_room,253,90,0 duplicate(warp2bat_room) bat30#custom WARPNPC,1,1
// KvM bat_c01
-bat_room,253,220,0 duplicate(warp2bat_room) bat31 WARPNPC,1,1
-bat_room,253,211,0 duplicate(warp2bat_room) bat32 WARPNPC,1,1
+bat_room,253,220,0 duplicate(warp2bat_room) bat31#custom WARPNPC,1,1
+bat_room,253,211,0 duplicate(warp2bat_room) bat32#custom WARPNPC,1,1
// Badges Repairman
// *********************************************************************
-bat_room,138,144,5 script Repairman#bg 4W_M_03,{
+bat_room,138,144,5 script Repairman#bgc 4W_M_03,{
callfunc "repairmain","Repairman";
end;
}
@@ -1226,7 +1190,7 @@ bat_room,138,144,5 script Repairman#bg 4W_M_03,{
// Badges Exchange
// *********************************************************************
-bat_room,160,150,3 script Erundek 4_M_MANAGER,{
+bat_room,160,150,3 script Erundek#custom 4_M_MANAGER,{
mes "[Erundek]";
mes "Welcome, mighty warrior.";
mes "What can I do for you today ?";
diff --git a/npc/custom/battleground/bg_kvm01.txt b/npc/custom/battleground/bg_kvm01.txt
index bb3ba3e06..cf2d8aa15 100644
--- a/npc/custom/battleground/bg_kvm01.txt
+++ b/npc/custom/battleground/bg_kvm01.txt
@@ -5,27 +5,27 @@
// Registration NPC's
// *********************************************************************
-bat_room,253,227,4 script Registration::KvM01R_Guillaume 4_M_KY_KNT,{ // KvM Guillaume
+bat_room,253,227,4 script Registration::KvM01R_Guillaume#custom 4_M_KY_KNT,{ // KvM Guillaume
end;
OnInit:
- waitingroom "Battle Station 5 Players",5,"KvM01_BG::OnGuillaumeJoin",1;
+ waitingroom "Battle Station 5 Players",5,"KvM01_BG#custom::OnGuillaumeJoin",1;
end;
OnEnterBG:
- set $@KvM01BG_id1, waitingroom2bg("bat_c01",53,128,"KvM01_BG::OnGuillaumeQuit","KvM01_BG::OnGuillaumeDie");
+ set $@KvM01BG_id1, waitingroom2bg("bat_c01",53,128,"KvM01_BG#custom::OnGuillaumeQuit","KvM01_BG#custom::OnGuillaumeDie");
end;
}
-bat_room,253,204,0 script Registration::KvM01R_Croix 4_M_CRU_KNT,{ // KvM Croix
+bat_room,253,204,0 script Registration::KvM01R_Croix#custom 4_M_CRU_KNT,{ // KvM Croix
end;
OnInit:
- waitingroom "Battle Station 5 Players",5,"KvM01_BG::OnCroixJoin",1;
+ waitingroom "Battle Station 5 Players",5,"KvM01_BG#custom::OnCroixJoin",1;
end;
OnEnterBG:
- set $@KvM01BG_id2, waitingroom2bg("bat_c01",146,55,"KvM01_BG::OnCroixQuit","KvM01_BG::OnCroixDie");
+ set $@KvM01BG_id2, waitingroom2bg("bat_c01",146,55,"KvM01_BG#custom::OnCroixQuit","KvM01_BG#custom::OnCroixDie");
end;
}
@@ -49,7 +49,7 @@ bat_c01,145,60,0 duplicate(#bat_c01a) #bat_c01f HIDDEN_NPC
// Battleground Engine
// *********************************************************************
-- script KvM01_BG FAKE_NPC,{
+- script KvM01_BG#custom FAKE_NPC,{
end;
OnInit:
@@ -65,7 +65,7 @@ OnInit:
OnGuillaumeJoin:
OnCroixJoin:
- donpcevent "KvM01_BG::OnReadyCheck";
+ donpcevent "KvM01_BG#custom::OnReadyCheck";
end;
OnGuillaumeQuit:
@@ -76,7 +76,7 @@ OnGuillaumeDie:
set .Guillaume_Count, .Guillaume_Count - 1;
set .Croix_Score, .Croix_Score + 1;
bg_updatescore "bat_c01",.Guillaume_Score,.Croix_Score;
- if( .Guillaume_Count < 1 ) donpcevent "KvM01_BG::OnCroixWin";
+ if( .Guillaume_Count < 1 ) donpcevent "KvM01_BG#custom::OnCroixWin";
}
end;
@@ -88,15 +88,15 @@ OnCroixDie:
set .Croix_Count, .Croix_Count - 1;
set .Guillaume_Score, .Guillaume_Score + 1;
bg_updatescore "bat_c01",.Guillaume_Score,.Croix_Score;
- if( .Croix_Count < 1 ) donpcevent "KvM01_BG::OnGuillaumeWin";
+ if( .Croix_Count < 1 ) donpcevent "KvM01_BG#custom::OnGuillaumeWin";
}
end;
OnReadyCheck:
if( $@KvM01BG )
end;
- set .@Guillaume, getwaitingroomstate(0,"KvM01R_Guillaume");
- set .@Croix, getwaitingroomstate(0,"KvM01R_Croix");
+ set .@Guillaume, getwaitingroomstate(0,"KvM01R_Guillaume#custom");
+ set .@Croix, getwaitingroomstate(0,"KvM01R_Croix#custom");
if( .@Guillaume < 5 || .@Croix < 5 )
{
@@ -111,9 +111,9 @@ OnReadyCheck:
}
set $@KvM01BG, 1; // Starting
- donpcevent "KvM01R_Croix::OnEnterBG";
- donpcevent "KvM01R_Guillaume::OnEnterBG";
- donpcevent "KvM01_BG::OnStart";
+ donpcevent "KvM01R_Croix#custom::OnEnterBG";
+ donpcevent "KvM01R_Guillaume#custom::OnEnterBG";
+ donpcevent "KvM01_BG#custom::OnStart";
end;
OnStart:
@@ -166,7 +166,7 @@ OnTimer30000:
mapannounce "bat_c01","There are not enough players to start the battle",1,0x696969;
stopnpctimer;
sleep 2000;
- donpcevent "KvM01_BG::OnStop";
+ donpcevent "KvM01_BG#custom::OnStop";
end;
}
@@ -187,9 +187,9 @@ OnTimer300000:
OnTimer330000:
if( .Croix_Count > .Guillaume_Count )
- donpcevent "KvM01_BG::OnCroixWin";
+ donpcevent "KvM01_BG#custom::OnCroixWin";
else if( .Croix_Count < .Guillaume_Count )
- donpcevent "KvM01_BG::OnGuillaumeWin";
+ donpcevent "KvM01_BG#custom::OnGuillaumeWin";
else
{ // Draw Game
set $@KvM01BG, 3;
@@ -198,7 +198,7 @@ OnTimer330000:
stopnpctimer;
sleep 2000;
mapannounce "bat_c01","The time is out! This is a Tie...",1,0x696969;
- donpcevent "KvM01_BG::OnStop";
+ donpcevent "KvM01_BG#custom::OnStop";
}
end;
@@ -209,7 +209,7 @@ OnGuillaumeWin:
stopnpctimer;
sleep 2000;
mapannounce "bat_c01","The Guillaume Army has won the Battle of Kreiger Von Midgard",1,0x0000FF;
- donpcevent "KvM01_BG::OnStop";
+ donpcevent "KvM01_BG#custom::OnStop";
end;
OnCroixWin:
@@ -219,7 +219,7 @@ OnCroixWin:
stopnpctimer;
sleep 2000;
mapannounce "bat_c01","The Croix Army has won the Battle of Kreiger Von Midgard",1,0xFF0000;
- donpcevent "KvM01_BG::OnStop";
+ donpcevent "KvM01_BG#custom::OnStop";
end;
OnStop:
@@ -230,12 +230,12 @@ OnStop:
// Warp Teams
bg_warp $@KvM01BG_id1,"bat_c01",53,128;
bg_warp $@KvM01BG_id2,"bat_c01",146,55;
- donpcevent "KvM01_BG_Out::OnBegin";
+ donpcevent "KvM01_BG_Out#custom::OnBegin";
end;
OnReset:
stopnpctimer;
- stopnpctimer "KvM01_BG_Out";
+ stopnpctimer "KvM01_BG_Out#custom";
set .Croix_Count, 0;
set .Guillaume_Count, 0;
set .Croix_Score, 0;
@@ -254,11 +254,11 @@ OnReset:
bg_updatescore "bat_c01",0,0;
sleep 2000;
set $@KvM01BG, 0;
- donpcevent "KvM01_BG::OnReadyCheck"; // Maybe a game is ready to start
+ donpcevent "KvM01_BG#custom::OnReadyCheck"; // Maybe a game is ready to start
end;
}
-- script KvM01_BG_Out FAKE_NPC,{
+- script KvM01_BG_Out#custom FAKE_NPC,{
end;
OnBegin:
@@ -275,7 +275,7 @@ OnTimer50000:
mapannounce "bat_c01","Battle of Kreiger Von Midgard will close in 10 seconds!",1,0x696969;
end;
OnTimer60000:
- donpcevent "KvM01_BG::OnReset";
+ donpcevent "KvM01_BG#custom::OnReset";
end;
}
diff --git a/npc/custom/battleground/bg_kvm02.txt b/npc/custom/battleground/bg_kvm02.txt
index a6cadb3af..9ffc508a6 100644
--- a/npc/custom/battleground/bg_kvm02.txt
+++ b/npc/custom/battleground/bg_kvm02.txt
@@ -5,27 +5,27 @@
// Registration NPC's
// *********************************************************************
-bat_room,225,227,4 script Registration::KvM02R_Guillaume 4_M_KY_KNT,{ // KvM Guillaume
+bat_room,225,227,4 script Registration::KvM02R_Guillaume#custom 4_M_KY_KNT,{ // KvM Guillaume
end;
OnInit:
- waitingroom "Battle Station 5 Players",5,"KvM02_BG::OnGuillaumeJoin",1;
+ waitingroom "Battle Station 5 Players",5,"KvM02_BG#custom::OnGuillaumeJoin",1;
end;
OnEnterBG:
- set $@KvM02BG_id1, waitingroom2bg("bat_c02",53,128,"KvM02_BG::OnGuillaumeQuit","KvM02_BG::OnGuillaumeDie");
+ set $@KvM02BG_id1, waitingroom2bg("bat_c02",53,128,"KvM02_BG#custom::OnGuillaumeQuit","KvM02_BG#custom::OnGuillaumeDie");
end;
}
-bat_room,225,204,0 script Registration::KvM02R_Croix 4_M_CRU_KNT,{ // KvM Croix
+bat_room,225,204,0 script Registration::KvM02R_Croix#custom 4_M_CRU_KNT,{ // KvM Croix
end;
OnInit:
- waitingroom "Battle Station 5 Players",5,"KvM02_BG::OnCroixJoin",1;
+ waitingroom "Battle Station 5 Players",5,"KvM02_BG#custom::OnCroixJoin",1;
end;
OnEnterBG:
- set $@KvM02BG_id2, waitingroom2bg("bat_c02",146,55,"KvM02_BG::OnCroixQuit","KvM02_BG::OnCroixDie");
+ set $@KvM02BG_id2, waitingroom2bg("bat_c02",146,55,"KvM02_BG#custom::OnCroixQuit","KvM02_BG#custom::OnCroixDie");
end;
}
@@ -49,7 +49,7 @@ bat_c02,145,60,0 duplicate(#bat_c02a) #bat_c02f HIDDEN_NPC
// Battleground Engine
// *********************************************************************
-- script KvM02_BG FAKE_NPC,{
+- script KvM02_BG#custom FAKE_NPC,{
end;
OnInit:
@@ -65,7 +65,7 @@ OnInit:
OnGuillaumeJoin:
OnCroixJoin:
- donpcevent "KvM02_BG::OnReadyCheck";
+ donpcevent "KvM02_BG#custom::OnReadyCheck";
end;
OnGuillaumeQuit:
@@ -76,7 +76,7 @@ OnGuillaumeDie:
set .Guillaume_Count, .Guillaume_Count - 1;
set .Croix_Score, .Croix_Score + 1;
bg_updatescore "bat_c02",.Guillaume_Score,.Croix_Score;
- if( .Guillaume_Count < 1 ) donpcevent "KvM02_BG::OnCroixWin";
+ if( .Guillaume_Count < 1 ) donpcevent "KvM02_BG#custom::OnCroixWin";
}
end;
@@ -88,15 +88,15 @@ OnCroixDie:
set .Croix_Count, .Croix_Count - 1;
set .Guillaume_Score, .Guillaume_Score + 1;
bg_updatescore "bat_c02",.Guillaume_Score,.Croix_Score;
- if( .Croix_Count < 1 ) donpcevent "KvM02_BG::OnGuillaumeWin";
+ if( .Croix_Count < 1 ) donpcevent "KvM02_BG#custom::OnGuillaumeWin";
}
end;
OnReadyCheck:
if( $@KvM02BG )
end;
- set .@Guillaume, getwaitingroomstate(0,"KvM02R_Guillaume");
- set .@Croix, getwaitingroomstate(0,"KvM02R_Croix");
+ set .@Guillaume, getwaitingroomstate(0,"KvM02R_Guillaume#custom");
+ set .@Croix, getwaitingroomstate(0,"KvM02R_Croix#custom");
if( .@Guillaume < 5 || .@Croix < 5 )
{
@@ -111,9 +111,9 @@ OnReadyCheck:
}
set $@KvM02BG, 1; // Starting
- donpcevent "KvM02R_Croix::OnEnterBG";
- donpcevent "KvM02R_Guillaume::OnEnterBG";
- donpcevent "KvM02_BG::OnStart";
+ donpcevent "KvM02R_Croix#custom::OnEnterBG";
+ donpcevent "KvM02R_Guillaume#custom::OnEnterBG";
+ donpcevent "KvM02_BG#custom::OnStart";
end;
OnStart:
@@ -166,7 +166,7 @@ OnTimer30000:
mapannounce "bat_c02","There are not enough players to start the battle",1,0x808080;
stopnpctimer;
sleep 2000;
- donpcevent "KvM02_BG::OnStop";
+ donpcevent "KvM02_BG#custom::OnStop";
end;
}
@@ -187,9 +187,9 @@ OnTimer300000:
OnTimer330000:
if( .Croix_Count > .Guillaume_Count )
- donpcevent "KvM02_BG::OnCroixWin";
+ donpcevent "KvM02_BG#custom::OnCroixWin";
else if( .Croix_Count < .Guillaume_Count )
- donpcevent "KvM02_BG::OnGuillaumeWin";
+ donpcevent "KvM02_BG#custom::OnGuillaumeWin";
else
{ // Draw Game
set $@KvM02BG, 3;
@@ -198,7 +198,7 @@ OnTimer330000:
stopnpctimer;
sleep 2000;
mapannounce "bat_c02","The time is out! This is a Tie...",1,0x808080;
- donpcevent "KvM02_BG::OnStop";
+ donpcevent "KvM02_BG#custom::OnStop";
}
end;
@@ -209,7 +209,7 @@ OnGuillaumeWin:
stopnpctimer;
sleep 2000;
mapannounce "bat_c02","The Guillaume Army has won the Battle of Kreiger Von Midgard",1,0x0000FF;
- donpcevent "KvM02_BG::OnStop";
+ donpcevent "KvM02_BG#custom::OnStop";
end;
OnCroixWin:
@@ -219,7 +219,7 @@ OnCroixWin:
stopnpctimer;
sleep 2000;
mapannounce "bat_c02","The Croix Army has won the Battle of Kreiger Von Midgard",1,0xFF0000;
- donpcevent "KvM02_BG::OnStop";
+ donpcevent "KvM02_BG#custom::OnStop";
end;
OnStop:
@@ -230,12 +230,12 @@ OnStop:
// Warp Teams
bg_warp $@KvM02BG_id1,"bat_c02",53,128;
bg_warp $@KvM02BG_id2,"bat_c02",146,55;
- donpcevent "KvM02_BG_Out::OnBegin";
+ donpcevent "KvM02_BG_Out#custom::OnBegin";
end;
OnReset:
stopnpctimer;
- stopnpctimer "KvM02_BG_Out";
+ stopnpctimer "KvM02_BG_Out#custom";
set .Croix_Count, 0;
set .Guillaume_Count, 0;
set .Croix_Score, 0;
@@ -254,11 +254,11 @@ OnReset:
bg_updatescore "bat_c02",0,0;
sleep 2000;
set $@KvM02BG, 0;
- donpcevent "KvM02_BG::OnReadyCheck"; // Maybe a game is ready to start
+ donpcevent "KvM02_BG#custom::OnReadyCheck"; // Maybe a game is ready to start
end;
}
-- script KvM02_BG_Out FAKE_NPC,{
+- script KvM02_BG_Out#custom FAKE_NPC,{
end;
OnBegin:
@@ -275,7 +275,7 @@ OnTimer50000:
mapannounce "bat_c02","Battle of Kreiger Von Midgard will close in 10 seconds!",1,0x808080;
end;
OnTimer60000:
- donpcevent "KvM02_BG::OnReset";
+ donpcevent "KvM02_BG#custom::OnReset";
end;
}
diff --git a/npc/custom/battleground/bg_kvm03.txt b/npc/custom/battleground/bg_kvm03.txt
index 8f255c90f..14d7c03a3 100644
--- a/npc/custom/battleground/bg_kvm03.txt
+++ b/npc/custom/battleground/bg_kvm03.txt
@@ -5,27 +5,27 @@
// Registration NPC's
// *********************************************************************
-bat_room,197,227,4 script Registration::KvM03R_Guillaume 4_M_KY_KNT,{ // KvM Guillaume
+bat_room,197,227,4 script Registration::KvM03R_Guillaume#custom 4_M_KY_KNT,{ // KvM Guillaume
end;
OnInit:
- waitingroom "Battle Station 5 Players",5,"KvM03_BG::OnGuillaumeJoin",1;
+ waitingroom "Battle Station 5 Players",5,"KvM03_BG#custom::OnGuillaumeJoin",1;
end;
OnEnterBG:
- set $@KvM03BG_id1, waitingroom2bg("bat_c03",53,128,"KvM03_BG::OnGuillaumeQuit","KvM03_BG::OnGuillaumeDie");
+ set $@KvM03BG_id1, waitingroom2bg("bat_c03",53,128,"KvM03_BG#custom::OnGuillaumeQuit","KvM03_BG#custom::OnGuillaumeDie");
end;
}
-bat_room,197,204,0 script Registration::KvM03R_Croix 4_M_CRU_KNT,{ // KvM Croix
+bat_room,197,204,0 script Registration::KvM03R_Croix#custom 4_M_CRU_KNT,{ // KvM Croix
end;
OnInit:
- waitingroom "Battle Station 5 Players",5,"KvM03_BG::OnCroixJoin",1;
+ waitingroom "Battle Station 5 Players",5,"KvM03_BG#custom::OnCroixJoin",1;
end;
OnEnterBG:
- set $@KvM03BG_id2, waitingroom2bg("bat_c03",146,55,"KvM03_BG::OnCroixQuit","KvM03_BG::OnCroixDie");
+ set $@KvM03BG_id2, waitingroom2bg("bat_c03",146,55,"KvM03_BG#custom::OnCroixQuit","KvM03_BG#custom::OnCroixDie");
end;
}
@@ -49,7 +49,7 @@ bat_c03,145,60,0 duplicate(#bat_c03a) #bat_c03f HIDDEN_NPC
// Battleground Engine
// *********************************************************************
-- script KvM03_BG FAKE_NPC,{
+- script KvM03_BG#custom FAKE_NPC,{
end;
OnInit:
@@ -65,7 +65,7 @@ OnInit:
OnGuillaumeJoin:
OnCroixJoin:
- donpcevent "KvM03_BG::OnReadyCheck";
+ donpcevent "KvM03_BG#custom::OnReadyCheck";
end;
OnGuillaumeQuit:
@@ -76,7 +76,7 @@ OnGuillaumeDie:
set .Guillaume_Count, .Guillaume_Count - 1;
set .Croix_Score, .Croix_Score + 1;
bg_updatescore "bat_c03",.Guillaume_Score,.Croix_Score;
- if( .Guillaume_Count < 1 ) donpcevent "KvM03_BG::OnCroixWin";
+ if( .Guillaume_Count < 1 ) donpcevent "KvM03_BG#custom::OnCroixWin";
}
end;
@@ -88,15 +88,15 @@ OnCroixDie:
set .Croix_Count, .Croix_Count - 1;
set .Guillaume_Score, .Guillaume_Score + 1;
bg_updatescore "bat_c03",.Guillaume_Score,.Croix_Score;
- if( .Croix_Count < 1 ) donpcevent "KvM03_BG::OnGuillaumeWin";
+ if( .Croix_Count < 1 ) donpcevent "KvM03_BG#custom::OnGuillaumeWin";
}
end;
OnReadyCheck:
if( $@KvM03BG )
end;
- set .@Guillaume, getwaitingroomstate(0,"KvM03R_Guillaume");
- set .@Croix, getwaitingroomstate(0,"KvM03R_Croix");
+ set .@Guillaume, getwaitingroomstate(0,"KvM03R_Guillaume#custom");
+ set .@Croix, getwaitingroomstate(0,"KvM03R_Croix#custom");
if( .@Guillaume < 5 || .@Croix < 5 )
{
@@ -111,9 +111,9 @@ OnReadyCheck:
}
set $@KvM03BG, 1; // Starting
- donpcevent "KvM03R_Croix::OnEnterBG";
- donpcevent "KvM03R_Guillaume::OnEnterBG";
- donpcevent "KvM03_BG::OnStart";
+ donpcevent "KvM03R_Croix#custom::OnEnterBG";
+ donpcevent "KvM03R_Guillaume#custom::OnEnterBG";
+ donpcevent "KvM03_BG#custom::OnStart";
end;
OnStart:
@@ -166,7 +166,7 @@ OnTimer30000:
mapannounce "bat_c03","There are not enough players to start the battle",1,0xC0C0C0;
stopnpctimer;
sleep 2000;
- donpcevent "KvM03_BG::OnStop";
+ donpcevent "KvM03_BG#custom::OnStop";
end;
}
@@ -187,9 +187,9 @@ OnTimer300000:
OnTimer330000:
if( .Croix_Count > .Guillaume_Count )
- donpcevent "KvM03_BG::OnCroixWin";
+ donpcevent "KvM03_BG#custom::OnCroixWin";
else if( .Croix_Count < .Guillaume_Count )
- donpcevent "KvM03_BG::OnGuillaumeWin";
+ donpcevent "KvM03_BG#custom::OnGuillaumeWin";
else
{ // Draw Game
set $@KvM03BG, 3;
@@ -198,7 +198,7 @@ OnTimer330000:
stopnpctimer;
sleep 2000;
mapannounce "bat_c03","The time is out! This is a Tie...",1,0xC0C0C0;
- donpcevent "KvM03_BG::OnStop";
+ donpcevent "KvM03_BG#custom::OnStop";
}
end;
@@ -209,7 +209,7 @@ OnGuillaumeWin:
stopnpctimer;
sleep 2000;
mapannounce "bat_c03","The Guillaume Army has won the Battle of Kreiger Von Midgard",1,0x0000FF;
- donpcevent "KvM03_BG::OnStop";
+ donpcevent "KvM03_BG#custom::OnStop";
end;
OnCroixWin:
@@ -219,7 +219,7 @@ OnCroixWin:
stopnpctimer;
sleep 2000;
mapannounce "bat_c03","The Croix Army has won the Battle of Kreiger Von Midgard",1,0xFF0000;
- donpcevent "KvM03_BG::OnStop";
+ donpcevent "KvM03_BG#custom::OnStop";
end;
OnStop:
@@ -230,12 +230,12 @@ OnStop:
// Warp Teams
bg_warp $@KvM03BG_id1,"bat_c03",53,128;
bg_warp $@KvM03BG_id2,"bat_c03",146,55;
- donpcevent "KvM03_BG_Out::OnBegin";
+ donpcevent "KvM03_BG_Out#custom::OnBegin";
end;
OnReset:
stopnpctimer;
- stopnpctimer "KvM03_BG_Out";
+ stopnpctimer "KvM03_BG_Out#custom";
set .Croix_Count, 0;
set .Guillaume_Count, 0;
set .Croix_Score, 0;
@@ -254,11 +254,11 @@ OnReset:
bg_updatescore "bat_c03",0,0;
sleep 2000;
set $@KvM03BG, 0;
- donpcevent "KvM03_BG::OnReadyCheck"; // Maybe a game is ready to start
+ donpcevent "KvM03_BG#custom::OnReadyCheck"; // Maybe a game is ready to start
end;
}
-- script KvM03_BG_Out FAKE_NPC,{
+- script KvM03_BG_Out#custom FAKE_NPC,{
end;
OnBegin:
@@ -275,7 +275,7 @@ OnTimer50000:
mapannounce "bat_c03","Battle of Kreiger Von Midgard will close in 10 seconds!",1,0xC0C0C0;
end;
OnTimer60000:
- donpcevent "KvM03_BG::OnReset";
+ donpcevent "KvM03_BG#custom::OnReset";
end;
}
diff --git a/npc/jobs/2-1/wizard.txt b/npc/jobs/2-1/wizard.txt
index 3814e1880..3c779f188 100644
--- a/npc/jobs/2-1/wizard.txt
+++ b/npc/jobs/2-1/wizard.txt
@@ -1527,7 +1527,7 @@ OnTimer183000:
end;
OnTimer184000:
- enablenpc "Room of Fire#Failed";
+ areawarp("job_wiz", 30, 83, 62, 115, "geffen", 120, 110);
end;
OnTimer185000:
@@ -1535,8 +1535,6 @@ OnTimer185000:
end;
OnTimer186000:
- disablenpc "Room of Fire#Failed";
- donpcevent "Room of Fire::OnDisable";
donpcevent "Arena Assistant::OnStart";
end;
}
@@ -1604,7 +1602,7 @@ OnTimer120000:
end;
OnTimer121000:
- enablenpc "Room of Fire#Failed";
+ areawarp("job_wiz", 30, 83, 62, 115, "geffen", 120, 110);
end;
OnTimer122000:
@@ -1612,21 +1610,10 @@ OnTimer122000:
end;
OnTimer123000:
- disablenpc "Room of Fire#Failed";
donpcevent "Room of Fire#Door::OnDisable";
donpcevent "Arena Assistant::OnStart";
}
-job_wiz,46,99,0 script Room of Fire#Failed FAKE_NPC,16,16,{
-OnInit:
- disablenpc "Room of Fire#Failed";
- end;
-
-OnTouch:
- warp "geffen",120,110;
- end;
-}
-
job_wiz,1,7,1 script Test Helper#wiz 1_F_01,{
end;
diff --git a/npc/mapflag/night.txt b/npc/mapflag/night.txt
index 3e421bf13..444189412 100644
--- a/npc/mapflag/night.txt
+++ b/npc/mapflag/night.txt
@@ -263,8 +263,8 @@ ve_fild06 mapflag nightenabled
ve_fild07 mapflag nightenabled
//Episode 12 ====================
-poring_c01 mapflag nightenabled
-poring_c02 mapflag nightenabled
+//poring_c01 mapflag nightenabled
+//poring_c02 mapflag nightenabled
nameless_i mapflag nightenabled
nameless_n mapflag nightenabled
poring_w01 mapflag nightenabled
diff --git a/npc/mapflag/nobranch.txt b/npc/mapflag/nobranch.txt
index 4007c8203..7e4f3b49d 100644
--- a/npc/mapflag/nobranch.txt
+++ b/npc/mapflag/nobranch.txt
@@ -153,8 +153,8 @@ que_god01 mapflag nobranch
que_god02 mapflag nobranch
que_bingo mapflag nobranch
que_hugel mapflag nobranch
-poring_c01 mapflag nobranch
-poring_c02 mapflag nobranch
+//poring_c01 mapflag nobranch
+//poring_c02 mapflag nobranch
kh_mansion mapflag nobranch
kh_rossi mapflag nobranch
kh_school mapflag nobranch
diff --git a/npc/mapflag/nomemo.txt b/npc/mapflag/nomemo.txt
index 548f1563e..d4f7140fe 100644
--- a/npc/mapflag/nomemo.txt
+++ b/npc/mapflag/nomemo.txt
@@ -259,8 +259,8 @@ que_hugel mapflag nomemo
que_rachel mapflag nomemo
que_san04 mapflag nomemo
que_thor mapflag nomemo
-poring_c01 mapflag nomemo
-poring_c02 mapflag nomemo
+//poring_c01 mapflag nomemo
+//poring_c02 mapflag nomemo
// Dungeons =================
alde_dun01 mapflag nomemo
alde_dun02 mapflag nomemo
diff --git a/npc/mapflag/nopet.txt b/npc/mapflag/nopet.txt
new file mode 100644
index 000000000..82f9e36eb
--- /dev/null
+++ b/npc/mapflag/nopet.txt
@@ -0,0 +1,78 @@
+//================= Hercules Script =======================================
+//= _ _ _
+//= | | | | | |
+//= | |_| | ___ _ __ ___ _ _| | ___ ___
+//= | _ |/ _ \ '__/ __| | | | |/ _ \/ __|
+//= | | | | __/ | | (__| |_| | | __/\__ \
+//= \_| |_/\___|_| \___|\__,_|_|\___||___/
+//================= License ===============================================
+//= This file is part of Hercules.
+//= http://herc.ws - http://github.com/HerculesWS/Hercules
+//=
+//= Copyright (C) 2012-2020 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/>.
+//=========================================================================
+//= Mapflag: Disable pet in map.
+//================= Current Version =======================================
+//= 1.0
+//================= Description ===========================================
+//= Players can't hatch pet in the map, existing pet will return to egg.
+//=========================================================================
+
+// GvG Arenas =============
+// guild_vs1 mapflag nopet
+// guild_vs2 mapflag nopet
+// guild_vs3 mapflag nopet
+// guild_vs4 mapflag nopet
+// guild_vs5 mapflag nopet
+
+// Guild Castles ==========
+// aldeg_cas01 mapflag nopet
+// aldeg_cas02 mapflag nopet
+// aldeg_cas03 mapflag nopet
+// aldeg_cas04 mapflag nopet
+// aldeg_cas05 mapflag nopet
+// gefg_cas01 mapflag nopet
+// gefg_cas02 mapflag nopet
+// gefg_cas03 mapflag nopet
+// gefg_cas04 mapflag nopet
+// gefg_cas05 mapflag nopet
+// payg_cas01 mapflag nopet
+// payg_cas02 mapflag nopet
+// payg_cas03 mapflag nopet
+// payg_cas04 mapflag nopet
+// payg_cas05 mapflag nopet
+// prtg_cas01 mapflag nopet
+// prtg_cas02 mapflag nopet
+// prtg_cas03 mapflag nopet
+// prtg_cas04 mapflag nopet
+// prtg_cas05 mapflag nopet
+// schg_cas01 mapflag nopet
+// schg_cas02 mapflag nopet
+// schg_cas03 mapflag nopet
+// schg_cas04 mapflag nopet
+// schg_cas05 mapflag nopet
+// arug_cas01 mapflag nopet
+// arug_cas02 mapflag nopet
+// arug_cas03 mapflag nopet
+// arug_cas04 mapflag nopet
+// arug_cas05 mapflag nopet
+
+// Novice Guild Castles ===
+// n_castle mapflag nopet
+// nguild_alde mapflag nopet
+// nguild_gef mapflag nopet
+// nguild_pay mapflag nopet
+// nguild_prt mapflag nopet
diff --git a/npc/mapflag/noteleport.txt b/npc/mapflag/noteleport.txt
index 537781075..9f41e4342 100644
--- a/npc/mapflag/noteleport.txt
+++ b/npc/mapflag/noteleport.txt
@@ -186,8 +186,8 @@ kh_kiehl01 mapflag noteleport
kh_kiehl02 mapflag noteleport
que_rachel mapflag noteleport
que_thor mapflag noteleport
-poring_c01 mapflag noteleport
-poring_c02 mapflag noteleport
+//poring_c01 mapflag noteleport
+//poring_c02 mapflag noteleport
que_job01 mapflag noteleport
que_job02 mapflag noteleport
que_job03 mapflag noteleport
diff --git a/npc/quests/quests_amatsu.txt b/npc/quests/quests_amatsu.txt
index 3c55f91a3..504ab6032 100644
--- a/npc/quests/quests_amatsu.txt
+++ b/npc/quests/quests_amatsu.txt
@@ -399,11 +399,14 @@ OnStartArena:
enablenpc "Grandma#ama1";
enablenpc "Grandpa#ama";
warpwaitingpc "ama_test",50,83;
- donpcevent "Timer#ama::OnEnable";
+ enablenpc("Timer#ama");
+ initnpctimer("Timer#ama");
disablewaitingroomevent "Assistant#ama";
end;
OnReset:
+ stopnpctimer("Timer#ama");
+ disablenpc("Timer#ama");
enablewaitingroomevent "Assistant#ama";
end;
}
@@ -620,7 +623,6 @@ ama_test,50,100,3 script Coach#ama 4_M_JPN2,15,15,{
mes "Don't lose your high self-esteem";
mes "in the future. Farewell.";
close2;
- donpcevent "Timer#ama::OnDisable";
warp "amatsu",223,230;
disablenpc "Coach#ama";
donpcevent "Assistant#ama::OnReset";
@@ -665,7 +667,6 @@ ama_test,50,100,3 script Coach#ama 4_M_JPN2,15,15,{
setquest 8128;
warp "amatsu",223,230;
disablenpc "Coach#ama";
- donpcevent "Timer#ama::OnDisable";
donpcevent "Assistant#ama::OnReset";
end;
}
@@ -754,7 +755,6 @@ OnTouch:
changequest 8129,8130;
warp "amatsu",223,230;
disablenpc "Coach#after";
- donpcevent "Timer#ama::OnDisable";
donpcevent "Assistant#ama::OnReset";
end;
}
@@ -764,14 +764,6 @@ OnInit:
disablenpc "Timer#ama";
end;
-OnEnable:
- enablenpc "Timer#ama";
- initnpctimer;
- end;
-OnDisable:
- stopnpctimer;
- end;
-
OnTimer1000:
mapannounce "ama_test"," The Timer has been activated. You have 6 minutes. Annihilate the monsters in time! ",bc_map;
end;
@@ -788,26 +780,11 @@ OnTimer361000:
end;
OnTimer361500:
- enablenpc "backwarp#ama";
- end;
-
-OnTimer362000:
- disablenpc "backwarp#ama";
+ areawarp("ama_test", 25, 75, 80, 130, "amatsu", 115, 95);
end;
OnTimer362500:
donpcevent "Assistant#ama::OnReset";
- donpcevent "Timer#ama::OnDisable";
- end;
-}
-
-ama_test,50,100,0 script backwarp#ama FAKE_NPC,25,25,{
-OnInit:
- disablenpc "backwarp#ama";
- end;
-
-OnTouch:
- warp "amatsu",115,95;
end;
}
diff --git a/npc/quests/quests_juperos.txt b/npc/quests/quests_juperos.txt
index d120bfc27..f9120796d 100644
--- a/npc/quests/quests_juperos.txt
+++ b/npc/quests/quests_juperos.txt
@@ -4914,7 +4914,7 @@ OnTouch:
case 1:
specialeffect(EF_LIGHTSPHERE, AREA, playerattached());
close2;
- stopnpctimer;
+ stopnpctimer(1);
warp "juperos_02",130,142;
break;
case 2:
@@ -4922,7 +4922,7 @@ OnTouch:
mes "Not now!";
mes "I can't leave yet!";
close2;
- stopnpctimer;
+ stopnpctimer(1);
warp "jupe_gate",50,168;
break;
}
@@ -4930,23 +4930,7 @@ OnTouch:
OnTimer10000:
warp "juperos_02",128,278;
- enablenpc "gate#start#2";
- disablenpc "gate#start";
- end;
-}
-
-jupe_gate,50,171,0 script gate#start#2 FAKE_NPC,2,2,{
-OnInit:
- disablenpc "gate#start#2";
- end;
-
-OnTouch:
- warp "juperos_02",130,142;
- end;
-
-OnTimer2000:
- enablenpc "gate#start";
- disablenpc "gate#start#2";
+ areawarp("jupe_gate", 48, 169, 52, 173, "juperos_02", 130, 142);
end;
}
diff --git a/npc/quests/quests_lighthalzen.txt b/npc/quests/quests_lighthalzen.txt
index fe8abf473..0d83efd3c 100644
--- a/npc/quests/quests_lighthalzen.txt
+++ b/npc/quests/quests_lighthalzen.txt
@@ -9774,27 +9774,17 @@ OnTouch:
}
lhz_in01,177,44,0 script Timer_Sneak FAKE_NPC,8,12,{
-
-OnTouch:
- warp "lhz_in01",191,49;
- end;
-
-OnInit:
- disablenpc "Timer_Sneak";
- end;
-
OnEnter:
stopnpctimer;
initnpctimer;
end;
OnTimer180000:
- enablenpc "Timer_Sneak";
+ areawarp("lhz_in01", 169, 32, 185, 56, "lhz_in01", 191, 49);
end;
OnTimer190000:
stopnpctimer;
- disablenpc "Timer_Sneak";
end;
}
diff --git a/npc/quests/quests_moscovia.txt b/npc/quests/quests_moscovia.txt
index 3f44a9b0a..e0678cec9 100644
--- a/npc/quests/quests_moscovia.txt
+++ b/npc/quests/quests_moscovia.txt
@@ -1134,7 +1134,7 @@ mosk_ship,101,111,4 script rudder#ship HIDDEN_NPC,{
mes "Hey! Listen to what I am saying.";
mes "How come you go there without my";
mes "permission...";
- next;
+ close;
}
mes "[Mr. Ibanoff]";
mes "What? How did you get on";
@@ -1171,7 +1171,10 @@ S_Rud1:
mes "ever encountered! Be careful! We";
mes "must repulse these monsters!";
++$@mos1_edq;
- donpcevent "Baehideun3#ship::OnEnable";
+ if (mos_whale_edq >= 241)
+ donpcevent "Baehideun4#ship::OnEnable";
+ else
+ donpcevent "Baehideun3#ship::OnEnable";
}
mos_whale_edq = (getarg(1) == 2)?((mos_whale_edq >= 241)?((.@r != 3)?26:25):((.@r != 3)?10:11)):mos_whale_edq + 1;
close;
diff --git a/npc/quests/seals/god_weapon_creation.txt b/npc/quests/seals/god_weapon_creation.txt
index 8009bd36d..17979e51a 100644
--- a/npc/quests/seals/god_weapon_creation.txt
+++ b/npc/quests/seals/god_weapon_creation.txt
@@ -807,41 +807,15 @@ OnTimer610000:
end;
OnTimer612000:
- donpcevent "god_wep_warpmaster::OnEnable";
+ areawarp("que_god01", 130, 55, 190, 135, "prontera", 156, 324);
end;
OnTimer615000:
- donpcevent "god_wep_warpmaster::OnDisable";
donpcevent "#god_hopewarp1::OnReset";
stopnpctimer;
end;
}
-que_god01,169,82,0 script god_wep_warpmaster FAKE_NPC,{
-OnEnable:
- for(.@i = 1; .@i<=6; ++.@i)
- enablenpc "god_failwarp#"+.@i;
- end;
-OnDisable:
- for(.@i = 1; .@i<=6; ++.@i)
- disablenpc "god_failwarp#"+.@i;
- end;
-}
-
-que_god01,154,67,0 script god_failwarp#1 FAKE_NPC,4,7,{
-OnInit:
- disablenpc strnpcinfo(NPC_NAME);
- end;
-OnTouch:
- warp "prontera",156,324;
- end;
-}
-que_god01,154,82,0 duplicate(god_failwarp#1) god_failwarp#2 FAKE_NPC,4,7
-que_god01,145,99,0 duplicate(god_failwarp#1) god_failwarp#3 FAKE_NPC,9,9
-que_god01,164,99,0 duplicate(god_failwarp#1) god_failwarp#4 FAKE_NPC,9,9
-que_god01,145,118,0 duplicate(god_failwarp#1) god_failwarp#5 FAKE_NPC,9,9
-que_god01,164,118,0 duplicate(god_failwarp#1) god_failwarp#6 FAKE_NPC,9,9
-
// Original name: "Godly Item Quests Related#god"
que_god01,293,3,0 script Godly Item Quests#god 4_F_01,{
callfunc "F_GM_NPC";
@@ -864,24 +838,16 @@ que_god01,293,3,0 script Godly Item Quests#god 4_F_01,{
mes "[Use in case of emergency]";
mes "What services would you like to use?";
next;
- switch(select("Turn off Warps.", "Reset Timer.", "Reset chat room.")) {
+ switch(select("Reset Timer.", "Reset chat room.")) {
case 1:
mes "[Use in case of emergency]";
- mes "Press the 'Next' button to turn off warps.";
- next;
- donpcevent "god_wep_warpmaster::OnDisable";
- mes "[Use in case of emergency]";
- mes "You have successfully turned off warps.";
- close;
- case 2:
- mes "[Use in case of emergency]";
mes "Press the 'Next' button to reset timer.";
next;
donpcevent "Grunburti#god::OnEnable";
mes "[Use in case of emergency]";
mes "You have successfully reset timer.";
close;
- case 3:
+ case 2:
mes "[Use in case of emergency]";
mes "Please press the 'Next' button to reset the arena chat room in que_god01.";
next;
diff --git a/npc/quests/the_sign_quest.txt b/npc/quests/the_sign_quest.txt
index 5949c3558..d7db39dff 100644
--- a/npc/quests/the_sign_quest.txt
+++ b/npc/quests/the_sign_quest.txt
@@ -12317,34 +12317,18 @@ OnEnable:
end;
}
-que_sign01,196,44,0 script Warp#serin FAKE_NPC,35,35,{
-OnDisable:
-OnInit:
- disablenpc "Warp#serin";
- end;
-
-OnTouch:
- warp "niflheim",30,156;
- end;
-
-OnEnable:
- enablenpc "Warp#serin";
- end;
-}
-
que_sign01,1,0,0 script Timer#serin FAKE_NPC,{
OnStart:
initnpctimer;
end;
OnTimer600000:
- donpcevent "Warp#serin::OnEnable";
+ areawarp("que_sign01", 161, 9, 231, 79, "niflheim", 30, 156);
end;
OnTimer620000:
$@sign_w2 = 0;
donpcevent "Starter#serin::OnEnable";
- donpcevent "Warp#serin::OnDisable";
donpcevent "Serin#serin::OnEnable";
donpcevent "Dark Lord#serin::OnDisable";
donpcevent "Serin#dummy::OnDisable";
diff --git a/npc/re/merchants/hd_refiner.txt b/npc/re/merchants/hd_refiner.txt
index 43cdc2c01..7b032efff 100644
--- a/npc/re/merchants/hd_refiner.txt
+++ b/npc/re/merchants/hd_refiner.txt
@@ -38,7 +38,7 @@
//=========================================================================
//== Blacksmith Mighty Hammer (+7~9) =======================
-- script ::MightyHammer FAKE_NPC,{
+- script ::MightyHammer#re FAKE_NPC,{
mes("[Blacksmith Mighty Hammer]");
mes("I'm a blacksmith skilled in refining weapons and armors.");
mes("I can refine an item of your choice among the items you are equipped with.");
@@ -171,20 +171,20 @@
mes "I am sure a person like you would never blame me for a decrease in refine level by 1. Hmm.";
close;
}
-prt_in,59,54,3 duplicate(MightyHammer) Mighty Hammer#prt 4_M_DWARF
-morocc_in,65,30,3 duplicate(MightyHammer) Mighty Hammer#morocc 4_M_DWARF
-payon,148,176,3 duplicate(MightyHammer) Mighty Hammer#pay 4_M_DWARF
-alberta_in,16,56,3 duplicate(MightyHammer) Mighty Hammer#alb 4_M_DWARF
-yuno_in01,171,18,3 duplicate(MightyHammer) Mighty Hammer#yuno 4_M_DWARF
-ein_in01,22,82,3 duplicate(MightyHammer) Mighty Hammer#ein 4_M_DWARF
-lhz_in02,280,19,3 duplicate(MightyHammer) Mighty Hammer#lhz 4_M_DWARF
+prt_in,59,54,3 duplicate(MightyHammer#re) Mighty Hammer#prtre 4_M_DWARF
+morocc_in,65,30,3 duplicate(MightyHammer#re) Mighty Hammer#moroccre 4_M_DWARF
+payon,148,176,3 duplicate(MightyHammer#re) Mighty Hammer#payre 4_M_DWARF
+alberta_in,16,56,3 duplicate(MightyHammer#re) Mighty Hammer#albre 4_M_DWARF
+yuno_in01,171,18,3 duplicate(MightyHammer#re) Mighty Hammer#yunore 4_M_DWARF
+ein_in01,22,82,3 duplicate(MightyHammer#re) Mighty Hammer#einre 4_M_DWARF
+lhz_in02,280,19,3 duplicate(MightyHammer#re) Mighty Hammer#lhzre 4_M_DWARF
//- iRO NPC locations -
-//moc_para01,38,185,4 duplicate(MightyHammer) Mighty Hammer#ed 4_M_DWARF
-//payon,174,133,4 duplicate(MightyHammer) Mighty Hammer#im 4_M_DWARF
+//moc_para01,38,185,4 duplicate(MightyHammer#re) Mighty Hammer#edre 4_M_DWARF
+//payon,174,133,4 duplicate(MightyHammer#re) Mighty Hammer#imre 4_M_DWARF
//== Basta (+10 and up) ====================================
-- script ::Basta FAKE_NPC,{
+- script ::Basta#re FAKE_NPC,{
disable_items;
mes "[Basta]";
mes "I'm the best Blacksmith in the whole world, Basta.";
@@ -327,10 +327,10 @@ lhz_in02,280,19,3 duplicate(MightyHammer) Mighty Hammer#lhz 4_M_DWARF
mes "I'll do better next time! Don't worry!";
close;
}
-prt_in,57,54,3 duplicate(Basta) Basta#prt 4_M_DWARF
-morocc_in,68,30,3 duplicate(Basta) Basta#morocc 4_M_DWARF
-payon,148,174,3 duplicate(Basta) Basta#payon 4_M_DWARF
-alberta_in,18,56,3 duplicate(Basta) Basta#alberta 4_M_DWARF
-yuno_in01,173,18,3 duplicate(Basta) Basta#yuno 4_M_DWARF
-ein_in01,24,82,3 duplicate(Basta) Basta#einbroch 4_M_DWARF
-lhz_in02,280,17,3 duplicate(Basta) Basta#lighthalzen 4_M_DWARF
+prt_in,57,54,3 duplicate(Basta#re) Basta#prtre 4_M_DWARF
+morocc_in,68,30,3 duplicate(Basta#re) Basta#moroccre 4_M_DWARF
+payon,148,174,3 duplicate(Basta#re) Basta#payonre 4_M_DWARF
+alberta_in,18,56,3 duplicate(Basta#re) Basta#albertare 4_M_DWARF
+yuno_in01,173,18,3 duplicate(Basta#re) Basta#yunore 4_M_DWARF
+ein_in01,24,82,3 duplicate(Basta#re) Basta#einbrochre 4_M_DWARF
+lhz_in02,280,17,3 duplicate(Basta#re) Basta#lighthalzenre 4_M_DWARF
diff --git a/npc/scripts.conf b/npc/scripts.conf
index 086370899..c5dd2b54b 100644
--- a/npc/scripts.conf
+++ b/npc/scripts.conf
@@ -120,7 +120,8 @@
"npc/events/god_se_festival.txt",
// - Official Halloween Events (iRO)
//"npc/events/halloween_2006.txt",
-//"npc/events/halloween_2008.txt",
+// missing map
+// "npc/events/halloween_2008.txt",
//"npc/events/halloween_2009.txt",
// - Official idRO Idul Fitri Event
//"npc/events/idul_fitri.txt",
diff --git a/npc/scripts_dev.conf b/npc/scripts_dev.conf
index d6d807a74..df644013d 100644
--- a/npc/scripts_dev.conf
+++ b/npc/scripts_dev.conf
@@ -31,4 +31,4 @@
//=========================================================================
//================= Script Engine self-test ===============================
-//"npc: npc/dev/test.txt",
+//"npc/dev/test.txt",
diff --git a/npc/scripts_mapflags.conf b/npc/scripts_mapflags.conf
index 084004244..74fb40610 100644
--- a/npc/scripts_mapflags.conf
+++ b/npc/scripts_mapflags.conf
@@ -58,3 +58,4 @@
"npc/mapflag/skillduration.txt",
"npc/mapflag/notomb.txt",
"npc/mapflag/private_airship.txt",
+"npc/mapflag/nopet.txt",
diff --git a/sql-files/item_db.sql b/sql-files/item_db.sql
index abceecdba..d6f6ca544 100644
--- a/sql-files/item_db.sql
+++ b/sql-files/item_db.sql
@@ -1190,7 +1190,7 @@ REPLACE INTO `item_db` VALUES ('2231','Gemmed_Sallet_','Gemmed Sallet','5','0','
REPLACE INTO `item_db` VALUES ('2232','Circlet','Circlet','5','0','7500','3750','300','0','0','3','0','0','8487700','63','2','256','0','0',NULL,'1','0','18','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
REPLACE INTO `item_db` VALUES ('2233','Circlet_','Circlet','5','0','7500','3750','300','0','0','3','0','1','8487700','63','2','256','0','0',NULL,'1','0','18','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
REPLACE INTO `item_db` VALUES ('2234','Tiara','Tiara','5','0','20','10','400','0','0','4','0','0','18446744073709551614','63','2','256','0','45',NULL,'1','0','19','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,2;','','');
-REPLACE INTO `item_db` VALUES ('2235','Crown','Crown','5','0','20','10','400','0','0','4','0','0','18446744073709551614','63','1','256','0','45',NULL,'1','0','45','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,2;','','');
+REPLACE INTO `item_db` VALUES ('2235','Crown','Crown','5','0','20','10','400','0','0','4','0','0','18446744073709551614','63','2','256','0','45',NULL,'1','0','45','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,2;','','');
REPLACE INTO `item_db` VALUES ('2236','Santas_Hat','Santa Hat','5','0','20','10','100','0','0','1','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','20','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,1; bonus bLuk,1;','','');
REPLACE INTO `item_db` VALUES ('2237','Weird_Goatee','Bandit Beard','5','0','2','1','100','0','0','0','0','0','18446744073709551615','63','2','1','0','0',NULL,'0','0','21','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2239','One_Eyed_Glass','Monocle','5','0','10000','5000','100','0','0','0','0','0','18446744073709551615','63','2','512','0','0',NULL,'0','0','23','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -2338,7 +2338,7 @@ REPLACE INTO `item_db` VALUES ('5139','Hibiscus','Hibiscus','5','0','20','10','2
REPLACE INTO `item_db` VALUES ('5140','Charming_Ribbon','Charming Ribbon','5','0','20','10','400','0','0','1','0','1','18446744073709551615','63','2','256','0','10',NULL,'1','0','211','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSubRace,RC_Undead,5; bonus2 bSubRace,RC_Demon,5;','','');
REPLACE INTO `item_db` VALUES ('5141','Marionette_Doll','Marionette Doll','5','0','20','10','400','0','0','0','0','1','18446744073709551614','63','2','256','0','30',NULL,'1','0','212','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,1;','','');
REPLACE INTO `item_db` VALUES ('5142','Crescent_Helm','Crescent Helm','5','0','20','10','3000','0','0','8','0','0','279714','63','2','768','0','50',NULL,'1','0','213','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVit,1; bonus2 bSubRace,RC_DemiPlayer,5;','','');
-REPLACE INTO `item_db` VALUES ('5143','Kabuki_Mask','Kabuki Mask','5','0','20','10','1000','0','0','5','0','1','18446744073709551614','63','1','769','0','30',NULL,'1','0','214','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bResEff,Eff_Silence,3000;','','');
+REPLACE INTO `item_db` VALUES ('5143','Kabuki_Mask','Kabuki Mask','5','0','20','10','1000','0','0','5','0','1','18446744073709551614','63','2','769','0','30',NULL,'1','0','214','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bResEff,Eff_Silence,3000;','','');
REPLACE INTO `item_db` VALUES ('5144','Gambler_Hat','Gambler Hat','5','0','20','10','200','0','0','2','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','16','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bLuk,5;','','');
REPLACE INTO `item_db` VALUES ('5145','Carnival_Joker_Jester','Carnival Joker Jester','5','0','10','5','100','0','0','0','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','89','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5146','Elephant_Hat','Elephant Hat','5','0','0','0','500','0','0','0','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','215','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVit,1; bonus2 bSubRace,RC_Brute,7; skill WZ_WATERBALL,1;','','');
@@ -2360,7 +2360,7 @@ REPLACE INTO `item_db` VALUES ('5161','Sharp_Gear_','Spiky Band','5','0','20','1
REPLACE INTO `item_db` VALUES ('5162','Bone_Helm_','Bone Helm','5','0','20','10','800','0','0','7','0','1','279714','63','2','256','0','70',NULL,'1','0','103','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSubEle,Ele_Dark,-15;','','');
REPLACE INTO `item_db` VALUES ('5163','Corsair_','Corsair','5','0','20','10','500','0','0','5','0','1','18446744073709551614','63','2','256','0','0',NULL,'1','0','105','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVit,1;','','');
REPLACE INTO `item_db` VALUES ('5164','Tiara_','Tiara','5','0','20','10','400','0','0','4','0','1','18446744073709551614','63','2','256','0','45',NULL,'1','0','19','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
-REPLACE INTO `item_db` VALUES ('5165','Crown_','Crown','5','0','20','10','400','0','0','4','0','1','18446744073709551614','63','1','256','0','45',NULL,'1','0','45','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
+REPLACE INTO `item_db` VALUES ('5165','Crown_','Crown','5','0','20','10','400','0','0','4','0','1','18446744073709551614','63','2','256','0','45',NULL,'1','0','45','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
REPLACE INTO `item_db` VALUES ('5166','Spinx_Helm_','Sphinx Hat','5','0','20','10','3000','0','0','5','0','1','16514','63','2','257','0','65',NULL,'0','0','137','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,2;','','');
REPLACE INTO `item_db` VALUES ('5167','Munak_Turban_','Munak Hat','5','0','20','10','300','0','0','5','0','1','18446744073709551615','63','2','769','0','0',NULL,'0','0','51','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSubRace,RC_Undead,10;','','');
REPLACE INTO `item_db` VALUES ('5168','Bongun_Hat_','Bongun Hat','5','0','20','10','300','0','0','5','0','1','18446744073709551615','63','2','769','0','0',NULL,'0','0','139','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -2549,7 +2549,7 @@ REPLACE INTO `item_db` VALUES ('5350','Pirate_Bandana_','Pirate Bandana','5','0'
REPLACE INTO `item_db` VALUES ('5351','Sunflower_','Sunflower','5','0','20','10','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'0','0','37','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSubRace,RC_Insect,10;','','');
REPLACE INTO `item_db` VALUES ('5352','Poporing_Cap','Poporing Cap','5','0','20','10','700','0','0','2','0','0','18446744073709551614','63','2','256','0','38',NULL,'1','0','361','0','0','0','0','73',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5353','Helm_Of_Sun_','Hat of the Sun God','5','0','20','10','2400','0','0','4','0','1','13623168','63','2','768','0','0',NULL,'1','0','138','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,3; bonus bInt,2;','','');
-REPLACE INTO `item_db` VALUES ('5354','Muslim_Hat_M','Muslim Hat M','5','0','0','0','100','0','0','2','0','0','18446744073709551615','63','1','256','0','0',NULL,'0','0','362','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bCastrate,-5;','','');
+REPLACE INTO `item_db` VALUES ('5354','Muslim_Hat_M','Muslim Hat M','5','0','0','0','100','0','0','2','0','0','18446744073709551615','63','2','256','0','0',NULL,'0','0','362','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bCastrate,-5;','','');
REPLACE INTO `item_db` VALUES ('5355','Muslim_Hat_F','Selendang','5','0','0','0','100','0','0','2','0','0','18446744073709551615','63','2','256','0','0',NULL,'0','0','363','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bCastrate,-5;','','');
REPLACE INTO `item_db` VALUES ('5356','Pumpkin_Hat_H','Festival Pumpkin Hat','5','0','20','10','200','0','0','2','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','206','0','0','0','0','384',NULL,'0',NULL,'0',NULL,'0','bonus2 bSubRace,RC_Demon,5; bonus2 bAddRace,RC_Demon,5;','','');
REPLACE INTO `item_db` VALUES ('5357','Wings_Of_Victory','Wings Of Victory','5','0','20','10','200','0','0','10','0','0','18446744073709551615','63','2','768','0','0',NULL,'0','0','365','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,10; bonus bUnbreakableHelm,0;','','');
@@ -7037,6 +7037,7 @@ REPLACE INTO `item_db` VALUES ('28763','Sharp_Wind_Sword','Sharp_Wind_Sword','3'
REPLACE INTO `item_db` VALUES ('28764','Fog_Dew_Sword','Fog_Dew_Sword','3','0','0','0','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','','','');
REPLACE INTO `item_db` VALUES ('28771','Ein_1HDAGGER','Ein_1HDAGGER','3','0','0','0','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','','','');
REPLACE INTO `item_db` VALUES ('28772','Ein_1HMAGGER','Ein_1HMAGGER','3','0','0','0','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','','','');
+REPLACE INTO `item_db` VALUES ('28900','Praetorian_Shield','Praetorian Shield','3','0','0','0','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','','','');
REPLACE INTO `item_db` VALUES ('28922','Herald_Of_GOD_IL','Herald_Of_GOD_IL','3','0','0','0','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','','','');
REPLACE INTO `item_db` VALUES ('28942','Bloody_Knight_Shield','Bloody_Knight_Shield','3','0','0','0','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','','','');
REPLACE INTO `item_db` VALUES ('28945','Bloody_Knight_Shield_','Bloody_Knight_Shield_','3','0','0','0','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','','','');
diff --git a/sql-files/item_db_re.sql b/sql-files/item_db_re.sql
index 89685a6c8..2f23e3f12 100644
--- a/sql-files/item_db_re.sql
+++ b/sql-files/item_db_re.sql
@@ -1380,10 +1380,10 @@ REPLACE INTO `item_db` VALUES ('2202','Sunglasses_','Sunglasses','5','0','5000',
REPLACE INTO `item_db` VALUES ('2203','Glasses','Glasses','5','0','4000','2000','100','0','0','0','0','0','18446744073709551615','63','2','512','0','0',NULL,'0','0','3','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2204','Glasses_','Glasses','5','0','4000','2000','100','0','0','0','0','1','18446744073709551615','63','2','512','0','0',NULL,'0','0','3','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2205','Divers_Goggles','Diver Goggles','5','0','3500','1750','100','0','0','0','0','0','18446744073709551615','63','2','512','0','0',NULL,'0','0','10','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
-REPLACE INTO `item_db` VALUES ('2206','Wedding_Veil','Wedding Veil','5','0','23000','11500','100','0','0','0','0','0','18446744073709551615','63','0','256','0','0',NULL,'1','0','44','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,5;','','');
+REPLACE INTO `item_db` VALUES ('2206','Wedding_Veil','Wedding Veil','5','0','23000','11500','100','0','0','0','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','44','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,5;','','');
REPLACE INTO `item_db` VALUES ('2207','Fancy_Flower','Fancy Flower','5','0','20','10','100','0','0','0','0','0','18446744073709551615','63','2','256','0','0',NULL,'0','0','4','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bAddRaceTolerance,RC_Plant,10;','','');
-REPLACE INTO `item_db` VALUES ('2208','Ribbon','Ribbon','5','0','800','400','100','0','0','1','0','0','18446744073709551615','63','0','256','0','0',NULL,'1','0','17','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('2209','Ribbon_','Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','0','256','0','0',NULL,'1','0','17','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('2208','Ribbon','Ribbon','5','0','800','400','100','0','0','1','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','17','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('2209','Ribbon_','Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','17','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
REPLACE INTO `item_db` VALUES ('2210','Hair_Band','Hairband','5','0','500','250','100','0','0','2','0','0','18446744073709551615','63','2','256','0','0',NULL,'0','0','9','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2211','Bandana','Bandana','5','0','400','200','100','0','0','2','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','6','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2212','Eye_Bandage','Eye Patch','5','0','1000','500','100','0','0','0','0','0','18446744073709551615','63','2','512','0','0',NULL,'0','0','13','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -1408,8 +1408,8 @@ REPLACE INTO `item_db` VALUES ('2230','Gemmed_Sallet','Gemmed Sallet','5','0','5
REPLACE INTO `item_db` VALUES ('2231','Gemmed_Sallet_','Gemmed Sallet','5','0','50000','25000','500','0','0','8','0','1','414946','63','2','256','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
REPLACE INTO `item_db` VALUES ('2232','Circlet','Circlet','5','0','7500','3750','300','0','0','6','0','0','8487700','63','2','256','0','0',NULL,'1','0','18','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
REPLACE INTO `item_db` VALUES ('2233','Circlet_','Circlet','5','0','7500','3750','300','0','0','6','0','1','8487700','63','2','256','0','0',NULL,'1','0','18','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('2234','Tiara','Tiara','5','0','20','10','400','0','0','7','0','0','18446744073709551614','63','0','256','0','45',NULL,'1','0','19','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,2;','','');
-REPLACE INTO `item_db` VALUES ('2235','Crown','Crown','5','0','20','10','400','0','0','7','0','0','18446744073709551614','63','1','256','0','45',NULL,'1','0','45','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,2;','','');
+REPLACE INTO `item_db` VALUES ('2234','Tiara','Tiara','5','0','20','10','400','0','0','7','0','0','18446744073709551614','63','2','256','0','45',NULL,'1','0','19','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,2;','','');
+REPLACE INTO `item_db` VALUES ('2235','Crown','Crown','5','0','20','10','400','0','0','7','0','0','18446744073709551614','63','2','256','0','45',NULL,'1','0','45','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,2;','','');
REPLACE INTO `item_db` VALUES ('2236','Santas_Hat','Santa Hat','5','0','20','10','100','0','0','2','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','20','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,1; bonus bLuk,1;','','');
REPLACE INTO `item_db` VALUES ('2237','Weird_Goatee','Bandit Beard','5','0','2','1','100','0','0','0','0','0','18446744073709551615','63','2','1','0','0',NULL,'0','0','21','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2238','Weird_Moustache','Moustache','5','0','2','1','100','0','0','0','0','0','18446744073709551615','63','2','1','0','0',NULL,'0','0','22','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -1579,7 +1579,7 @@ REPLACE INTO `item_db` VALUES ('2403','Shoes','Shoes','5','0','3500','1750','400
REPLACE INTO `item_db` VALUES ('2404','Shoes_','Shoes','5','0','3500','1750','400','0','0','10','0','1','18446744073709551614','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2405','Boots','Boots','5','0','18000','9000','600','0','0','16','0','0','24009962','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2406','Boots_','Boots','5','0','18000','9000','600','0','0','16','0','1','24009962','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
-REPLACE INTO `item_db` VALUES ('2407','Chrystal_Pumps','Crystal Pumps','5','0','20','10','100','0','0','5','0','0','18446744073709551614','63','0','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,10; bonus bLuk,5;','','');
+REPLACE INTO `item_db` VALUES ('2407','Chrystal_Pumps','Crystal Pumps','5','0','20','10','100','0','0','5','0','0','18446744073709551614','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,10; bonus bLuk,5;','','');
REPLACE INTO `item_db` VALUES ('2408','Cuffs','Shackles','5','0','5000','2500','3000','0','0','18','0','0','18446744073709551615','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2409','Spiky_Heel','High Heels','5','0','8500','4250','600','0','0','10','0','0','18446744073709551614','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,5;','','');
REPLACE INTO `item_db` VALUES ('2410','Sleipnir','Sleipnir','5','0','20','10','3500','0','0','40','0','0','18446744073709551615','63','2','64','0','94',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bUnbreakableShoes,0; bonus bMdef,10; bonus bMaxHPrate,20; bonus bMaxSPrate,20; bonus bSPrecovRate,25; bonus bSpeedRate,25; bonus bInt,25;','','');
@@ -1665,7 +1665,7 @@ REPLACE INTO `item_db` VALUES ('2489','Vidars_Boots_','Vidar\'s Boots','5','0','
REPLACE INTO `item_db` VALUES ('2491','Bangungot_Boots','Bangungot Boots of Nightmare','5','0','20','10','600','0','0','10','0','0','18446744073709551615','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,getrefine(); if(getrefine()>=14) { bonus bSpeedRate,25; }','','');
REPLACE INTO `item_db` VALUES ('2492','Bayani_Bangungot_Boots','Bangungot Boots(Bayani)','5','0','20','10','600','0','0','10','0','1','18446744073709551615','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,getrefine(); if(getrefine()>=12) { bonus bSpeedRate,25; }','','');
REPLACE INTO `item_db` VALUES ('2493','Goibnes_Combat_Boots_','Goibne\'s Greaves','5','0','30000','15000','700','0','0','13','0','1','18446744073709551614','63','2','64','0','54',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3; bonus bMaxHPrate,5; bonus bMaxSPrate,5;','','');
-REPLACE INTO `item_db` VALUES ('2494','Chrystal_Pumps_','Crystal Pumps','5','0','20','10','100','0','0','5','0','1','18446744073709551614','63','0','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,10; bonus bLuk,5;','','');
+REPLACE INTO `item_db` VALUES ('2494','Chrystal_Pumps_','Crystal Pumps','5','0','20','10','100','0','0','5','0','1','18446744073709551614','63','2','64','0','0',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,10; bonus bLuk,5;','','');
REPLACE INTO `item_db` VALUES ('2495','Egir_Shoes','Aegir Shoes','5','0','200000','100000','300','0','0','13','0','1','18446744073709551615','63','2','64','0','110',NULL,'1','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','if (BaseClass == Job_Mage || BaseClass == Job_Archer || BaseClass == Job_Acolyte) bonus bMaxHP, BaseLevel * 5; else if (BaseClass == Job_Swordman || BaseClass == Job_Merchant || BaseClass == Job_Thief) bonus bMaxSP, JobLevel * 2;','','');
REPLACE INTO `item_db` VALUES ('2496','TE_Woe_Shoes','TE WoE Shoes','5','0','0','0','0','0','0','5','0','0','18446744073709551615','63','2','64','0','40',NULL,'0','0','0','0','0','0','0','499',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,5; bonus bMaxHP,150; bonus bMaxSP,150; bonus2 bAddRace,RC_Player,5; bonus2 bMagicAddRace,RC_Player,5; bonus2 bResEff,Eff_Freeze,2500;','','');
REPLACE INTO `item_db` VALUES ('2497','TE_Woe_Boots','TE WoE Boots','5','0','0','0','0','0','0','10','0','0','279714','63','2','64','0','40',NULL,'0','0','0','0','0','0','0','499',NULL,'0',NULL,'0',NULL,'0','bonus bMaxHP,200; bonus bMaxSP,100; bonus2 bAddRace,RC_Player,10; bonus2 bResEff,Eff_Freeze,2500;','','');
@@ -1874,7 +1874,7 @@ REPLACE INTO `item_db` VALUES ('2704','Golden_Accessory','Golden Accessories','5
REPLACE INTO `item_db` VALUES ('2705','Golden_Accessory2','Golden Accessories','5','0','20','10','100','0','0','0','0','0','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','bonus2 bAddMonsterDropItem,12018,500;','','');
REPLACE INTO `item_db` VALUES ('2706','Handcuff','Arrest Handcuffs','5','0','0','0','0','0','0','0','0','0','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2707','GUSLI','Gusli','5','0','20','10','100','0','0','0','0','0','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','','','');
-REPLACE INTO `item_db` VALUES ('2708','Chinese_Handicraft','Chinese Handicraft','5','0','0','0','50','0','0','0','0','0','18446744073709551615','63','0','136','0','0',NULL,'0','0','0','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','bonus3 bAutoSpell,MG_FIREBOLT,5,300;','','');
+REPLACE INTO `item_db` VALUES ('2708','Chinese_Handicraft','Chinese Handicraft','5','0','0','0','50','0','0','0','0','0','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','bonus3 bAutoSpell,MG_FIREBOLT,5,300;','','');
REPLACE INTO `item_db` VALUES ('2709','5_Anniversary_Coin','5th Anniversary Coin','5','0','2','1','0','0','0','0','0','0','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','bonus bAtkRate,5; bonus bMatkRate,5;','','');
REPLACE INTO `item_db` VALUES ('2710','Bloody_Iron_Ball_C','Bloody Iron Ball','5','0','1','0','0','0','0','0','0','0','18446744073709551614','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','bonus bBaseAtk,30;','','');
REPLACE INTO `item_db` VALUES ('2711','Spiritual_Ring_C','Spiritual Ring','5','0','1','0','0','0','0','0','0','0','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','507',NULL,'0',NULL,'0',NULL,'0','bonus bInt,2; bonus bDex,2;','','');
@@ -2120,7 +2120,7 @@ REPLACE INTO `item_db` VALUES ('2971','Pocket_Watch__','Pocket Watch','5','0','2
REPLACE INTO `item_db` VALUES ('2981','RingOfHero','Brave Ring','5','0','20','10','200','0','0','0','0','0','18446744073709551615','63','2','136','0','160',NULL,'0','0','0','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('2986','Snake_Ring','Snake Ring','5','0','20','10','100','0','0','2','0','1','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bDex,3; bonus bMdef,2;','','');
REPLACE INTO `item_db` VALUES ('2987','Snake_Pendant','Snake Pendant','5','0','20','10','100','0','0','3','0','1','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAgi,3; bonus bLuk,2; bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('2988','Winged_Ring_Of_Newoz','Oz\'s New Wing Ring','5','0','62000','31000','100','0','0','0','0','1','524288','56','1','136','0','130',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVariableCastrate,-25;','','');
+REPLACE INTO `item_db` VALUES ('2988','Winged_Ring_Of_Newoz','Oz\'s New Wing Ring','5','0','62000','31000','100','0','0','0','0','1','524288','56','2','136','0','130',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVariableCastrate,-25;','','');
REPLACE INTO `item_db` VALUES ('2989','Floral_Bracelet_Of_Igu','Bloody Floral Decoration Bracelet','5','0','62000','31000','100','0','0','0','0','1','524288','56','2','136','0','130',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVariableCastrate,-25;','','');
REPLACE INTO `item_db` VALUES ('2997','RWC_Gold_Brooch','RWC Gold Brooch','5','0','0','0','200','0','0','0','0','1','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','bonus bAtk,20; bonus bMatk,20;','','');
REPLACE INTO `item_db` VALUES ('2999','RWC_Silver_Brooch','RWC Silver Brooch','5','0','0','0','200','0','0','0','0','0','18446744073709551615','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMaxHP,300; bonus bMaxSP,30;','','');
@@ -3267,8 +3267,8 @@ REPLACE INTO `item_db` VALUES ('5160','Magestic_Goat_','Magestic Goat','5','0','
REPLACE INTO `item_db` VALUES ('5161','Sharp_Gear_','Spiky Band','5','0','20','10','1000','0','0','12','0','1','6739442','63','2','256','0','50',NULL,'1','0','43','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5162','Bone_Helm_','Bone Helm','5','0','20','10','800','0','0','15','0','1','279714','63','2','256','0','70',NULL,'1','0','103','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSubEle,Ele_Dark,-15;','','');
REPLACE INTO `item_db` VALUES ('5163','Corsair_','Corsair','5','0','20','10','500','0','0','10','0','1','18446744073709551614','63','2','256','0','0',NULL,'1','0','105','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVit,1;','','');
-REPLACE INTO `item_db` VALUES ('5164','Tiara_','Tiara','5','0','20','10','400','0','0','7','0','1','18446744073709551614','63','0','256','0','45',NULL,'1','0','19','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
-REPLACE INTO `item_db` VALUES ('5165','Crown_','Crown','5','0','20','10','400','0','0','7','0','1','18446744073709551614','63','1','256','0','45',NULL,'1','0','45','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
+REPLACE INTO `item_db` VALUES ('5164','Tiara_','Tiara','5','0','20','10','400','0','0','7','0','1','18446744073709551614','63','2','256','0','45',NULL,'1','0','19','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
+REPLACE INTO `item_db` VALUES ('5165','Crown_','Crown','5','0','20','10','400','0','0','7','0','1','18446744073709551614','63','2','256','0','45',NULL,'1','0','45','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
REPLACE INTO `item_db` VALUES ('5166','Spinx_Helm_','Sphinx Hat','5','0','20','10','3000','0','0','5','0','1','16514','63','2','257','0','65',NULL,'0','0','137','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,2;','','');
REPLACE INTO `item_db` VALUES ('5167','Munak_Turban_','Munak Hat','5','0','20','10','300','0','0','5','0','1','18446744073709551615','63','2','769','0','0',NULL,'0','0','51','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bAddRaceTolerance,RC_Undead,10;','','');
REPLACE INTO `item_db` VALUES ('5168','Bongun_Hat_','Bongun Hat','5','0','20','10','300','0','0','5','0','1','18446744073709551615','63','2','769','0','0',NULL,'0','0','139','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -3294,14 +3294,14 @@ REPLACE INTO `item_db` VALUES ('5187','Twin_Ribbon','Twin Red Ribbon','5','0','2
REPLACE INTO `item_db` VALUES ('5188','Minstrel_Hat','Creative Convention Hat','5','0','20','10','500','0','0','4','0','0','18446744073709551615','63','2','256','0','50',NULL,'1','0','240','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1; bonus bDex,1;','','');
REPLACE INTO `item_db` VALUES ('5189','Fallen_Leaves','Autumn Leaves','5','0','20','10','100','0','0','0','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','241','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMaxHP,40; bonus bMaxSP,40;','','');
REPLACE INTO `item_db` VALUES ('5190','Baseball_Cap_','Independence Memorial Hat','5','0','20','10','20','0','0','5','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','216','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
-REPLACE INTO `item_db` VALUES ('5191','Ribbon_Black','Black Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','0','256','0','0',NULL,'1','0','242','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('5192','Ribbon_Yellow','Yellow Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','0','256','0','0',NULL,'1','0','243','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('5193','Ribbon_Green','Green Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','0','256','0','0',NULL,'1','0','244','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('5194','Ribbon_Pink','Pink Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','0','256','0','0',NULL,'1','0','245','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('5195','Ribbon_Red','Red Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','0','256','0','0',NULL,'1','0','246','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('5196','Ribbon_Orange','Orange Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','0','256','0','0',NULL,'1','0','247','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('5197','Ribbon_White','White Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','0','256','0','0',NULL,'1','0','248','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
-REPLACE INTO `item_db` VALUES ('5198','Drooping_Bunny','Evolved Drooping Bunny','5','0','10','5','100','0','0','3','0','0','18446744073709551615','63','0','256','0','0',NULL,'1','0','249','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bDex,1; bonus bFlee,2;','','');
+REPLACE INTO `item_db` VALUES ('5191','Ribbon_Black','Black Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','242','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5192','Ribbon_Yellow','Yellow Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','243','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5193','Ribbon_Green','Green Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','244','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5194','Ribbon_Pink','Pink Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','245','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5195','Ribbon_Red','Red Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','246','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5196','Ribbon_Orange','Orange Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','247','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5197','Ribbon_White','White Ribbon','5','0','800','400','100','0','0','1','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','248','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5198','Drooping_Bunny','Evolved Drooping Bunny','5','0','10','5','100','0','0','3','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','249','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bDex,1; bonus bFlee,2;','','');
REPLACE INTO `item_db` VALUES ('5199','Baseball_Cap_I','Baseball Cap','5','0','0','0','200','0','0','5','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','216','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5200','Coppola','Coppola','5','0','10','5','300','0','0','0','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','252','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5201','Party_Hat_B','Party Hat','5','0','20','10','300','0','0','4','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','144','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAllStats,3;','','');
@@ -3784,7 +3784,7 @@ REPLACE INTO `item_db` VALUES ('5677','Scorpio_Diadem','Scorpio Diadem','5','0',
REPLACE INTO `item_db` VALUES ('5678','Notation_Hairband','Musical Note Headband','5','0','200','100','100','0','0','5','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','607','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bUnbreakableHelm,0;','','');
REPLACE INTO `item_db` VALUES ('5679','Engineer_Cap','Engineer Cap','5','0','20','10','200','0','0','2','0','1','18446744073709551615','63','2','256','0','10',NULL,'1','0','608','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5680','Hawkeyes','Hawk Eye','5','0','20','10','100','0','0','0','0','0','18446744073709551615','63','2','512','0','10',NULL,'0','0','609','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bUnbreakableHelm,0;','','');
-REPLACE INTO `item_db` VALUES ('5681','F_Ribbon_Green','Green Ribbon','5','0','800','400','100','0','0','1','0','0','18446744073709551615','63','0','256','0','0',NULL,'1','0','244','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5681','F_Ribbon_Green','Green Ribbon','5','0','800','400','100','0','0','1','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','244','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
REPLACE INTO `item_db` VALUES ('5682','Triangle_Rune_Cap','Triangle Rune Cap','5','0','20','10','300','0','0','5','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','610','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
REPLACE INTO `item_db` VALUES ('5683','Majestic_Goat_Repl','Horn Of Arch Evil Model','5','0','20','10','100','0','0','5','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','41','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5684','Jewel_Crown_Repl','Luxurious Crown','5','0','20','10','100','0','0','5','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','88','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
@@ -3838,7 +3838,7 @@ REPLACE INTO `item_db` VALUES ('5731','E_Apple_OE_Archer_C','E Apple OE Archer C
REPLACE INTO `item_db` VALUES ('5732','E_Elven_Ears_C','E Elven Ears C','5','0','1','0','0','0','0','2','0','0','18446744073709551614','63','2','512','0','0',NULL,'0','0','73','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bInt,1;','','');
REPLACE INTO `item_db` VALUES ('5733','E_Brooch_C','E Brooch C','5','0','1','0','0','0','0','0','0','0','18446744073709551614','63','2','136','0','0',NULL,'0','0','0','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bAgi,4;','','');
REPLACE INTO `item_db` VALUES ('5734','E_Magestic_Goat_C','E Magestic Goat C','5','0','2','1','0','0','0','5','0','0','18446744073709551614','63','2','256','0','0',NULL,'0','0','41','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,1;','','');
-REPLACE INTO `item_db` VALUES ('5735','E_Ribbon_Green','E Ribbon Green','5','0','800','400','100','0','0','1','0','0','18446744073709551615','63','0','256','0','0',NULL,'1','0','244','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
+REPLACE INTO `item_db` VALUES ('5735','E_Ribbon_Green','E Ribbon Green','5','0','800','400','100','0','0','1','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','244','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,3;','','');
REPLACE INTO `item_db` VALUES ('5736','EF_Whisper_Mask','EF Whisper Mask','5','0','20','10','0','0','0','0','0','0','18446744073709551615','63','2','769','0','0',NULL,'0','0','321','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bUnbreakableHelm,0; bonus bAgi,3; bonus2 bSubEle,Ele_Ghost,-10;','','');
REPLACE INTO `item_db` VALUES ('5737','Cactus_Hat','Potted Muka Hat','5','0','20','10','300','0','0','1','0','0','18446744073709551615','63','2','256','0','0',NULL,'0','0','615','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','skill SM_PROVOKE,3;','','');
REPLACE INTO `item_db` VALUES ('5738','Snowman_Hat','Snowman Hat','5','0','20','10','300','0','0','4','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','616','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,1; bonus bInt,1; bonus bMdef,3; bonus2 bSubEle,Ele_Water,7; bonus2 bAddMonsterDropItem,530,100; bonus2 bAddMonsterDropItem,12354,300; if(getrefine()>7) { bonus5 bAutoSpellWhenHit,BA_FROSTJOKER,5,20,BF_WEAPON|BF_MAGIC,0; } else { bonus5 bAutoSpellWhenHit,BA_FROSTJOKER,1,20,BF_WEAPON|BF_MAGIC,0; }','','');
@@ -3908,7 +3908,7 @@ REPLACE INTO `item_db` VALUES ('5801','Ribbon_Of_Bride','Red Tailed Ribbon','5',
REPLACE INTO `item_db` VALUES ('5802','Upgrade_Elephant_Hat','Upgrade Elephant Hat','5','0','0','0','500','0','0','6','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','215','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5803','Flower_Love_Hat','Love Flower Hat','5','0','20','10','100','0','0','4','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','5','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bAddMonsterDropItem,608,100;','','');
REPLACE INTO `item_db` VALUES ('5804','Pirate_Eyepatch','Pirate Eye Bandage','5','0','1000','500','100','0','0','0','0','0','18446744073709551615','63','2','512','0','0',NULL,'0','0','13','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
-REPLACE INTO `item_db` VALUES ('5805','Victorious_Coronet','Victorious Coronet','5','0','0','0','150','0','0','2','0','0','18446744073709551615','63','0','256','0','70',NULL,'0','0','43','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','bonus bMaxHPrate,15; bonus bSPrecovRate,5;','','');
+REPLACE INTO `item_db` VALUES ('5805','Victorious_Coronet','Victorious Coronet','5','0','0','0','150','0','0','2','0','0','18446744073709551615','63','2','256','0','70',NULL,'0','0','43','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','bonus bMaxHPrate,15; bonus bSPrecovRate,5;','','');
REPLACE INTO `item_db` VALUES ('5806','Poem_Natalia_Hat','Poem Natalia Hat','5','0','20','10','300','0','0','9','0','0','18446744073709551615','63','2','256','0','0',NULL,'0','0','67','0','0','0','0','475',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5807','October_Fest_Cap','October Fest Cap','5','0','20','10','100','0','0','2','0','0','18446744073709551614','63','2','256','0','50',NULL,'1','0','104','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('5808','Diabolus_Helmet','Dark Bacilium','5','0','20','10','250','0','0','5','0','1','1040256','58','2','769','0','0',NULL,'1','0','364','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bResEff,Eff_Stone,2000+(getrefine()*200); bonus2 bResEff,Eff_Freeze,2000+(getrefine()*200); bonus2 bResEff,Eff_Stun,2000+(getrefine()*200);','','');
@@ -3977,7 +3977,7 @@ REPLACE INTO `item_db` VALUES ('5898','Autumn_Headband','Autumn Headband','5','0
REPLACE INTO `item_db` VALUES ('5899','Black_Ribbon_','Black Ribbon','5','0','0','0','200','0','0','10','0','1','128','56','2','256','0','100',NULL,'1','0','1120','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSkillAtk,RK_WINDCUTTER,50; bonus2 bSkillAtk,RK_SONICWAVE,50; if(getrefine()>=7) { bonus bAtk,2*(readparam(bAgi)/5); } if(getrefine()>=9) { bonus2 bSkillAtk,RK_IGNITIONBREAK,30; }','','');
REPLACE INTO `item_db` VALUES ('5900','Divine_Guard_Hat_','Divine Guard Hat','5','0','20','10','200','0','0','10','0','1','16384','56','2','256','0','100',NULL,'1','0','1121','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSubSize,Size_Medium,5; bonus2 bSubSize,Size_Large,5; bonus2 bSubSize,Size_Small,5; if(getrefine()>6) { bonus5 bAutoSpellWhenHit,AL_HEAL,max(getskilllv(AL_HEAL),5),100,BF_WEAPON,0; } if(getrefine()>8) { bonus2 bSkillAtk,LG_RAYOFGENESIS,20; }','','');
REPLACE INTO `item_db` VALUES ('5904','Inconspicuous_Hat_','Inconspicuous Hat','5','0','20','10','200','0','0','10','0','1','131072','56','2','256','0','100',NULL,'1','0','1125','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMatkRate,7; if(getrefine()>6) { bonus bMatk,(readparam(bInt)/5)*2; } if(getrefine()>8) { bonus bMatkRate,5; }','','');
-REPLACE INTO `item_db` VALUES ('5905','Lyrica_Hat_','Lyrica Hat','5','0','20','10','200','0','0','10','0','1','524288','56','1','256','0','100',NULL,'1','0','1126','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSkillAtk,WM_SEVERE_RAINSTORM_MELEE,15; if(getrefine()>6) { bonus bFixedCastrate,-(getskilllv(BA_MUSICALLESSON)*4); } if(getrefine()>8) { bonus2 bSkillUseSP,WM_SEVERE_RAINSTORM,10; }','','');
+REPLACE INTO `item_db` VALUES ('5905','Lyrica_Hat_','Lyrica Hat','5','0','20','10','200','0','0','10','0','1','524288','56','2','256','0','100',NULL,'1','0','1126','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSkillAtk,WM_SEVERE_RAINSTORM_MELEE,15; if(getrefine()>6) { bonus bFixedCastrate,-(getskilllv(BA_MUSICALLESSON)*4); } if(getrefine()>8) { bonus2 bSkillUseSP,WM_SEVERE_RAINSTORM,10; }','','');
REPLACE INTO `item_db` VALUES ('5906','Oni_Horns','Oni Horns','5','0','20','10','200','0','0','10','0','1','4096','56','2','256','0','100',NULL,'1','0','1127','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSkillAtk,GC_COUNTERSLASH,getskilllv(GC_WEAPONBLOCKING)*10; if(getrefine()>6) { bonus bAtk,10; bonus bHit,5; } if(getrefine()>8) { bonus3 bAutoSpell,GC_CROSSIMPACT,1,100; }','','');
REPLACE INTO `item_db` VALUES ('5907','Sea_Captain_Hat_','Sea Captain Hat','5','0','20','10','200','0','0','20','0','1','1024','56','2','256','0','100',NULL,'1','0','1128','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus2 bSkillAtk,NC_AXETORNADO,20; bonus2 bSkillAtk,NC_AXEBOOMERANG,20; if(getrefine()>6) { bonus2 bSkillAtk,NC_AXETORNADO,getskilllv(BS_WEAPONRESEARCH); } if(getrefine()>8) { bonus2 bSkillAtk,NC_AXETORNADO,getskilllv(NC_TRAININGAXE); }','','');
REPLACE INTO `item_db` VALUES ('5918','Gambler_Seal','Gambler Seal','5','0','20','10','500','0','0','0','0','0','18446744073709551615','63','2','512','0','70',NULL,'0','0','1202','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bCritical,3; bonus bCritAtkRate,3;','','');
@@ -8748,7 +8748,7 @@ REPLACE INTO `item_db` VALUES ('18576','YinYang_Earring','Yin Yang Earrings','5'
REPLACE INTO `item_db` VALUES ('18577','24_Bolt','Screw Stuck Head','5','0','20','10','200','0','0','0','0','0','18446744073709551615','63','2','512','0','10',NULL,'0','0','696','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('18578','Helm_Of_Valor','Helm Of Valor','5','0','0','0','0','0','0','4','0','0','18446744073709551615','63','2','256','0','0',NULL,'0','0','258','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','','','');
REPLACE INTO `item_db` VALUES ('18579','9th_Anni_Hat','kRO 9 Anniversary Hat','5','0','0','0','90','0','0','0','0','0','18446744073709551615','63','2','256','0','0',NULL,'1','0','745','0','0','0','0','467',NULL,'0',NULL,'0',NULL,'0','bonus bUnbreakableHelm,0; bonus bMdef,9;','','');
-REPLACE INTO `item_db` VALUES ('18580','Yggdrasil_Crown','Yggdrasil Crown','5','0','20','10','200','0','0','3','0','1','18446744073709551615','63','1','256','0','0',NULL,'1','0','746','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVit,2; bonus bInt,2; bonus bHealPower,1; bonus bHealPower2,1; if(getrefine() >= 7) { bonus bHealPower,5; } if(getrefine() >= 9) { bonus bHealPower,3; }','','');
+REPLACE INTO `item_db` VALUES ('18580','Yggdrasil_Crown','Yggdrasil Crown','5','0','20','10','200','0','0','3','0','1','18446744073709551615','63','2','256','0','0',NULL,'1','0','746','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bVit,2; bonus bInt,2; bonus bHealPower,1; bonus bHealPower2,1; if(getrefine() >= 7) { bonus bHealPower,5; } if(getrefine() >= 9) { bonus bHealPower,3; }','','');
REPLACE INTO `item_db` VALUES ('18581','Red_Tiger_Mask','Red Tiger Mask','5','0','20','10','400','0','0','2','0','0','18446744073709551615','63','2','768','0','50',NULL,'0','0','747','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,3;','','');
REPLACE INTO `item_db` VALUES ('18582','Blue_Tiger_Mask','Blue Tiger Mask','5','0','20','10','400','0','0','2','0','0','18446744073709551615','63','2','768','0','50',NULL,'0','0','748','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bStr,3;','','');
REPLACE INTO `item_db` VALUES ('18583','Navy_Drooping_Kitty','Navy Drooping Kitty','5','0','250000','125000','500','0','0','3','0','0','18446744073709551614','63','2','256','0','0',NULL,'1','0','749','0','0','0','0','0',NULL,'0',NULL,'0',NULL,'0','bonus bMdef,15;','','');
diff --git a/sql-files/mob_db.sql b/sql-files/mob_db.sql
index 2fdd722a1..68f365d7b 100644
--- a/sql-files/mob_db.sql
+++ b/sql-files/mob_db.sql
@@ -1095,3 +1095,4 @@ REPLACE INTO `mob_db` VALUES (2081,'E_HYDRA','Suspicious Hydra','Strange Hydra',
REPLACE INTO `mob_db` VALUES (2082,'G_PIRANHA','Piranha','Piranha',75,4522,1,0,0,1,182,223,2,10,69,45,30,30,66,35,10,12,1,5,61,12949,200,768,768,384,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (2210,'XMAS_LUNATIC','Xmas Lunatic','Xmas Lunatic',1,100,1,0,0,1,1,1,0,0,10,1,1,1,1,1,10,12,0,2,20,131,200,1456,456,336,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
REPLACE INTO `mob_db` VALUES (2308,'KO_KAGE','Zanzou','Zanzou',1,50,1,0,0,1,1,1,0,0,1,1,1,1,1,1,1,1,1,7,20,0,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
+REPLACE INTO `mob_db` VALUES (2248,'GOLDPORING','Golden Poring','Golden Poring',1,15,1,0,0,0,0,0,127,5,1,1,1,1,999,1,10,12,1,3,21,129,400,1872,672,480,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
diff --git a/src/char/char.c b/src/char/char.c
index c61b6107a..b3de22c00 100644
--- a/src/char/char.c
+++ b/src/char/char.c
@@ -2535,19 +2535,39 @@ static void char_changesex(int account_id, int sex)
}
/**
- * Performs the necessary operations when changing a character's sex, such as
- * correcting the job class and unequipping items, and propagating the
- * information to the guild data.
+ * Performs the necessary operations when changing a character's gender,
+ * such as correcting the job class and unequipping items,
+ * and propagating the information to the guild data.
*
- * @param sex The new sex (SEX_MALE or SEX_FEMALE).
- * @param acc The character's account ID.
- * @param char_id The character ID.
- * @param class The character's current job class.
+ * @param sex The character's new gender (SEX_MALE or SEX_FEMALE).
+ * @param acc The character's account ID.
+ * @param char_id The character ID.
+ * @param class The character's current job class.
* @param guild_id The character's guild ID.
- */
+ *
+ **/
static void char_change_sex_sub(int sex, int acc, int char_id, int class, int guild_id)
{
- // job modification
+ struct SqlStmt *stmt = SQL->StmtMalloc(inter->sql_handle);
+
+ /** If we can't save the data, there's nothing to do. **/
+ if (stmt == NULL) {
+ SqlStmt_ShowDebug(stmt);
+ return;
+ }
+
+ const char *query_inv = "UPDATE `%s` SET `equip`='0' WHERE `char_id`=?";
+
+ /** Don't change gender if resetting the view data fails to prevent character from being unable to login. **/
+ if (SQL_ERROR == SQL->StmtPrepare(stmt, query_inv, inventory_db)
+ || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT32, &char_id, sizeof(char_id))
+ || SQL_ERROR == SQL->StmtExecute(stmt)) {
+ SqlStmt_ShowDebug(stmt);
+ SQL->StmtFree(stmt);
+ return;
+ }
+
+ /** Correct the job class for gender specific jobs according to the passed gender. **/
if (class == JOB_BARD || class == JOB_DANCER)
class = (sex == SEX_MALE ? JOB_BARD : JOB_DANCER);
else if (class == JOB_CLOWN || class == JOB_GYPSY)
@@ -2563,14 +2583,30 @@ static void char_change_sex_sub(int sex, int acc, int char_id, int class, int gu
else if (class == JOB_KAGEROU || class == JOB_OBORO)
class = (sex == SEX_MALE ? JOB_KAGEROU : JOB_OBORO);
- if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `equip`='0' WHERE `char_id`='%d'", inventory_db, char_id))
- Sql_ShowDebug(inter->sql_handle);
+#if PACKETVER >= 20141016
+ char gender = (sex == SEX_MALE) ? 'M' : ((sex == SEX_FEMALE) ? 'F' : 'U');
+#else
+ char gender = 'U';
+#endif
- if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `class`='%d', `weapon`='0', `shield`='0', "
- "`head_top`='0', `head_mid`='0', `head_bottom`='0' WHERE `char_id`='%d'",
- char_db, class, char_id))
- Sql_ShowDebug(inter->sql_handle);
- if (guild_id) // If there is a guild, update the guild_member data [Skotlex]
+ const char *query_char = "UPDATE `%s` SET `class`=?, `weapon`='0', `shield`='0', `head_top`='0', "
+ "`head_mid`='0', `head_bottom`='0', `robe`='0', `sex`=? WHERE `char_id`=?";
+
+ /** Don't update guild data if changing gender fails to prevent data de-synchronisation. **/
+ if (SQL_ERROR == SQL->StmtPrepare(stmt, query_char, char_db)
+ || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT32, &class, sizeof(class))
+ || SQL_ERROR == SQL->StmtBindParam(stmt, 1, SQLDT_ENUM, &gender, sizeof(gender))
+ || SQL_ERROR == SQL->StmtBindParam(stmt, 2, SQLDT_INT32, &char_id, sizeof(char_id))
+ || SQL_ERROR == SQL->StmtExecute(stmt)) {
+ SqlStmt_ShowDebug(stmt);
+ SQL->StmtFree(stmt);
+ return;
+ }
+
+ SQL->StmtFree(stmt);
+
+ /** Update guild member data if a guild ID was passed. **/
+ if (guild_id != 0)
inter_guild->sex_changed(guild_id, acc, char_id, sex);
}
@@ -3504,45 +3540,68 @@ static void char_ask_name_ack(int fd, int acc, const char *name, int type, int r
}
/**
- * Changes a character's sex.
- * The information is updated on database, and the character is kicked if it
- * currently is online.
+ * Changes a character's gender.
+ * The information is updated on database, and the character is kicked if it currently is online.
*
- * @param char_id The character's ID.
- * @param sex The new sex.
+ * @param char_id The character ID
+ * @param sex The character's new gender (SEX_MALE or SEX_FEMALE).
* @retval 0 in case of success.
* @retval 1 in case of failure.
- */
+ *
+ **/
static int char_changecharsex(int char_id, int sex)
{
- int class = 0, guild_id = 0, account_id = 0;
- char *data;
+ struct SqlStmt *stmt = SQL->StmtMalloc(inter->sql_handle);
- // get character data
- if (SQL_ERROR == SQL->Query(inter->sql_handle, "SELECT `account_id`,`class`,`guild_id` FROM `%s` WHERE `char_id` = '%d'", char_db, char_id)) {
- Sql_ShowDebug(inter->sql_handle);
+ /** If we can't load the data, there's nothing to do. **/
+ if (stmt == NULL) {
+ SqlStmt_ShowDebug(stmt);
return 1;
}
- if (SQL->NumRows(inter->sql_handle) != 1 || SQL_ERROR == SQL->NextRow(inter->sql_handle)) {
- SQL->FreeResult(inter->sql_handle);
+
+ const char *query = "SELECT `account_id`, `class`, `guild_id` FROM `%s` WHERE `char_id`=?";
+ int account_id = 0;
+ int class = 0;
+ int guild_id = 0;
+
+ /** Abort changing gender if there was an error while loading the data. **/
+ if (SQL_ERROR == SQL->StmtPrepare(stmt, query, char_db)
+ || SQL_ERROR == SQL->StmtBindParam(stmt, 0, SQLDT_INT32, &char_id, sizeof(char_id))
+ || SQL_ERROR == SQL->StmtExecute(stmt)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 0, SQLDT_INT32, &account_id, sizeof(account_id), NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 1, SQLDT_INT32, &class, sizeof(class), NULL, NULL)
+ || SQL_ERROR == SQL->StmtBindColumn(stmt, 2, SQLDT_INT32, &guild_id, sizeof(guild_id), NULL, NULL)) {
+ SqlStmt_ShowDebug(stmt);
+ SQL->StmtFree(stmt);
return 1;
}
- SQL->GetData(inter->sql_handle, 0, &data, NULL); account_id = atoi(data);
- SQL->GetData(inter->sql_handle, 1, &data, NULL); class = atoi(data);
- SQL->GetData(inter->sql_handle, 2, &data, NULL); guild_id = atoi(data);
- SQL->FreeResult(inter->sql_handle);
- if (SQL_ERROR == SQL->Query(inter->sql_handle, "UPDATE `%s` SET `sex` = '%c' WHERE `char_id` = '%d'", char_db, sex == SEX_MALE ? 'M' : 'F', char_id)) {
- Sql_ShowDebug(inter->sql_handle);
+ /** Abort changing gender if no character was found. **/
+ if (SQL->StmtNumRows(stmt) < 1) {
+ ShowError("char_changecharsex: Requested non-existant character! (ID: %d)\n", char_id);
+ SQL->StmtFree(stmt);
return 1;
}
- char_change_sex_sub(sex, account_id, char_id, class, guild_id);
- // disconnect player if online on char-server
- chr->disconnect_player(account_id);
+ /** Abort changing gender if more than one character was found. **/
+ if (SQL->StmtNumRows(stmt) > 1) {
+ ShowError("char_changecharsex: There are multiple characters with identical ID! (ID: %d)\n", char_id);
+ SQL->StmtFree(stmt);
+ return 1;
+ }
+
+ /** Abort changing gender if fetching the data fails. **/
+ if (SQL_ERROR == SQL->StmtNextRow(stmt)) {
+ SqlStmt_ShowDebug(stmt);
+ SQL->StmtFree(stmt);
+ return 1;
+ }
+
+ SQL->StmtFree(stmt);
+ char_change_sex_sub(sex, account_id, char_id, class, guild_id);
+ chr->disconnect_player(account_id); // Disconnect player if online on char-server.
+ chr->changesex(account_id, sex); // Notify all mapservers about this change.
- // notify all mapservers about this change
- chr->changesex(account_id, sex);
return 0;
}
diff --git a/src/char/int_party.c b/src/char/int_party.c
index c16eea34e..62633b4a8 100644
--- a/src/char/int_party.c
+++ b/src/char/int_party.c
@@ -67,6 +67,7 @@ static int inter_party_check_lv(struct party_data *p)
if (p->party.exp == 1 && inter_party->check_exp_share(p) == 0) {
p->party.exp = 0;
mapif->party_optionchanged(0, &p->party, 0, 0);
+ inter_party->tosql(&p->party, PS_BASIC, 0);
return 0;
}
@@ -577,9 +578,9 @@ static bool inter_party_leave(int party_id, int account_id, int char_id)
if (p->party.member[i].online == 1)
p->party.member[i].online = 0;
+ inter_party->tosql(&p->party, PS_DELMEMBER, i);
memset(&p->party.member[i], 0, sizeof(struct party_member));
inter_party->calc_state(p); /// Count online/offline members and check family state and even share range.
- inter_party->tosql(&p->party, PS_DELMEMBER, i);
if (inter_party->check_empty(p) == 0)
mapif->party_info(-1, &p->party, 0);
diff --git a/src/common/atomic.h b/src/common/atomic.h
index 518d2e6ab..b9157373f 100644
--- a/src/common/atomic.h
+++ b/src/common/atomic.h
@@ -103,8 +103,9 @@ forceinline volatile int64 InterlockedExchange64(volatile int64 *target, int64 v
// The __sync functions are available on x86 or ARMv6+
#if !defined(__x86_64__) && !defined(__i386__) \
+ && !defined(__ppc64__) && ! defined(__powerpc64__) \
&& ( !defined(__ARM_ARCH_VERSION__) || __ARM_ARCH_VERSION__ < 6 )
-#error Your Target Platfrom is not supported
+#error Target platform currently not supported
#endif
static forceinline int64 InterlockedExchangeAdd64(volatile int64 *addend, int64 increment){
diff --git a/src/common/cbasetypes.h b/src/common/cbasetypes.h
index 31d89d66b..06333a7b2 100644
--- a/src/common/cbasetypes.h
+++ b/src/common/cbasetypes.h
@@ -62,16 +62,24 @@
#endif
// Standardize the ARM platform version, if available (the only values we're interested in right now are >= ARMv6)
+#ifdef __ARM_ARCH
+#define __ARM_ARCH_VERSION__ __ARM_ARCH
+#else
#if defined(__ARMV6__) || defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || defined(__ARM_ARCH_6K__) \
|| defined(__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) || defined(__ARM_ARCH_6T2__) // gcc ARMv6
#define __ARM_ARCH_VERSION__ 6
-#elif defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__) // gcc ARMv7
+#elif defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || defined(__ARM_ARCH_7M__) || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7S__) // gcc ARMv7
#define __ARM_ARCH_VERSION__ 7
+#elif defined(__ARM_ARCH_8__) || defined(__ARM_ARCH_8A__)
+#define __ARM_ARCH_VERSION__ 8
#elif defined(_M_ARM) // MSVC
#define __ARM_ARCH_VERSION__ _M_ARM
+#elif defined(__TARGET_ARCH_ARM) // RVCT
+#define __ARM_ARCH_VERSION__ __TARGET_ARCH_ARM
#else
#define __ARM_ARCH_VERSION__ 0
#endif
+#endif
// Necessary for __NetBSD_Version__ (defined as VVRR00PP00) on NetBSD
#ifdef __NETBSD__
diff --git a/src/common/hercules.h b/src/common/hercules.h
index 89ea761b4..e62656494 100644
--- a/src/common/hercules.h
+++ b/src/common/hercules.h
@@ -23,11 +23,15 @@
#include "config/core.h"
#include "common/cbasetypes.h"
+#ifdef HERCULES_CORE
+#define HPExport static
+#else // HERCULES_CORE
#ifdef WIN32
- #define HPExport __declspec(dllexport)
-#else
- #define HPExport __attribute__((visibility("default")))
-#endif
+#define HPExport __declspec(dllexport)
+#else // WIN32
+#define HPExport __attribute__((visibility("default")))
+#endif // WIN32
+#endif // HERCULES_CORE
#define HPShared extern
diff --git a/src/common/packets/packets2020_len_main.h b/src/common/packets/packets2020_len_main.h
index 4b7273775..215f59727 100644
--- a/src/common/packets/packets2020_len_main.h
+++ b/src/common/packets/packets2020_len_main.h
@@ -4675,5 +4675,35 @@ packetLen(0x0b79, -1)
packetLen(0x0b7a, -1)
#endif
+// Packet: 0x0b7b
+#if PACKETVER >= 20200701
+packetLen(0x0b7b, 118)
+#endif
+
+// Packet: 0x0b7c
+#if PACKETVER >= 20200701
+packetLen(0x0b7c, -1)
+#endif
+
+// Packet: 0x0b7d
+#if PACKETVER >= 20200701
+packetLen(0x0b7d, -1)
+#endif
+
+// Packet: 0x0b7e
+#if PACKETVER >= 20200701
+packetLen(0x0b7e, 60)
+#endif
+
+// Packet: 0x0b7f
+#if PACKETVER >= 20200701
+packetLen(0x0b7f, 10)
+#endif
+
+// Packet: 0x0b80
+#if PACKETVER >= 20200701
+packetLen(0x0b80, 10)
+#endif
+
#endif /* COMMON_PACKETS2020_LEN_MAIN_H */
diff --git a/src/common/packets/packets2020_len_re.h b/src/common/packets/packets2020_len_re.h
index 2c21b1c67..7296d86c5 100644
--- a/src/common/packets/packets2020_len_re.h
+++ b/src/common/packets/packets2020_len_re.h
@@ -4623,7 +4623,9 @@ packetLen(0x0b6f, 177)
#endif
// Packet: 0x0b70
-#if PACKETVER >= 20200122
+#if PACKETVER >= 20200709
+packetLen(0x0b70, -1)
+#elif PACKETVER >= 20200122
packetLen(0x0b70, 8)
#endif
@@ -4633,7 +4635,9 @@ packetLen(0x0b71, 177)
#endif
// Packet: 0x0b72
-#if PACKETVER >= 20200122
+#if PACKETVER >= 20200709
+packetLen(0x0b72, -1)
+#elif PACKETVER >= 20200122
packetLen(0x0b72, 4)
#endif
@@ -4652,5 +4656,60 @@ packetLen(0x0b74, 1026)
packetLen(0x0b75, 1026)
#endif
+// Packet: 0x0b76
+#if PACKETVER >= 20200709
+packetLen(0x0b76, 77)
+#endif
+
+// Packet: 0x0b77
+#if PACKETVER >= 20200709
+packetLen(0x0b77, -1)
+#endif
+
+// Packet: 0x0b78
+#if PACKETVER >= 20200709
+packetLen(0x0b78, -1)
+#endif
+
+// Packet: 0x0b79
+#if PACKETVER >= 20200709
+packetLen(0x0b79, -1)
+#endif
+
+// Packet: 0x0b7a
+#if PACKETVER >= 20200709
+packetLen(0x0b7a, -1)
+#endif
+
+// Packet: 0x0b7b
+#if PACKETVER >= 20200709
+packetLen(0x0b7b, 118)
+#endif
+
+// Packet: 0x0b7c
+#if PACKETVER >= 20200709
+packetLen(0x0b7c, -1)
+#endif
+
+// Packet: 0x0b7d
+#if PACKETVER >= 20200709
+packetLen(0x0b7d, -1)
+#endif
+
+// Packet: 0x0b7e
+#if PACKETVER >= 20200709
+packetLen(0x0b7e, 60)
+#endif
+
+// Packet: 0x0b7f
+#if PACKETVER >= 20200709
+packetLen(0x0b7f, 10)
+#endif
+
+// Packet: 0x0b80
+#if PACKETVER >= 20200709
+packetLen(0x0b80, 10)
+#endif
+
#endif /* COMMON_PACKETS2020_LEN_RE_H */
diff --git a/src/common/packets/packets2020_len_zero.h b/src/common/packets/packets2020_len_zero.h
index 2aa2ccc96..cba80e90c 100644
--- a/src/common/packets/packets2020_len_zero.h
+++ b/src/common/packets/packets2020_len_zero.h
@@ -4675,5 +4675,35 @@ packetLen(0x0b79, -1)
packetLen(0x0b7a, -1)
#endif
+// Packet: 0x0b7b
+#if PACKETVER >= 20200701
+packetLen(0x0b7b, 118)
+#endif
+
+// Packet: 0x0b7c
+#if PACKETVER >= 20200701
+packetLen(0x0b7c, -1)
+#endif
+
+// Packet: 0x0b7d
+#if PACKETVER >= 20200701
+packetLen(0x0b7d, -1)
+#endif
+
+// Packet: 0x0b7e
+#if PACKETVER >= 20200701
+packetLen(0x0b7e, 60)
+#endif
+
+// Packet: 0x0b7f
+#if PACKETVER >= 20200701
+packetLen(0x0b7f, 10)
+#endif
+
+// Packet: 0x0b80
+#if PACKETVER >= 20200701
+packetLen(0x0b80, 10)
+#endif
+
#endif /* COMMON_PACKETS2020_LEN_ZERO_H */
diff --git a/src/login/login.c b/src/login/login.c
index 623457b8a..32c935d75 100644
--- a/src/login/login.c
+++ b/src/login/login.c
@@ -1758,7 +1758,7 @@ static bool login_config_read_permission_hash(const char *filename, struct confi
static void login_clear_dnsbl_servers(void)
{
while (VECTOR_LENGTH(login->config->dnsbl_servers) > 0) {
- aFree(&VECTOR_POP(login->config->dnsbl_servers));
+ aFree(VECTOR_POP(login->config->dnsbl_servers));
}
VECTOR_CLEAR(login->config->dnsbl_servers);
}
diff --git a/src/map/atcommand.c b/src/map/atcommand.c
index 76448b237..9fb2540ef 100644
--- a/src/map/atcommand.c
+++ b/src/map/atcommand.c
@@ -1168,17 +1168,17 @@ ACMD(item)
memset(item_name, '\0', sizeof(item_name));
- if (!strcmpi(info->command,"itembound") && (!*message || (
- sscanf(message, "\"%99[^\"]\" %12d %12d", item_name, &number, &bound) < 2 &&
- sscanf(message, "%99s %12d %12d", item_name, &number, &bound) < 2
- ))) {
- clif->message(fd, msg_fd(fd,295)); // Please enter an item name or ID (usage: @itembound <item name/ID> <quantity> <bound_type>).
+ if (!strcmpi(info->command, "itembound") && (!*message || (
+ sscanf(message, "\"%99[^\"]\" %12d %12d", item_name, &number, &bound) < 1 &&
+ sscanf(message, "%99s %12d %12d", item_name, &number, &bound) < 1
+ ))) {
+ clif->message(fd, msg_fd(fd, 295)); // Please enter an item name or ID (usage: @itembound <item name/ID> <quantity> <bound_type>).
return false;
} else if (!*message
- || ( sscanf(message, "\"%99[^\"]\" %12d", item_name, &number) < 1
- && sscanf(message, "%99s %12d", item_name, &number) < 1
- )) {
- clif->message(fd, msg_fd(fd,983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
+ || (sscanf(message, "\"%99[^\"]\" %12d", item_name, &number) < 1
+ && sscanf(message, "%99s %12d", item_name, &number) < 1
+ )) {
+ clif->message(fd, msg_fd(fd, 983)); // Please enter an item name or ID (usage: @item <item name/ID> <quantity>).
return false;
}
@@ -1186,33 +1186,33 @@ ACMD(item)
number = 1;
if ((item_data = itemdb->search_name(item_name)) == NULL &&
- (item_data = itemdb->exists(atoi(item_name))) == NULL)
+ (item_data = itemdb->exists(atoi(item_name))) == NULL)
{
- clif->message(fd, msg_fd(fd,19)); // Invalid item ID or name.
+ clif->message(fd, msg_fd(fd, 19)); // Invalid item ID or name.
return false;
}
- if(!strcmpi(info->command,"itembound") ) {
- if( !(bound >= IBT_MIN && bound <= IBT_MAX) ) {
- clif->message(fd, msg_fd(fd,298)); // Invalid bound type
+ if (!strcmpi(info->command, "itembound")) {
+ if (!(bound >= IBT_MIN && bound <= IBT_MAX)) {
+ clif->message(fd, msg_fd(fd, 298)); // Invalid bound type
return false;
}
- switch( (enum e_item_bound_type)bound ) {
- case IBT_CHARACTER:
- case IBT_ACCOUNT:
- break; /* no restrictions */
- case IBT_PARTY:
- if( !sd->status.party_id ) {
- clif->message(fd, msg_fd(fd,1498)); //You can't add a party bound item to a character without party!
- return false;
- }
- break;
- case IBT_GUILD:
- if( !sd->status.guild_id ) {
- clif->message(fd, msg_fd(fd,1499)); //You can't add a guild bound item to a character without guild!
- return false;
- }
- break;
+ switch ((enum e_item_bound_type)bound) {
+ case IBT_CHARACTER:
+ case IBT_ACCOUNT:
+ break; /* no restrictions */
+ case IBT_PARTY:
+ if (!sd->status.party_id) {
+ clif->message(fd, msg_fd(fd, 1498)); //You can't add a party bound item to a character without party!
+ return false;
+ }
+ break;
+ case IBT_GUILD:
+ if (!sd->status.guild_id) {
+ clif->message(fd, msg_fd(fd, 1499)); //You can't add a guild bound item to a character without guild!
+ return false;
+ }
+ break;
}
}
@@ -1220,8 +1220,8 @@ ACMD(item)
get_count = number;
//Check if it's stackable.
if (!itemdb->isstackable2(item_data)) {
- if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) ) {
- clif->message(fd, msg_fd(fd,498)); // Cannot create bounded pet eggs or pet armors.
+ if (bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR)) {
+ clif->message(fd, msg_fd(fd, 498)); // Cannot create bounded pet eggs or pet armors.
return false;
}
get_count = 1;
@@ -1241,7 +1241,7 @@ ACMD(item)
}
if (flag == 0)
- clif->message(fd, msg_fd(fd,18)); // Item created.
+ clif->message(fd, msg_fd(fd, 18)); // Item created.
return true;
}
@@ -1254,37 +1254,37 @@ ACMD(item2)
struct item_data *item_data;
char item_name[100];
int item_id, number = 0, bound = 0;
- int identify = 0, refine_level = 0, attr = 0;
+ int identify = 1, refine_level = 0, attr = ATTR_NONE;
int c1 = 0, c2 = 0, c3 = 0, c4 = 0;
memset(item_name, '\0', sizeof(item_name));
- if (!strcmpi(info->command,"itembound2") && (!*message || (
+ if (!strcmpi(info->command, "itembound2") && (!*message || (
sscanf(message, "\"%99[^\"]\" %12d %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine_level, &attr, &c1, &c2, &c3, &c4, &bound) < 10 &&
- sscanf(message, "%99s %12d %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine_level, &attr, &c1, &c2, &c3, &c4, &bound) < 10 ))) {
- clif->message(fd, msg_fd(fd,296)); // Please enter all parameters (usage: @itembound2 <item name/ID> <quantity>
- clif->message(fd, msg_fd(fd,297)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
+ sscanf(message, "%99s %12d %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine_level, &attr, &c1, &c2, &c3, &c4, &bound) < 10))) {
+ clif->message(fd, msg_fd(fd, 296)); // Please enter all parameters (usage: @itembound2 <item name/ID> <quantity>
+ clif->message(fd, msg_fd(fd, 297)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4> <bound_type>).
return false;
} else if (!*message
- || ( sscanf(message, "\"%99[^\"]\" %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine_level, &attr, &c1, &c2, &c3, &c4) < 9
- && sscanf(message, "%99s %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine_level, &attr, &c1, &c2, &c3, &c4) < 9
- )) {
- clif->message(fd, msg_fd(fd,984)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
- clif->message(fd, msg_fd(fd,985)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4>).
+ || (sscanf(message, "\"%99[^\"]\" %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine_level, &attr, &c1, &c2, &c3, &c4) < 1
+ && sscanf(message, "%99s %12d %12d %12d %12d %12d %12d %12d %12d", item_name, &number, &identify, &refine_level, &attr, &c1, &c2, &c3, &c4) < 1
+ )) {
+ clif->message(fd, msg_fd(fd, 984)); // Please enter all parameters (usage: @item2 <item name/ID> <quantity>
+ clif->message(fd, msg_fd(fd, 985)); // <identify_flag> <refine> <attribute> <card1> <card2> <card3> <card4>).
return false;
}
if (number <= 0)
number = 1;
- if( !strcmpi(info->command,"itembound2") && !(bound >= IBT_MIN && bound <= IBT_MAX) ) {
- clif->message(fd, msg_fd(fd,298)); // Invalid bound type
+ if (!strcmpi(info->command, "itembound2") && !(bound >= IBT_MIN && bound <= IBT_MAX)) {
+ clif->message(fd, msg_fd(fd, 298)); // Invalid bound type
return false;
}
item_id = 0;
if ((item_data = itemdb->search_name(item_name)) != NULL ||
- (item_data = itemdb->exists(atoi(item_name))) != NULL)
+ (item_data = itemdb->exists(atoi(item_name))) != NULL)
item_id = item_data->nameid;
if (item_id > 500) {
@@ -1292,11 +1292,11 @@ ACMD(item2)
int loop, get_count, i;
loop = 1;
get_count = number;
- if( !strcmpi(info->command,"itembound2") )
- bound = 1;
- if( !itemdb->isstackable2(item_data) ) {
- if( bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR) ) {
- clif->message(fd, msg_fd(fd,498)); // Cannot create bounded pet eggs or pet armors.
+ if (!strcmpi(info->command, "itembound2"))
+ bound = IBT_ACCOUNT;
+ if (!itemdb->isstackable2(item_data)) {
+ if (bound && (item_data->type == IT_PETEGG || item_data->type == IT_PETARMOR)) {
+ clif->message(fd, msg_fd(fd, 498)); // Cannot create bounded pet eggs or pet armors.
return false;
}
loop = number;
@@ -1309,7 +1309,8 @@ ACMD(item2)
refine_level = 0;
} else {
identify = 1;
- refine_level = attr = 0;
+ refine_level = 0;
+ attr = ATTR_NONE;
}
refine_level = cap_value(refine_level, 0, MAX_REFINE);
for (i = 0; i < loop; i++) {
@@ -1329,9 +1330,9 @@ ACMD(item2)
}
if (flag == 0)
- clif->message(fd, msg_fd(fd,18)); // Item created.
+ clif->message(fd, msg_fd(fd, 18)); // Item created.
} else {
- clif->message(fd, msg_fd(fd,19)); // Invalid item ID or name.
+ clif->message(fd, msg_fd(fd, 19)); // Invalid item ID or name.
return false;
}
@@ -2810,10 +2811,8 @@ ACMD(petfriendly)
return false;
}
- if (friendly != pd->pet.intimate) { // No need to update the pet's status if intimacy value won't change.
+ if (friendly != pd->pet.intimate) // No need to update the pet's status if intimacy value won't change.
pet->set_intimate(pd, friendly);
- clif->send_petstatus(sd);
- }
clif->message(fd, msg_fd(fd, 182)); // Pet intimacy changed. (Send message regardless of value has changed or not.)
@@ -2854,10 +2853,8 @@ ACMD(pethungry)
return false;
}
- if (hungry != pd->pet.hungry) { // No need to update the pet's status if hunger value won't change.
- pd->pet.hungry = hungry;
- clif->send_petstatus(sd);
- }
+ if (hungry != pd->pet.hungry) // No need to update the pet's status if hunger value won't change.
+ pet->set_hunger(pd, hungry);
clif->message(fd, msg_fd(fd, 185)); // Pet hunger changed. (Send message regardless of value has changed or not.)
@@ -2881,6 +2878,15 @@ ACMD(petrename)
}
pd->pet.rename_flag = 0;
+
+ int i;
+
+ ARR_FIND(0, sd->status.inventorySize, i, sd->status.inventory[i].card[0] == CARD0_PET
+ && pd->pet.pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
+
+ if (i != sd->status.inventorySize)
+ sd->status.inventory[i].card[3] = pet->get_card4_value(pd->pet.rename_flag, pd->pet.intimate);
+
intif->save_petdata(sd->status.account_id, &pd->pet);
clif->send_petstatus(sd);
clif->message(fd, msg_fd(fd,187)); // You can now rename your pet.
@@ -4096,6 +4102,8 @@ ACMD(mapinfo)
strcat(atcmd_output, msg_fd(fd, 1292)); // PrivateAirshipStartable |
if (map->list[m_id].flag.pairship_endable)
strcat(atcmd_output, msg_fd(fd, 1293)); // PrivateAirshipEndable |
+ if (map->list[m_id].flag.nopet != 0)
+ strcat(atcmd_output, msg_fd(fd, 853)); // NoPet |
clif->message(fd, atcmd_output);
switch (list) {
@@ -8562,7 +8570,7 @@ ACMD(itemlist)
if( it->card[0] == CARD0_PET ) {
// pet egg
- if (it->card[3])
+ if ((it->card[3] & 1) != 0)
StrBuf->Printf(&buf, msg_fd(fd,1348), (unsigned int)MakeDWord(it->card[1], it->card[2])); // -> (pet egg, pet id: %u, named)
else
StrBuf->Printf(&buf, msg_fd(fd,1349), (unsigned int)MakeDWord(it->card[1], it->card[2])); // -> (pet egg, pet id: %u, unnamed)
diff --git a/src/map/battle.c b/src/map/battle.c
index 611154953..a571a555d 100644
--- a/src/map/battle.c
+++ b/src/map/battle.c
@@ -7100,7 +7100,7 @@ static const struct battle_data {
{ "pet_max_stats", &battle_config.pet_max_stats, 99, 0, INT_MAX, },
{ "pet_max_atk1", &battle_config.pet_max_atk1, 750, 0, INT_MAX, },
{ "pet_max_atk2", &battle_config.pet_max_atk2, 1000, 0, INT_MAX, },
- { "pet_disable_in_gvg", &battle_config.pet_no_gvg, 0, 0, 1, },
+ { "pet_remove_immediately", &battle_config.pet_remove_immediately, 1, 0, 1, },
{ "skill_min_damage", &battle_config.skill_min_damage, 2|4, 0, 1|2|4, },
{ "finger_offensive_type", &battle_config.finger_offensive_type, 0, 0, 1, },
{ "heal_exp", &battle_config.heal_exp, 0, 0, INT_MAX, },
@@ -7345,6 +7345,7 @@ static const struct battle_data {
{ "searchstore_querydelay", &battle_config.searchstore_querydelay, 10, 0, INT_MAX, },
{ "searchstore_maxresults", &battle_config.searchstore_maxresults, 30, 1, INT_MAX, },
{ "display_party_name", &battle_config.display_party_name, 0, 0, 1, },
+ { "send_party_options", &battle_config.send_party_options, 0x31F9, 0, 0x1FFFF, },
{ "cashshop_show_points", &battle_config.cashshop_show_points, 0, 0, 1, },
{ "mail_show_status", &battle_config.mail_show_status, 0, 0, 2, },
{ "client_limit_unit_lv", &battle_config.client_limit_unit_lv, 0, 0, BL_ALL, },
@@ -7378,12 +7379,12 @@ static const struct battle_data {
{ "item_restricted_consumption_type", &battle_config.item_restricted_consumption_type,1, 0, 1, },
{ "unequip_restricted_equipment", &battle_config.unequip_restricted_equipment, 0, 0, 3, },
{ "max_walk_path", &battle_config.max_walk_path, 17, 1, MAX_WALKPATH, },
- { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, INT_MAX, },
+ { "item_enabled_npc", &battle_config.item_enabled_npc, 1, 0, 3, },
{ "gm_ignore_warpable_area", &battle_config.gm_ignore_warpable_area, 0, 2, 100, },
{ "packet_obfuscation", &battle_config.packet_obfuscation, 1, 0, 3, },
{ "client_accept_chatdori", &battle_config.client_accept_chatdori, 0, 0, INT_MAX, },
{ "snovice_call_type", &battle_config.snovice_call_type, 0, 0, 1, },
- { "guild_notice_changemap", &battle_config.guild_notice_changemap, 2, 0, 2, },
+ { "guild_notice_changemap", &battle_config.guild_notice_changemap, 7, 0, 7, },
{ "features/banking", &battle_config.feature_banking, 1, 0, 1, },
{ "features/auction", &battle_config.feature_auction, 0, 0, 2, },
{ "idletime_criteria", &battle_config.idletime_criteria, 0x25, 1, INT_MAX, },
@@ -7431,6 +7432,10 @@ static const struct battle_data {
{ "ping_time", &battle_config.ping_time, 20, 0, 99999999, },
{ "option_drop_max_loop", &battle_config.option_drop_max_loop, 10, 1, 100000, },
{ "drop_connection_on_quit", &battle_config.drop_connection_on_quit, 0, 0, 1, },
+ { "display_rate_messages", &battle_config.display_rate_messages, 1, 0, 7, },
+ { "display_config_messages", &battle_config.display_config_messages, 0x1F1, 0, 0x1F7, },
+ { "display_overweight_messages", &battle_config.display_overweight_messages, 3, 0, 3, },
+ { "show_tip_window", &battle_config.show_tip_window, 1, 0, 1, },
{ "features/enable_refinery_ui", &battle_config.enable_refinery_ui, 1, 0, 1, },
{ "features/replace_refine_npcs", &battle_config.replace_refine_npcs, 1, 0, 1, },
{ "batk_min_limit", &battle_config.batk_min, 0, 0, INT_MAX, },
@@ -7449,6 +7454,8 @@ static const struct battle_data {
{ "hit_max_limit", &battle_config.hit_max, SHRT_MAX, 1, INT_MAX, },
{ "autoloot_adjust", &battle_config.autoloot_adjust, 0, 0, 1, },
{ "hom_bonus_exp_from_master", &battle_config.hom_bonus_exp_from_master, 10, 0, 100, },
+ { "allowed_actions_when_dead", &battle_config.allowed_actions_when_dead, 0, 0, 3, },
+ { "teleport_close_storage", &battle_config.teleport_close_storage, 1, 0, 1, },
};
static bool battle_set_value_sub(int index, int value)
@@ -7681,6 +7688,8 @@ static void do_init_battle(bool minimal)
static void do_final_battle(void)
{
+ if (map->minimal)
+ return;
ers_destroy(battle->delay_damage_ers);
}
diff --git a/src/map/battle.h b/src/map/battle.h
index 55ee32445..abf4c0f68 100644
--- a/src/map/battle.h
+++ b/src/map/battle.h
@@ -228,8 +228,8 @@ struct Battle_Config {
int pet_max_stats; //[Skotlex]
int pet_max_atk1; //[Skotlex]
int pet_max_atk2; //[Skotlex]
- int pet_no_gvg; //Disables pets in gvg. [Skotlex]
int pet_equip_required;
+ int pet_remove_immediately;
int skill_min_damage;
int finger_offensive_type;
@@ -471,6 +471,7 @@ struct Battle_Config {
int searchstore_querydelay;
int searchstore_maxresults;
int display_party_name;
+ int send_party_options;
int cashshop_show_points;
int mail_show_status;
int client_limit_unit_lv;
@@ -590,6 +591,10 @@ struct Battle_Config {
int option_drop_max_loop;
int drop_connection_on_quit;
+ int display_rate_messages;
+ int display_config_messages;
+ int display_overweight_messages;
+ int show_tip_window;
int enable_refinery_ui;
int replace_refine_npcs;
@@ -609,6 +614,8 @@ struct Battle_Config {
int hit_max;
int autoloot_adjust;
+ int allowed_actions_when_dead;
+ int teleport_close_storage;
};
/* criteria for battle_config.idletime_critera */
diff --git a/src/map/buyingstore.c b/src/map/buyingstore.c
index 2c2fc13ae..fd6e6fd6e 100644
--- a/src/map/buyingstore.c
+++ b/src/map/buyingstore.c
@@ -91,8 +91,9 @@ static void buyingstore_create(struct map_session_data *sd, int zenylimit, unsig
return;
}
- if( !battle_config.feature_buying_store || pc_istrading(sd) || sd->state.prevend || sd->buyingstore.slots == 0 || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || !storename[0] )
- {// disabled or invalid input
+ if (battle_config.feature_buying_store == 0 || pc_istrading_except_npc(sd) || sd->state.prevend != 0
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->buyingstore.slots == 0
+ || count > sd->buyingstore.slots || zenylimit <= 0 || zenylimit > sd->status.zeny || *storename == '\0') { // Disabled or invalid input.
sd->buyingstore.slots = 0;
clif->buyingstore_open_failed(sd, BUYINGSTORE_CREATE, 0);
return;
@@ -218,8 +219,8 @@ static void buyingstore_open(struct map_session_data *sd, int account_id)
struct map_session_data* pl_sd;
nullpo_retv(sd);
- if (!battle_config.feature_buying_store || pc_istrading(sd) || sd->state.prevend)
- {// not allowed to sell
+ if (battle_config.feature_buying_store == 0 || pc_istrading_except_npc(sd) || sd->state.prevend != 0
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) { // Not allowed to sell.
return;
}
@@ -255,8 +256,8 @@ static void buyingstore_trade(struct map_session_data* sd, int account_id, unsig
return;
}
- if (!battle_config.feature_buying_store || pc_istrading(sd) || sd->state.prevend)
- {// not allowed to sell
+ if (battle_config.feature_buying_store == 0 || pc_istrading_except_npc(sd) || sd->state.prevend != 0
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) { // Not allowed to sell.
clif->buyingstore_trade_failed_seller(sd, BUYINGSTORE_TRADE_SELLER_FAILED, 0);
return;
}
diff --git a/src/map/clif.c b/src/map/clif.c
index 649df3e33..f44d9a716 100644
--- a/src/map/clif.c
+++ b/src/map/clif.c
@@ -1596,10 +1596,33 @@ static bool clif_spawn(struct block_list *bl)
clif->specialeffect(bl,421,AREA);
if (sd->bg_id != 0 && map->list[sd->bl.m].flag.battleground)
clif->sendbgemblem_area(sd);
- for (i = 0; i < sd->sc_display_count; i++) {
- clif->sc_continue(&sd->bl, sd->bl.id, AREA, status->get_sc_icon(sd->sc_display[i]->type), sd->sc_display[i]->val1, sd->sc_display[i]->val2, sd->sc_display[i]->val3);
+ struct status_change *sc = status->get_sc(bl);
+
+ if (sd->sc_display_count > 0 && sc != NULL) {
+ for (i = 0; i < sd->sc_display_count; i++) {
+ enum sc_type type = sd->sc_display[i]->type;
+
+ if (sc->data[type] == NULL)
+ continue;
+
+ int tick = 0;
+ int tid = sc->data[type]->timer;
+ const struct TimerData *td = (tid > 0) ? timer->get(tid) : NULL;
+
+ if (td != NULL)
+ tick = DIFF_TICK32(td->tick, timer->gettick());
+
+ int sc_icon = status->get_sc_icon(type);
+ int sc_types = status->get_sc_relevant_bl_types(type);
+ int val1 = sd->sc_display[i]->val1;
+ int val2 = sd->sc_display[i]->val2;
+ int val3 = sd->sc_display[i]->val3;
+
+ clif->status_change(&sd->bl, sc_icon, sc_types, 1, tick, val1, val2, val3);
+ }
}
+
if (sd->charm_type != CHARM_TYPE_NONE && sd->charm_count > 0)
clif->spiritcharm(sd);
if (sd->status.look.robe != 0)
@@ -2431,23 +2454,26 @@ static void clif_scriptinput(struct map_session_data *sd, int npcid)
/// - close inputstr window
static void clif_scriptinputstr(struct map_session_data *sd, int npcid)
{
- int fd;
- struct block_list *bl = NULL;
-
nullpo_retv(sd);
- if (!sd->state.using_fake_npc && (npcid == npc->fake_nd->bl.id || ((bl = map->id2bl(npcid)) != NULL && (bl->m!=sd->bl.m ||
- bl->x<sd->bl.x-AREA_SIZE-1 || bl->x>sd->bl.x+AREA_SIZE+1 ||
- bl->y<sd->bl.y-AREA_SIZE-1 || bl->y>sd->bl.y+AREA_SIZE+1))))
+ struct block_list *bl = map->id2bl(npcid);
+ int x1 = sd->bl.x - AREA_SIZE - 1;
+ int x2 = sd->bl.x + AREA_SIZE + 1;
+ int y1 = sd->bl.y - AREA_SIZE - 1;
+ int y2 = sd->bl.y + AREA_SIZE + 1;
+ bool out_of_sight = (bl != NULL && (bl->m != sd->bl.m || bl->x < x1 || bl->x > x2 || bl->y < y1 || bl->y > y2));
+
+ if (sd->state.using_fake_npc == 0 && sd->state.using_megaphone == 0
+ && (npcid == npc->fake_nd->bl.id || out_of_sight)) {
clif->sendfakenpc(sd, npcid);
+ }
pc->update_idle_time(sd, BCIDLE_SCRIPT);
- fd=sd->fd;
- WFIFOHEAD(fd, packet_len(0x1d4));
- WFIFOW(fd,0)=0x1d4;
- WFIFOL(fd,2)=npcid;
- WFIFOSET(fd,packet_len(0x1d4));
+ WFIFOHEAD(sd->fd, packet_len(0x1d4));
+ WFIFOW(sd->fd, 0) = 0x1d4;
+ WFIFOL(sd->fd, 2) = (sd->state.using_megaphone == 0) ? npcid : 0;
+ WFIFOSET(sd->fd, packet_len(0x1d4));
}
/// Marks a position on client's minimap (ZC_COMPASS).
@@ -2519,8 +2545,8 @@ static void clif_addcards(struct EQUIPSLOTINFO *buf, struct item *item)
if (item->card[0] == CARD0_PET) { //pet eggs
buf->card[0] = 0;
buf->card[1] = 0;
- buf->card[2] = 0;
- buf->card[3] = item->card[3]; //Pet renamed flag.
+ buf->card[2] = (item->card[3] >> 1); // Pet intimacy level.
+ buf->card[3] = (item->card[3] & 1); // Pet renamed flag.
return;
}
if (item->card[0] == CARD0_FORGE || item->card[0] == CARD0_CREATE) { //Forged/created items
@@ -7292,46 +7318,101 @@ static void clif_party_inviteack(struct map_session_data *sd, const char *nick,
#endif
}
-/// Updates party settings.
-/// 0101 <exp option>.L (ZC_GROUPINFO_CHANGE)
-/// 07d8 <exp option>.L <item pick rule>.B <item share rule>.B (ZC_REQ_GROUPINFO_CHANGE_V2)
-/// exp option:
-/// 0 = exp sharing disabled
-/// 1 = exp sharing enabled
-/// 2 = cannot change exp sharing
-///
-/// flag:
-/// 0 = send to party
-/// 1 = send to sd
+/**
+ * Sends party settings to the client.
+ *
+ * 0101 <exp option>.L (ZC_GROUPINFO_CHANGE)
+ * 07d8 <exp option>.L <item pick rule>.B <item share rule>.B (ZC_REQ_GROUPINFO_CHANGE_V2)
+ * <exp option>:
+ * 0 = EXP sharing disabled.
+ * 1 = EXP sharing enabled.
+ * 2 = Cannot change EXP sharing.
+ *
+ * @param p The related party.
+ * @param sd The related character.
+ * @param flag Reason for sending.
+ * @parblock
+ * Possible flags:
+ * 0x01 = Cannot change EXP sharing. (Only set when tried to change options manually.)
+ * 0x02 = Options changed manually.
+ * 0x04 = Options changed automatically.
+ * 0x08 = Member added.
+ * 0x10 = Member removed.
+ * 0x20 = Character logged in.
+ * 0x40 = Character changed map.
+ * 0x80 = Character teleported.
+ * @endparblock
+ *
+ **/
static void clif_party_option(struct party_data *p, struct map_session_data *sd, int flag)
{
- unsigned char buf[16];
+ nullpo_retv(p);
+
+ if (sd == NULL && (flag & 0x01) == 0) {
+ for (int i = 0; i < MAX_PARTY; i++) {
+ if (p->data[i].sd != NULL) {
+ sd = p->data[i].sd;
+ break;
+ }
+ }
+ }
+
+ if (sd == NULL)
+ return;
+
+ int conf = battle_config.send_party_options;
+
+ if (((flag & 0x01) != 0 && (conf & 0x10) == 0)
+ || ((flag & 0x02) != 0 && (conf & 0x08) == 0)
+ || ((flag & 0x04) != 0 && (conf & 0x20) == 0)
+ || ((flag & 0x08) != 0 && (conf & 0x40) == 0)
+ || ((flag & 0x10) != 0 && (conf & 0x80) == 0)
+ || ((flag & 0x20) != 0 && (conf & 0x01) == 0)
+ || ((flag & 0x40) != 0 && (conf & 0x02) == 0)
+ || ((flag & 0x80) != 0 && (conf & 0x04) == 0)) {
+ return;
+ }
+
+ enum send_target target = SELF;
+
+ if (((flag & 0x01) != 0 && (conf & 0x100) != 0)
+ || ((flag & 0x01) == 0 && (flag & 0x02) != 0)
+ || (flag & 0x04) != 0) {
+ target = PARTY;
+ }
+
+ int cmd = 0x101;
+
+ if (((flag & 0x01) != 0 && (conf & 0x02000) != 0)
+ || ((flag & 0x02) != 0 && (conf & 0x01000) != 0)
+ || ((flag & 0x04) != 0 && (conf & 0x04000) != 0)
+ || ((flag & 0x08) != 0 && (conf & 0x08000) != 0)
+ || ((flag & 0x10) != 0 && (conf & 0x10000) != 0)
+ || ((flag & 0x20) != 0 && (conf & 0x00200) != 0)
+ || ((flag & 0x40) != 0 && (conf & 0x00400) != 0)
+ || ((flag & 0x80) != 0 && (conf & 0x00800) != 0)) {
+ cmd = 0x7d8;
+ }
+
#if PACKETVER < 20090603
- const int cmd = 0x101;
-#else
- const int cmd = 0x7d8;
+ if (cmd == 0x7d8)
+ cmd = 0x101;
#endif
- nullpo_retv(p);
+ unsigned char buf[16];
- if(!sd && flag==0){
- int i;
- for(i=0;i<MAX_PARTY && !p->data[i].sd;i++)
- ;
- if (i < MAX_PARTY)
- sd = p->data[i].sd;
+ WBUFW(buf, 0) = cmd;
+ WBUFL(buf, 2) = ((flag & 0x10) != 0) ? 0 : (((flag & 0x01) != 0) ? 2 : p->party.exp);
+
+ if (cmd == 0x7d8) {
+ WBUFB(buf, 6) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 1) != 0) ? 1 : 0);
+ WBUFB(buf, 7) = ((flag & 0x10) != 0) ? 0 : (((p->party.item & 2) != 0) ? 1 : 0);
}
- if(!sd) return;
- WBUFW(buf,0)=cmd;
- WBUFL(buf,2)=((flag&0x01)?2:p->party.exp);
-#if PACKETVER >= 20090603
- WBUFB(buf,6)=(p->party.item&1)?1:0;
- WBUFB(buf,7)=(p->party.item&2)?1:0;
-#endif
- if(flag==0)
- clif->send(buf,packet_len(cmd),&sd->bl,PARTY);
- else
- clif->send(buf,packet_len(cmd),&sd->bl,SELF);
+
+ clif->send(buf, packet_len(cmd), &sd->bl, target);
+
+ if ((flag & 0x04) != 0)
+ p->state.option_auto_changed = 0;
}
/// 0105 <account id>.L <char name>.24B <result>.B (ZC_DELETE_MEMBER_FROM_GROUP).
@@ -7580,8 +7661,8 @@ static void clif_sendegg(struct map_session_data *sd)
nullpo_retv(sd);
fd = sd->fd;
- if (battle_config.pet_no_gvg && map_flag_gvg2(sd->bl.m)) { //Disable pet hatching in GvG grounds during Guild Wars [Skotlex]
- clif->message(fd, msg_sd(sd, 866)); // "Pets are not allowed in Guild Wars."
+ if (map->list[sd->bl.m].flag.nopet != 0) {
+ clif->message(fd, msg_sd(sd, 866)); // "Pets are disabled in this map."
return;
}
@@ -10613,6 +10694,97 @@ static void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
}
/**
+ * Displays the common server messages upon login, chaning maps or teleporting to a character.
+ *
+ * @param sd The character who should receive the messages.
+ * @param connect_new Whether the character is logging in.
+ * @param change_map Whether the character is changing maps.
+ *
+ **/
+static void clif_load_end_ack_sub_messages(struct map_session_data *sd, bool connect_new, bool change_map)
+{
+ nullpo_retv(sd);
+
+ /** Display overweight messages. **/
+ if (((battle_config.display_overweight_messages & 0x1) != 0 && connect_new)
+ || ((battle_config.display_overweight_messages & 0x2) != 0 && !connect_new && change_map)) {
+ // Send the character's weight to the client. (With displaying overweight messages.)
+ clif->updatestatus(sd, SP_MAXWEIGHT);
+ clif->updatestatus(sd, SP_WEIGHT);
+ } else {
+ // Send the character's weight to the client. (Without displaying overweight messages.)
+ clif->updatestatus(sd, SP_WEIGHT);
+ clif->updatestatus(sd, SP_MAXWEIGHT);
+ }
+
+ /** Display configuration messages. **/
+ if (((battle_config.display_config_messages & 0x1) != 0 && connect_new)
+ || ((battle_config.display_config_messages & 0x2) != 0 && !connect_new && change_map)
+ || (battle_config.display_config_messages & 0x4) != 0) {
+#if PACKETVER >= 20070918
+ if ((battle_config.display_config_messages & 0x10) != 0)
+ clif->partyinvitationstate(sd);
+
+ if ((battle_config.display_config_messages & 0x20) != 0)
+ clif->equpcheckbox(sd);
+#endif
+
+#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920
+ if ((battle_config.display_config_messages & 0x40) != 0)
+ clif->zc_config(sd, CZ_CONFIG_CALL, sd->status.allow_call);
+
+ if ((battle_config.display_config_messages & 0x80) != 0) {
+ if (sd->pd != NULL)
+ clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, sd->pd->pet.autofeed);
+ else
+ clif->zc_config(sd, CZ_CONFIG_PET_AUTOFEEDING, false);
+ }
+
+ if ((battle_config.display_config_messages & 0x100) != 0) {
+ if (sd->hd != NULL)
+ clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed);
+ else
+ clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false);
+ }
+#endif
+ }
+
+ /** Display party options. **/
+ struct party_data *p = NULL;
+
+ if (sd->status.party_id != 0 && (p = party->search(sd->status.party_id)) != NULL) {
+ int flag;
+
+ if (p->state.option_auto_changed != 0)
+ flag = 0x04;
+ else if (connect_new)
+ flag = 0x20;
+ else if (change_map)
+ flag = 0x40;
+ else
+ flag = 0x80;
+
+ clif->party_option(p, sd, flag);
+ }
+
+ /** Display rate modifier messages. **/
+ if (((battle_config.display_rate_messages & 0x1) != 0 && connect_new)
+ || ((battle_config.display_rate_messages & 0x2) != 0 && !connect_new && change_map)
+ || (battle_config.display_rate_messages & 0x4) != 0) {
+ clif->show_modifiers(sd);
+ }
+
+ /** Display guild notice. **/
+ if (sd->guild != NULL) {
+ if (((battle_config.guild_notice_changemap & 0x1) != 0 && connect_new)
+ || ((battle_config.guild_notice_changemap & 0x2) != 0 && !connect_new && change_map)
+ || (battle_config.guild_notice_changemap & 0x4) != 0) {
+ clif->guild_notice(sd, sd->guild);
+ }
+ }
+}
+
+/**
* Notification from the client, that it has finished map loading and is about to display player's character. (CZ_NOTIFY_ACTORINIT)
*
* @code
@@ -10626,6 +10798,9 @@ static void clif_parse_WantToConnection(int fd, struct map_session_data *sd)
static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
{
+ if (sd->state.using_megaphone != 0)
+ sd->state.using_megaphone = 0;
+
if (sd->bl.prev != NULL)
return;
@@ -10732,10 +10907,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
// Check for and delete unavailable/disabled items.
pc->checkitem(sd);
- // Send the character's weight to the client.
- clif->updatestatus(sd, SP_WEIGHT);
- clif->updatestatus(sd, SP_MAXWEIGHT);
-
// Send character's guild info to the client. Call this before clif->spawn() to show guild emblems correctly.
if (sd->status.guild_id != 0)
guild->send_memberinfoshort(sd, 1);
@@ -10764,9 +10935,18 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
map->addblock(&sd->bl); // Add the character to the map.
clif->spawn(&sd->bl); // Spawn character client side.
+ clif_load_end_ack_sub_messages(sd, (sd->state.connect_new != 0), (sd->state.changemap != 0));
+
+ struct party_data *p = NULL;
+
+ if (sd->status.party_id != 0)
+ p = party->search(sd->status.party_id);
+
// Send character's party info to the client. Call this after clif->spawn() to show HP bars correctly.
- if (sd->status.party_id != 0) {
- party->send_movemap(sd);
+ if (p != NULL) {
+ if (sd->state.connect_new == 0) // Login is handled in party_member_joined().
+ party->send_movemap(sd);
+
clif->party_hp(sd); // Show HP after displacement. [LuzZza]
}
@@ -10802,14 +10982,11 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
// Spawn pet.
if (sd->pd != NULL) {
- if (battle_config.pet_no_gvg != 0 && map_flag_gvg2(sd->bl.m)) { // Return the pet to egg. [Skotlex]
- clif->message(sd->fd, msg_sd(sd, 866)); // "Pets are not allowed in Guild Wars."
+ if (map->list[sd->bl.m].flag.nopet != 0) { // Return the pet to egg. [Skotlex]
+ clif->message(sd->fd, msg_sd(sd, 866)); // Pets are not allowed in Guild Wars.
pet->menu(sd, 3); // Option 3 is return to egg.
} else {
- map->addblock(&sd->pd->bl);
- clif->spawn(&sd->pd->bl);
- clif->send_petdata(sd,sd->pd, 0, 0);
- clif->send_petstatus(sd);
+ pet->spawn(sd, false);
}
}
@@ -10917,6 +11094,11 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
// Notify everyone that this character logged in. [Skotlex]
map->foreachpc(clif->friendslist_toggle_sub, sd->status.account_id, sd->status.char_id, 1);
+#if PACKETVER >= 20171122
+ if (battle_config.show_tip_window != 0)
+ clif->open_ui_send(sd, ZC_TIPBOX_UI);
+#endif
+
// Run OnPCLoginEvent labels.
npc->script_event(sd, NPCE_LOGIN);
} else {
@@ -10938,26 +11120,9 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
} else {
sd->state.warp_clean = 1;
}
-
- if (sd->guild != NULL && ((battle_config.guild_notice_changemap == 1 && sd->state.changemap != 0)
- || battle_config.guild_notice_changemap == 2)) {
- clif->guild_notice(sd, sd->guild);
- }
}
if (sd->state.changemap != 0) { // Restore information that gets lost on map-change.
-#if PACKETVER >= 20070918
- clif->partyinvitationstate(sd);
- clif->equpcheckbox(sd);
-#endif
-
-#if PACKETVER_MAIN_NUM >= 20171025 || PACKETVER_RE_NUM >= 20170920
- if (sd->hd != NULL)
- clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, sd->hd->homunculus.autofeed);
- else
- clif->zc_config(sd, CZ_CONFIG_HOMUNCULUS_AUTOFEEDING, false);
-#endif
-
bool flee_penalty = (battle_config.bg_flee_penalty != 100 || battle_config.gvg_flee_penalty != 100);
bool is_gvg = (map_flag_gvg2(sd->state.pmap) || map_flag_gvg2(sd->bl.m));
bool is_bg = (map->list[sd->state.pmap].flag.battleground != 0 || map->list[sd->bl.m].flag.battleground != 0);
@@ -11006,12 +11171,14 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
mail->clear(sd);
clif->maptypeproperty2(&sd->bl, SELF);
- // Init guild aura.
- if (sd->state.gmaster_flag != 0) {
- guild->aura_refresh(sd, GD_LEADERSHIP, guild->checkskill(sd->guild, GD_LEADERSHIP));
- guild->aura_refresh(sd, GD_GLORYWOUNDS, guild->checkskill(sd->guild, GD_GLORYWOUNDS));
- guild->aura_refresh(sd, GD_SOULCOLD, guild->checkskill(sd->guild, GD_SOULCOLD));
- guild->aura_refresh(sd, GD_HAWKEYES, guild->checkskill(sd->guild, GD_HAWKEYES));
+ if (sd->guild != NULL) {
+ // Init guild aura.
+ if (sd->state.gmaster_flag != 0) {
+ guild->aura_refresh(sd, GD_LEADERSHIP, guild->checkskill(sd->guild, GD_LEADERSHIP));
+ guild->aura_refresh(sd, GD_GLORYWOUNDS, guild->checkskill(sd->guild, GD_GLORYWOUNDS));
+ guild->aura_refresh(sd, GD_SOULCOLD, guild->checkskill(sd->guild, GD_SOULCOLD));
+ guild->aura_refresh(sd, GD_HAWKEYES, guild->checkskill(sd->guild, GD_HAWKEYES));
+ }
}
if (sd->state.vending != 0) { // Character is vending.
@@ -11036,10 +11203,6 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
clif->weather_check(sd);
- // This should be displayed last.
- if (sd->guild != NULL && first_time)
- clif->guild_notice(sd, sd->guild);
-
// For automatic triggering of NPCs after map loading. (So you don't need to walk 1 step first.)
if (map->getcell(sd->bl.m, &sd->bl, sd->bl.x, sd->bl.y, CELL_CHKNPC) != 0)
npc->touch_areanpc(sd, sd->bl.m, sd->bl.x, sd->bl.y);
@@ -11067,6 +11230,19 @@ static void clif_parse_LoadEndAck(int fd, struct map_session_data *sd)
#if PACKETVER >= 20090218
quest->questinfo_refresh(sd); // NPC quest/event icon check. [Kisuka]
#endif
+
+ if (first_time) {
+ int i;
+
+ ARR_FIND(0, instance->instances, i, instance->list[i].owner_type == IOT_CHAR && instance->list[i].owner_id == sd->status.account_id);
+
+ if (i < instance->instances) {
+ sd->instances = 1;
+ CREATE(sd->instance, short, 1);
+ sd->instance[0] = instance->list[i].id;
+ clif->instance_join(sd->fd, instance->list[i].id);
+ }
+ }
}
/// Server's tick (ZC_NOTIFY_TIME).
@@ -11288,7 +11464,7 @@ static void clif_parse_WalkToXY(int fd, struct map_session_data *sd)
; //You CAN walk on this OPT1 value.
/*else if( sd->progressbar.npc_id )
clif->progressbar_abort(sd);*/
- else if (pc_cant_act(sd) || pc_isvending(sd))
+ else if (pc_cant_act_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if(sd->sc.data[SC_RUN] || sd->sc.data[SC_WUGDASH])
@@ -11650,8 +11826,10 @@ static void clif_parse_ActionRequest_sub(struct map_session_data *sd, int action
return;
}
- if (pc_cant_act(sd) || pc_issit(sd) || sd->sc.option&OPTION_HIDE || pc_isvending(sd))
+ if (pc_cant_act_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0)
+ || pc_issit(sd) || (sd->sc.option & OPTION_HIDE) != 0 || pc_isvending(sd)) {
return;
+ }
if (sd->sc.option & OPTION_COSTUME)
return;
@@ -11951,7 +12129,7 @@ static void clif_parse_TakeItem(int fd, struct map_session_data *sd)
) )
break;
- if (pc_cant_act(sd))
+ if (pc_cant_act_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0))
break;
if (!pc->takeitem(sd, fitem))
@@ -11977,7 +12155,7 @@ static void clif_parse_DropItem(int fd, struct map_session_data *sd)
if (pc_isdead(sd))
break;
- if ( pc_cant_act2(sd) || sd->state.vending )
+ if (pc_cant_act_except_npc_chat(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0))
break;
if (sd->sc.count && (
@@ -12050,7 +12228,7 @@ static void clif_parse_EquipItem(int fd, struct map_session_data *sd)
return; //Out of bounds check.
if( sd->npc_id ) {
- if ((sd->npc_item_flag & ITEMENABLEDNPC_EQUIP) == 0)
+ if ((sd->npc_item_flag & ITEMENABLEDNPC_EQUIP) == 0 && sd->state.using_megaphone == 0)
return;
} else if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->sc.opt1)
; //You can equip/unequip stuff while storage is open/under status changes
@@ -12095,7 +12273,7 @@ static void clif_parse_UnequipItem(int fd, struct map_session_data *sd)
}
if( sd->npc_id ) {
- if ((sd->npc_item_flag & ITEMENABLEDNPC_EQUIP) == 0)
+ if ((sd->npc_item_flag & ITEMENABLEDNPC_EQUIP) == 0 && sd->state.using_megaphone == 0)
return;
} else if (sd->state.storage_flag != STORAGE_FLAG_CLOSED || sd->sc.opt1)
; //You can equip/unequip stuff while storage is open/under status changes
@@ -12295,7 +12473,7 @@ static void clif_parse_CreateChatRoom(int fd, struct map_session_data *sd) __att
/// 1 = public
static void clif_parse_CreateChatRoom(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
int len = (int)RFIFOW(fd, 2) - 15;
@@ -12343,7 +12521,7 @@ static void clif_parse_ChatAddMember(int fd, struct map_session_data *sd) __attr
/// 00d9 <chat ID>.L <passwd>.8B
static void clif_parse_ChatAddMember(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
int chatid = RFIFOL(fd,2);
@@ -12360,7 +12538,7 @@ static void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd)
/// 1 = public
static void clif_parse_ChatRoomStatusChange(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
int len = (int)RFIFOW(fd, 2) - 15;
@@ -12395,7 +12573,7 @@ static void clif_parse_ChangeChatOwner(int fd, struct map_session_data *sd) __at
/// 1 = normal
static void clif_parse_ChangeChatOwner(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
chat->change_owner(sd, RFIFOP(fd,6)); // non null terminated
@@ -12406,7 +12584,7 @@ static void clif_parse_KickFromChat(int fd, struct map_session_data *sd) __attri
/// 00e2 <name>.24B
static void clif_parse_KickFromChat(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
chat->kick(sd, RFIFOP(fd,2)); // non null terminated
@@ -12417,7 +12595,7 @@ static void clif_parse_ChatLeave(int fd, struct map_session_data *sd) __attribut
/// 00e3
static void clif_parse_ChatLeave(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_CHAT) == 0) || pc_isvending(sd))
return;
chat->leave(sd, false);
@@ -12444,12 +12622,12 @@ static void clif_parse_TradeRequest(int fd, struct map_session_data *sd) __attri
/// 00e4 <account id>.L
static void clif_parse_TradeRequest(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
struct map_session_data *t_sd = map->id2sd(RFIFOL(fd, 2));
- if (sd->chat_id == 0 && pc_cant_act(sd))
+ if (pc_cant_act_except_npc_chat(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0))
return; //You can trade while in a chatroom.
// @noask [LuzZza]
@@ -12474,7 +12652,7 @@ static void clif_parse_TradeAck(int fd, struct map_session_data *sd) __attribute
/// 4 = rejected
static void clif_parse_TradeAck(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
trade->ack(sd,RFIFOB(fd,2));
@@ -12485,7 +12663,7 @@ static void clif_parse_TradeAddItem(int fd, struct map_session_data *sd) __attri
/// 00e8 <index>.W <amount>.L
static void clif_parse_TradeAddItem(int fd, struct map_session_data *sd)
{
- if (!sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if (sd->state.trading == 0 || (pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
short index = RFIFOW(fd,2);
@@ -12502,8 +12680,9 @@ static void clif_parse_TradeOk(int fd, struct map_session_data *sd) __attribute_
/// 00eb
static void clif_parse_TradeOk(int fd, struct map_session_data *sd)
{
- if (pc_isdead(sd) || pc_isvending(sd))
+ if ((pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
+
trade->ok(sd);
}
@@ -12512,7 +12691,7 @@ static void clif_parse_TradeCancel(int fd, struct map_session_data *sd) __attrib
/// 00ed
static void clif_parse_TradeCancel(int fd, struct map_session_data *sd)
{
- if (pc_isdead(sd) || pc_isvending(sd))
+ if ((pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
trade->cancel(sd);
@@ -12523,7 +12702,7 @@ static void clif_parse_TradeCommit(int fd, struct map_session_data *sd) __attrib
/// 00ef
static void clif_parse_TradeCommit(int fd, struct map_session_data *sd)
{
- if (pc_isdead(sd) || pc_isvending(sd))
+ if ((pc_isdead(sd) && (battle_config.allowed_actions_when_dead & PCALLOWACTION_TRADE) == 0) || pc_isvending(sd))
return;
trade->commit(sd);
@@ -12543,8 +12722,10 @@ static void clif_parse_PutItemToCart(int fd, struct map_session_data *sd) __attr
static void clif_parse_PutItemToCart(int fd, struct map_session_data *sd)
{
int flag = 0;
- if (pc_istrading(sd) || sd->state.prevend)
+
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->state.prevend != 0)
return;
+
if (!pc_iscarton(sd))
return;
if ( (flag = pc->putitemtocart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4))) ) {
@@ -12558,8 +12739,9 @@ static void clif_parse_GetItemFromCart(int fd, struct map_session_data *sd) __at
/// 0127 <index>.W <amount>.L
static void clif_parse_GetItemFromCart(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || sd->state.prevend)
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->state.prevend != 0)
return;
+
if (!pc_iscarton(sd))
return;
pc->getitemfromcart(sd,RFIFOW(fd,2)-2,RFIFOL(fd,4));
@@ -12629,7 +12811,7 @@ static void clif_parse_ChangeCart(int fd, struct map_session_data *sd)
if (pc->checkskill(sd, MC_CHANGECART) == 0)
return;
- if (sd->npc_id || sd->state.workinprogress & 1) {
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0) || (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
#else
@@ -12849,7 +13031,7 @@ static void clif_useSkillToIdReal(int fd, struct map_session_data *sd, int skill
bool allow_self_skill = ((tmp & INF_SELF_SKILL) != 0 && (skill->get_nk(skill_id) & NK_NO_DAMAGE) != 0);
allow_self_skill = (allow_self_skill && battle_config.skill_enabled_npc == SKILLENABLEDNPC_SELF);
- if ((sd->npc_id != 0 && !allow_self_skill && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0 && !allow_self_skill && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
|| (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
@@ -12996,7 +13178,7 @@ static void clif_parse_UseSkillToPosSub(int fd, struct map_session_data *sd, uin
return;
}
- if ((sd->npc_id != 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)
|| (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
@@ -13118,7 +13300,7 @@ static void clif_parse_UseSkillMap(int fd, struct map_session_data *sd)
// It is possible to use teleport with the storage window open issue:8027
if ((pc_cant_act_except_npc(sd) && sd->state.storage_flag == STORAGE_FLAG_CLOSED && skill_id != AL_TELEPORT)
- || (sd->npc_id != 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)) {
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0 && battle_config.skill_enabled_npc != SKILLENABLEDNPC_ALL)) {
clif_menuskill_clear(sd);
return;
}
@@ -13161,7 +13343,8 @@ static void clif_parse_ProduceMix(int fd, struct map_session_data *sd)
default:
return;
}
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13192,7 +13375,8 @@ static void clif_parse_Cooking(int fd, struct map_session_data *sd)
if (type == 6 && sd->menuskill_id != GN_MIX_COOKING && sd->menuskill_id != GN_S_PHARMACY)
return;
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13212,7 +13396,8 @@ static void clif_parse_RepairItem(int fd, struct map_session_data *sd)
if (sd->menuskill_id != BS_REPAIRWEAPON)
return;
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13231,7 +13416,8 @@ static void clif_parse_WeaponRefine(int fd, struct map_session_data *sd)
if (sd->menuskill_id != WS_WEAPONREFINE) //Packet exploit?
return;
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13318,7 +13504,7 @@ static void clif_parse_NpcStringInput(int fd, struct map_session_data *sd) __att
/// 01d5 <packet len>.W <npc id>.L <string>.?B
static void clif_parse_NpcStringInput(int fd, struct map_session_data *sd)
{
- if (sd->state.trading || pc_isdead(sd) || pc_isvending(sd))
+ if ((sd->state.trading != 0 || pc_isvending(sd) || pc_isdead(sd)) && sd->state.using_megaphone == 0)
return;
int len = RFIFOW(fd, 2);
@@ -13334,7 +13520,7 @@ static void clif_parse_NpcStringInput(int fd, struct map_session_data *sd)
if (len < 9)
return;
- npcid = RFIFOL(fd, 4);
+ npcid = (sd->state.using_megaphone == 0) ? RFIFOL(fd, 4) : sd->npc_id;
message = RFIFOP(fd, 8);
safestrncpy(sd->npc_str, message, min(message_len,CHATBOX_SIZE));
@@ -13403,7 +13589,8 @@ static void clif_parse_SelectArrow(int fd, struct map_session_data *sd) __attrib
static void clif_parse_SelectArrow(int fd, struct map_session_data *sd)
{
int itemId;
- if (pc_istrading(sd) || pc_isdead(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || pc_isdead(sd) || pc_isvending(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
//Make it fail to avoid shop exploits where you sell something different than you see.
clif->skill_fail(sd, sd->ud.skill_id, USESKILL_FAIL_LEVEL, 0, 0);
clif_menuskill_clear(sd);
@@ -13689,7 +13876,7 @@ static void clif_parse_CreateParty(int fd, struct map_session_data *sd) __attrib
/// 01e8 <party name>.24B <item pickup rule>.B <item share rule>.B (CZ_MAKE_GROUP2)
static void clif_parse_CreateParty(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
char name[NAME_LENGTH];
@@ -13712,7 +13899,7 @@ static void clif_parse_CreateParty(int fd, struct map_session_data *sd)
static void clif_parse_CreateParty2(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_CreateParty2(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
char name[NAME_LENGTH];
@@ -13740,7 +13927,7 @@ static void clif_parse_PartyInvite(int fd, struct map_session_data *sd) __attrib
/// 02c4 <char name>.24B (CZ_PARTY_JOIN_REQ)
static void clif_parse_PartyInvite(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
struct map_session_data *t_sd;
@@ -13764,7 +13951,7 @@ static void clif_parse_PartyInvite(int fd, struct map_session_data *sd)
static void clif_parse_PartyInvite2(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_PartyInvite2(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
struct map_session_data *t_sd;
@@ -13797,7 +13984,7 @@ static void clif_parse_ReplyPartyInvite(int fd, struct map_session_data *sd) __a
/// 1 = accept
static void clif_parse_ReplyPartyInvite(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd)) {
party->reply_invite(sd, RFIFOL(fd, 2), 0);
return;
}
@@ -13808,7 +13995,7 @@ static void clif_parse_ReplyPartyInvite(int fd, struct map_session_data *sd)
static void clif_parse_ReplyPartyInvite2(int fd, struct map_session_data *sd) __attribute__((nonnull (2)));
static void clif_parse_ReplyPartyInvite2(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd)) {
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd)) {
party->reply_invite(sd, RFIFOL(fd, 2), 0);
return;
}
@@ -13821,7 +14008,7 @@ static void clif_parse_LeaveParty(int fd, struct map_session_data *sd) __attribu
/// 0100
static void clif_parse_LeaveParty(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (map->list[sd->bl.m].flag.partylock) {
@@ -13837,7 +14024,7 @@ static void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd) __
/// 0103 <account id>.L <char name>.24B
static void clif_parse_RemovePartyMember(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (map->list[sd->bl.m].flag.partylock) {
@@ -13854,7 +14041,7 @@ static void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd) __
/// 07d7 <exp share rule>.L <item pickup rule>.B <item share rule>.B (CZ_GROUPINFO_CHANGE_V2)
static void clif_parse_PartyChangeOption(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
struct party_data *p;
@@ -13909,7 +14096,7 @@ static void clif_parse_PartyChangeLeader(int fd, struct map_session_data *sd) __
/// 07da <account id>.L
static void clif_parse_PartyChangeLeader(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
party->changeleader(sd, map->id2sd(RFIFOL(fd,2)));
@@ -13924,7 +14111,7 @@ static void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data *
static void clif_parse_PartyBookingRegisterReq(int fd, struct map_session_data *sd)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short level = RFIFOW(fd,2);
@@ -13969,7 +14156,7 @@ static void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data *sd
static void clif_parse_PartyBookingSearchReq(int fd, struct map_session_data *sd)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short level = RFIFOW(fd,2);
@@ -14023,7 +14210,7 @@ static void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data *sd
static void clif_parse_PartyBookingDeleteReq(int fd, struct map_session_data *sd)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (party->booking_delete(sd))
@@ -14062,7 +14249,7 @@ static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd
static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short job[PARTY_BOOKING_JOBS];
@@ -14081,7 +14268,7 @@ static void clif_parse_PartyBookingUpdateReq(int fd, struct map_session_data *sd
static void clif_PartyBookingInsertNotify(struct map_session_data *sd, struct party_booking_ad_info *pb_ad)
{
#ifndef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int i;
@@ -14152,7 +14339,7 @@ static void clif_parse_PartyRecruitRegisterReq(int fd, struct map_session_data *
static void clif_parse_PartyRecruitRegisterReq(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short level = RFIFOW(fd, 2);
@@ -14226,7 +14413,7 @@ static void clif_parse_PartyRecruitSearchReq(int fd, struct map_session_data *sd
static void clif_parse_PartyRecruitSearchReq(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
short level = RFIFOW(fd, 2);
@@ -14246,7 +14433,7 @@ static void clif_parse_PartyRecruitDeleteReq(int fd, struct map_session_data *sd
static void clif_parse_PartyRecruitDeleteReq(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (party->booking_delete(sd))
@@ -14285,7 +14472,7 @@ static void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd
static void clif_parse_PartyRecruitUpdateReq(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
const char *notice = RFIFOP(fd, 2);
@@ -14361,7 +14548,7 @@ static void clif_parse_PartyBookingAddFilteringList(int fd, struct map_session_d
static void clif_parse_PartyBookingAddFilteringList(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int index = RFIFOL(fd, 2);
@@ -14378,7 +14565,7 @@ static void clif_parse_PartyBookingSubFilteringList(int fd, struct map_session_d
static void clif_parse_PartyBookingSubFilteringList(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int gid = RFIFOL(fd, 2);
@@ -14395,7 +14582,7 @@ static void clif_parse_PartyBookingReqVolunteer(int fd, struct map_session_data
static void clif_parse_PartyBookingReqVolunteer(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int index = RFIFOL(fd, 2);
@@ -14474,7 +14661,7 @@ static void clif_parse_PartyBookingRefuseVolunteer(int fd, struct map_session_da
static void clif_parse_PartyBookingRefuseVolunteer(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
unsigned int aid = RFIFOL(fd, 2);
@@ -14506,7 +14693,7 @@ static void clif_parse_PartyBookingCancelVolunteer(int fd, struct map_session_da
static void clif_parse_PartyBookingCancelVolunteer(int fd, struct map_session_data *sd)
{
#ifdef PARTY_RECRUIT
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
int index = RFIFOL(fd, 2);
@@ -14584,7 +14771,7 @@ static void clif_parse_CloseVending(int fd, struct map_session_data *sd) __attri
/// 012e
static void clif_parse_CloseVending(int fd, struct map_session_data *sd)
{
- if (sd->npc_id || sd->state.buyingstore || sd->state.trading)
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->state.buyingstore != 0 || sd->state.trading != 0)
return;
vending->close(sd);
@@ -14595,12 +14782,9 @@ static void clif_parse_VendingListReq(int fd, struct map_session_data *sd) __att
/// 0130 <account id>.L
static void clif_parse_VendingListReq(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isdead(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isdead(sd))
return;
- if( sd->npc_id ) {// using an NPC
- return;
- }
vending->list(sd,RFIFOL(fd,2));
}
@@ -14662,8 +14846,10 @@ static void clif_parse_OpenVending(int fd, struct map_session_data *sd) __attrib
/// 1 = open
static void clif_parse_OpenVending(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isdead(sd) || sd->state.vending || sd->state.buyingstore)
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0)
+ || pc_isdead(sd) || sd->state.vending != 0 || sd->state.buyingstore != 0) {
return;
+ }
int len = (int)RFIFOW(fd, 2) - 85;
@@ -15996,7 +16182,7 @@ static void clif_friendslist_toggle(struct map_session_data *sd, int account_id,
WFIFOL(fd, 2) = sd->status.friends[i].account_id;
WFIFOL(fd, 6) = sd->status.friends[i].char_id;
WFIFOB(fd, 10) = !online; //Yeah, a 1 here means "logged off", go figure...
-#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221 || PACKETVER_ZERO_NUM >= 20180328
memcpy(WFIFOP(fd, 11), sd->status.friends[i].name, NAME_LENGTH);
#endif // PACKETVER_ZERO
@@ -16021,7 +16207,7 @@ static void clif_friendslist_send(struct map_session_data *sd)
{
int i = 0, n, fd = sd->fd;
-#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221
+#if PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221 || PACKETVER_ZERO_NUM >= 20180328
const int offset = 8;
#else
const int offset = 32;
@@ -16033,7 +16219,7 @@ static void clif_friendslist_send(struct map_session_data *sd)
for(i = 0; i < MAX_FRIENDS && sd->status.friends[i].char_id; i++) {
WFIFOL(fd, 4 + offset * i + 0) = sd->status.friends[i].account_id;
WFIFOL(fd, 4 + offset * i + 4) = sd->status.friends[i].char_id;
-#if !(PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221)
+#if !(PACKETVER_MAIN_NUM >= 20180307 || PACKETVER_RE_NUM >= 20180221 || PACKETVER_ZERO_NUM >= 20180328)
memcpy(WFIFOP(fd, 4 + offset * i + 8), &sd->status.friends[i].name, NAME_LENGTH);
#endif
}
@@ -16750,7 +16936,7 @@ static void clif_parse_AutoRevive(int fd, struct map_session_data *sd) __attribu
/// 0292
static void clif_parse_AutoRevive(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isvending(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isvending(sd))
return;
if (!pc_isdead(sd))
@@ -19178,7 +19364,7 @@ static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data *sd) _
/// 1 = open
static void clif_parse_ReqOpenBuyingStore(int fd, struct map_session_data *sd)
{
- if (pc_istrading(sd) || pc_isdead(sd))
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0) || pc_isdead(sd))
return;
const unsigned int blocksize = sizeof(struct PACKET_CZ_REQ_OPEN_BUYING_STORE_sub);
@@ -20016,7 +20202,7 @@ static void clif_parse_SkillSelectMenu(int fd, struct map_session_data *sd)
if (sd->menuskill_id != SC_AUTOSHADOWSPELL)
return;
- if (pc_istrading(sd) || sd->state.prevend) {
+ if (pc_istrading_except_npc(sd) || sd->state.prevend != 0 || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
clif->skill_fail(sd, sd->ud.skill_id, 0, 0, 0);
clif_menuskill_clear(sd);
return;
@@ -20923,20 +21109,57 @@ static void clif_bank_withdraw(struct map_session_data *sd, enum e_BANKING_WITHD
#endif
}
-/* TODO: official response packet (tried 0x8cb/0x97b but the display was quite screwed up.) */
-/* currently mimicing */
+/**
+ * Sends EXP, drop and death-penalty rates.
+ * 0x097b <packet len>.W <exp>.L <death>.L <drop>.L <DETAIL_EXP_INFO>13B (ZC_PERSONAL_INFOMATION2)
+ * <InfoType>.B <Exp>.L <Death>.L <Drop>.L (DETAIL_EXP_INFO)
+ *
+ * @param sd The character which should receive the messages.
+ *
+ **/
static void clif_show_modifiers(struct map_session_data *sd)
{
nullpo_retv(sd);
- if( sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100 ) {
+#if PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
+ int length = sizeof(struct PACKET_ZC_PERSONAL_INFOMATION) + 4 * sizeof(struct PACKET_ZC_PERSONAL_INFOMATION_SUB);
+ WFIFOHEAD(sd->fd, length);
+ struct PACKET_ZC_PERSONAL_INFOMATION *p = WFIFOP(sd->fd, 0);
+
+ p->packetType = HEADER_ZC_PERSONAL_INFOMATION;
+ p->length = length;
+ // Single values.
+ p->details[0].type = PC_EXP_INFO;
+ p->details[0].exp = 0;
+ p->details[0].death = 0;
+ p->details[0].drop = 0;
+ p->details[1].type = TPLUS_EXP_INFO;
+ p->details[1].exp = 0;
+ p->details[1].death = 0;
+ p->details[1].drop = 0;
+ p->details[2].type = PREMIUM_EXP_INFO;
+ p->details[2].exp = (sd->status.mod_exp - 100) * 1000;
+ p->details[2].death = (sd->status.mod_death - 100) * 1000;
+ p->details[2].drop = (sd->status.mod_drop - 100) * 1000;
+ p->details[3].type = SERVER_EXP_INFO;
+ p->details[3].exp = battle_config.base_exp_rate * 1000;
+ p->details[3].death = battle_config.death_penalty_base * 10;
+ p->details[3].drop = battle_config.item_rate_common * 1000;
+ // Total values.
+ p->total_exp = (battle_config.base_exp_rate * sd->status.mod_exp / 100) * 1000;
+ p->total_death = (battle_config.base_exp_rate * sd->status.mod_death / 100) * 10;
+ p->total_drop = (battle_config.base_exp_rate * sd->status.mod_drop / 100) * 1000;
+
+ WFIFOSET(sd->fd, length);
+#else
+ if (sd->status.mod_exp != 100 || sd->status.mod_drop != 100 || sd->status.mod_death != 100) {
char output[128];
- snprintf(output,128, msg_sd(sd, 896), // Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%%
- sd->status.mod_exp,sd->status.mod_drop,sd->status.mod_death);
+ // Base EXP : %d%% | Base Drop: %d%% | Base Death Penalty: %d%%
+ safesnprintf(output, sizeof(output), msg_sd(sd, 896), sd->status.mod_exp, sd->status.mod_drop, sd->status.mod_death);
clif->broadcast2(&sd->bl, output, (int)strlen(output) + 1, 0xffbc90, 0x190, 12, 0, 0, SELF);
}
-
+#endif // PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
}
static void clif_notify_bounditem(struct map_session_data *sd, unsigned short index)
@@ -22176,7 +22399,10 @@ static void clif_parse_rodex_open_write_mail(int fd, struct map_session_data *sd
return;
const struct PACKET_CZ_REQ_OPEN_WRITE_MAIL *rPacket = RFIFOP(fd, 0);
- int8 result = (rodex->isenabled() == true && sd->npc_id == 0) ? 1 : 0;
+ int8 result = (rodex->isenabled() && (sd->npc_id == 0 || sd->state.using_megaphone != 0)) ? 1 : 0;
+
+ if (result == 1)
+ sd->state.workinprogress |= 2;
clif->rodex_open_write_mail(fd, rPacket->receiveName, result);
}
@@ -22959,61 +23185,65 @@ static void clif_parse_open_ui_request(int fd, struct map_session_data *sd)
clif->open_ui(sd, p->UIType);
}
-static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType)
+/**
+ * Does the actual packet sending for clif_open_ui().
+ *
+ * @param sd The character who opens the UI.
+ * @param ui_type The UI which should be opened.
+ *
+ **/
+static void clif_open_ui_send(struct map_session_data *sd, enum zc_ui_types ui_type)
{
+ nullpo_retv(sd);
+
#if PACKETVER >= 20150128
struct PACKET_ZC_OPEN_UI p;
-#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411
- int claimed = 0;
-#endif
-
- nullpo_retv(sd);
p.PacketType = openUiType;
- switch (uiType) {
- case CZ_STYLIST_UI:
- p.UIType = ZC_STYLIST_UI;
-#if PACKETVER >= 20171122
- p.data = 0;
-#endif
- break;
- case CZ_MACRO_REGISTER_UI:
- p.UIType = ZC_CAPTCHA_UI;
+ p.UIType = ui_type;
+
+ switch (ui_type) {
+ case ZC_BANK_UI:
+ case ZC_STYLIST_UI:
+ case ZC_CAPTCHA_UI:
+ case ZC_MACRO_UI:
#if PACKETVER >= 20171122
p.data = 0;
#endif
break;
- case CZ_MACRO_DETECTOR_UI:
- p.UIType = ZC_MACRO_UI;
#if PACKETVER >= 20171122
+ case ZC_TIPBOX_UI:
+ case ZC_RENEWQUEST_UI:
p.data = 0;
-#endif
break;
- case CZ_ATTENDANCE_UI:
- {
+ case ZC_ATTENDANCE_UI:
+ if (battle_config.feature_enable_attendance_system == 0)
+ return;
+
if (clif->attendance_getendtime() < time(NULL)) {
#if PACKETVER >= 20180207
clif->msgtable_color(sd, MSG_ATTENDANCE_UNAVAILABLE, COLOR_RED);
#endif
return;
}
- if (battle_config.feature_enable_attendance_system != 1)
- return;
+
#if PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411
- if (clif->attendance_timediff(sd) != true)
+ int claimed = 0;
+
+ if (!clif->attendance_timediff(sd))
++claimed;
else if (sd->status.attendance_count >= VECTOR_LENGTH(clif->attendance_data))
sd->status.attendance_count = 0;
- p.UIType = ZC_ATTENDANCE_UI;
+
p.data = sd->status.attendance_count * 10 + claimed;
#else
ShowWarning("Attendance System available only for PACKETVER_RE_NUM >= 20180307 || PACKETVER_MAIN_NUM >= 20180404 || PACKETVER_ZERO_NUM >= 20180411.\n");
return;
#endif
break;
- }
+#endif
default:
- ShowWarning("clif_open_ui: Requested UI (%u) is not implemented yet.\n", uiType);
+ ShowWarning("clif_open_ui_send: Requested UI (%u) is not implemented yet.\n", ui_type);
return;
}
@@ -23021,6 +23251,37 @@ static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType)
#endif
}
+static void clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType)
+{
+ nullpo_retv(sd);
+
+ enum zc_ui_types send_ui_type;
+
+ switch (uiType) {
+#if PACKETVER >= 20150128
+ case CZ_STYLIST_UI:
+ send_ui_type = ZC_STYLIST_UI;
+ break;
+ case CZ_MACRO_REGISTER_UI:
+ send_ui_type = ZC_CAPTCHA_UI;
+ break;
+ case CZ_MACRO_DETECTOR_UI:
+ send_ui_type = ZC_MACRO_UI;
+ break;
+#endif
+#if PACKETVER >= 20171122
+ case CZ_ATTENDANCE_UI:
+ send_ui_type = ZC_ATTENDANCE_UI;
+ break;
+#endif
+ default:
+ ShowWarning("clif_open_ui: Requested UI (%u) is not implemented yet.\n", uiType);
+ return;
+ }
+
+ clif->open_ui_send(sd, send_ui_type);
+}
+
static void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd) __attribute__((nonnull(2)));
static void clif_parse_attendance_reward_request(int fd, struct map_session_data *sd)
{
@@ -25131,6 +25392,7 @@ void clif_defaults(void)
clif->attendance_timediff = clif_attendance_timediff;
clif->attendance_getendtime = clif_attendance_getendtime;
clif->pOpenUIRequest = clif_parse_open_ui_request;
+ clif->open_ui_send = clif_open_ui_send;
clif->open_ui = clif_open_ui;
clif->pAttendanceRewardRequest = clif_parse_attendance_reward_request;
clif->ui_action = clif_ui_action;
diff --git a/src/map/clif.h b/src/map/clif.h
index e43aad808..ee76e62e8 100644
--- a/src/map/clif.h
+++ b/src/map/clif.h
@@ -750,6 +750,14 @@ enum removeGear_flag {
REMOVE_MOUNT_CART = 6,
};
+/** Info types for PACKET_ZC_PERSONAL_INFOMATION (0x097b). **/
+enum detail_exp_info_type {
+ PC_EXP_INFO = 0x0, //!< PCBang internet cafe modifiers. (http://pcbang.gnjoy.com/) (Unused.)
+ PREMIUM_EXP_INFO = 0x1, //!< Premium user modifiers. Values aren't displayed in 20161207+ clients.
+ SERVER_EXP_INFO = 0x2, //!< Server rates.
+ TPLUS_EXP_INFO = 0x3, //!< Unknown. Values are displayed as "TPLUS" in kRO. (Unused.)
+};
+
/**
* Clif.c Interface
**/
@@ -1650,6 +1658,7 @@ struct clif_interface {
bool (*attendance_timediff) (struct map_session_data *sd);
time_t (*attendance_getendtime) (void);
void (*pOpenUIRequest) (int fd, struct map_session_data *sd);
+ void (*open_ui_send) (struct map_session_data *sd, enum zc_ui_types ui_type);
void (*open_ui) (struct map_session_data *sd, enum cz_ui_types uiType);
void (*pAttendanceRewardRequest) (int fd, struct map_session_data *sd);
void (*ui_action) (struct map_session_data *sd, int32 UIType, int32 data);
diff --git a/src/map/guild.c b/src/map/guild.c
index 90f870f1c..a78ea169c 100644
--- a/src/map/guild.c
+++ b/src/map/guild.c
@@ -887,6 +887,12 @@ static void guild_member_joined(struct map_session_data *sd)
channel->join(g->channel, sd, "", true);
}
+ for (int j = 0; j < g->instances; j++) {
+ if (g->instance[j] >= 0) {
+ clif->instance_join(sd->fd, g->instance[j]);
+ break;
+ }
+ }
}
}
@@ -940,6 +946,13 @@ static int guild_member_added(int guild_id, int account_id, int char_id, int fla
channel->join(g->channel, sd, "", true);
}
+ for (int i = 0; i < g->instances; i++) {
+ if (g->instance[i] >= 0) {
+ clif->instance_join(sd->fd, g->instance[i]);
+ break;
+ }
+ }
+
return 0;
}
diff --git a/src/map/instance.c b/src/map/instance.c
index 1104b7e88..d2c0a229c 100644
--- a/src/map/instance.c
+++ b/src/map/instance.c
@@ -68,7 +68,7 @@ static bool instance_is_valid(int instance_id)
/*--------------------------------------
* name : instance name
* Return value could be
- * -4 = already exists | -3 = no free instances | -2 = owner not found | -1 = invalid type
+ * -4 = already exists | -2 = owner not found | -1 = invalid type
* On success return instance_id
*--------------------------------------*/
static int instance_create(int owner_id, const char *name, enum instance_owner_type type)
@@ -734,7 +734,7 @@ static void instance_force_destroy(struct map_session_data *sd)
switch (instance->list[i].owner_type) {
case IOT_CHAR:
{
- if (instance->list[i].owner_id != sd->status.char_id)
+ if (instance->list[i].owner_id != sd->status.account_id)
continue;
break;
}
diff --git a/src/map/itemdb.h b/src/map/itemdb.h
index 4b06a21d6..39f0e7945 100644
--- a/src/map/itemdb.h
+++ b/src/map/itemdb.h
@@ -152,6 +152,7 @@ enum item_itemid {
ITEMID_BUBBLE_GUM = 12210,
ITEMID_GIANT_FLY_WING = 12212,
ITEMID_NEURALIZER = 12213,
+ ITEMID_MEGAPHONE = 12221,
ITEMID_M_CENTER_POTION = 12241,
ITEMID_M_AWAKENING_POTION = 12242,
ITEMID_M_BERSERK_POTION = 12243,
diff --git a/src/map/mail.c b/src/map/mail.c
index a1176e8fc..b862900c7 100644
--- a/src/map/mail.c
+++ b/src/map/mail.c
@@ -81,9 +81,9 @@ static int mail_removezeny(struct map_session_data *sd, short flag)
static unsigned char mail_setitem(struct map_session_data *sd, int idx, int amount)
{
-
nullpo_retr(1, sd);
- if( pc_istrading(sd) )
+
+ if (pc_istrading_except_npc(sd) || (sd->npc_id != 0 && sd->state.using_megaphone == 0))
return 1;
if( idx == 0 ) { // Zeny Transfer
diff --git a/src/map/map.c b/src/map/map.c
index 24d571498..c88118b43 100644
--- a/src/map/map.c
+++ b/src/map/map.c
@@ -1911,6 +1911,7 @@ static void map_reqnickdb(struct map_session_data *sd, int charid)
}
// not in cache, request it
CREATE(req, struct charid_request, 1);
+ req->charid = sd->status.char_id;
req->next = p->requests;
p->requests = req;
chrif->searchcharid(charid);
@@ -5468,6 +5469,19 @@ static bool map_zone_mf_cache(int m, char *flag, char *params)
map_zone_mf_cache_add(m, rflag);
}
}
+ } else if (strcmpi(flag, "nopet") == 0) {
+ if (state == 0) {
+ if (map->list[m].flag.nopet != 0) {
+ sprintf(rflag, "nopet\t%d", map->list[m].flag.nopet);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
+ if (sscanf(params, "%d", &state) == 1) {
+ if (state != map->list[m].flag.nopet) {
+ sprintf(rflag, "nopet\t%d", state);
+ map_zone_mf_cache_add(m, rflag);
+ }
+ }
}
return false;
@@ -6691,6 +6705,8 @@ int do_init(int argc, char *argv[])
atcommand->msg_read(map->MSG_CONF_NAME, false);
map->inter_config_read(map->INTER_CONF_NAME, false);
logs->config_read(map->LOG_CONF_NAME, false);
+ } else {
+ battle->config_read(map->BATTLE_CONF_FILENAME, false);
}
script->config_read(map->SCRIPT_CONF_NAME, false);
@@ -6741,8 +6757,8 @@ int do_init(int argc, char *argv[])
timer->add_func_list(map->removemobs_timer, "map_removemobs_timer");
timer->add_interval(timer->gettick()+1000, map->freeblock_timer, 0, 0, 60*1000);
- HPM->event(HPET_INIT);
}
+ HPM->event(HPET_INIT);
atcommand->init(minimal);
battle->init(minimal);
@@ -6789,8 +6805,12 @@ int do_init(int argc, char *argv[])
exit(EXIT_SUCCESS);
}
- if( minimal ) {
+ if (minimal) {
HPM->event(HPET_READY);
+ HPM->event(HPET_FINAL);
+ battle->final();
+ HPM_map_do_final();
+ HPM->event(HPET_POST_FINAL);
exit(EXIT_SUCCESS);
}
diff --git a/src/map/map.h b/src/map/map.h
index 17f210bc3..e7c0cb50d 100644
--- a/src/map/map.h
+++ b/src/map/map.h
@@ -799,6 +799,7 @@ struct map_data {
unsigned pairship_endable : 1;
unsigned nostorage : 2;
unsigned nogstorage : 2;
+ unsigned nopet : 1;
uint32 noviewid; ///< noviewid (bitmask - @see enum equip_pos)
} flag;
struct point save;
diff --git a/src/map/messages_main.h b/src/map/messages_main.h
index dab537b6a..7dc0ff2b6 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: 20200520
+Latest version: 20200701
*/
enum clif_messages {
@@ -22636,6 +22636,26 @@ DEATH: %.1f%% (basic: 100.0%%, %s: %.1f%%)
*/
MSG_ID_EE8 = 0xee8,
#endif
+#if PACKETVER >= 20200617
+/*20200617 to latest
+캐릭터 생성에 제한이 있을 수 있습니다.
+*/
+ MSG_ID_EE9 = 0xee9,
+/*20200617 to latest
+월드가 포화상태입니다. 다른 월드를 이용해 주세요.
+*/
+ MSG_ID_EEA = 0xeea,
+#endif
+#if PACKETVER >= 20200701
+/*20200701 to latest
+채팅차단해제(수신거부해제)
+*/
+ MSG_ID_EEB = 0xeeb,
+/*20200701 to latest
+채팅차단(수신거부)
+*/
+ MSG_ID_EEC = 0xeec,
+#endif
};
#endif /* MAP_MESSAGES_MAIN_H */
diff --git a/src/map/messages_re.h b/src/map/messages_re.h
index e32f6b275..aa05a2e56 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: 20200304
+Latest version: 20200709
*/
enum clif_messages {
@@ -13342,12 +13342,14 @@ Ghost %d
Shadow %d
*/
MSG_NAVIGATION_PROPERTY8 = 0x8de,
-/*20120417 to latest
+/*20120417 to 20200304
언데드%d
Undead %d
20130807 to 20130814
염속성%d
Ghost %d
+20200709 to latest
+불사%d
*/
MSG_NAVIGATION_PROPERTY9 = 0x8df,
/*20120417 to latest
@@ -22089,6 +22091,44 @@ DEATH: %.1f%% (basic: 100.0%%, %s: %.1f%%)
*/
MSG_ID_EE3 = 0xee3,
#endif
+#if PACKETVER >= 20200709
+/*20200709 to latest
+특성 마법 공격력이 증가되었습니다.
+*/
+ MSG_ID_EE4 = 0xee4,
+/*20200709 to latest
+스펠 인챈팅 효과가 해제되었습니다.
+*/
+ MSG_ID_EE5 = 0xee5,
+/*20200709 to latest
+프롬 디 어비스 효과가 해제되었습니다.
+*/
+ MSG_ID_EE6 = 0xee6,
+/*20200709 to latest
+특성 물리 공격력, 특성 마법 공격력 및 명중률이 증가되었습니다.
+*/
+ MSG_ID_EE7 = 0xee7,
+/*20200709 to latest
+어비스 슬레이어 효과가 해제되었습니다.
+*/
+ MSG_ID_EE8 = 0xee8,
+/*20200709 to latest
+캐릭터 생성에 제한이 있을 수 있습니다.
+*/
+ MSG_ID_EE9 = 0xee9,
+/*20200709 to latest
+월드가 포화상태입니다. 다른 월드를 이용해 주세요.
+*/
+ MSG_ID_EEA = 0xeea,
+/*20200709 to latest
+채팅차단해제(수신거부해제)
+*/
+ MSG_ID_EEB = 0xeeb,
+/*20200709 to latest
+채팅차단(수신거부)
+*/
+ MSG_ID_EEC = 0xeec,
+#endif
};
#endif /* MAP_MESSAGES_RE_H */
diff --git a/src/map/messages_zero.h b/src/map/messages_zero.h
index 051d0e9df..7eca56cd9 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: 20200520
+Latest version: 20200701
*/
enum clif_messages {
@@ -18725,6 +18725,26 @@ DEATH: %.1f%% (basic: 100.0%%, %s: %.1f%%)
*/
MSG_ID_EE8 = 0xee8,
#endif
+#if PACKETVER >= 20200617
+/*20200617 to latest
+캐릭터 생성에 제한이 있을 수 있습니다.
+*/
+ MSG_ID_EE9 = 0xee9,
+/*20200617 to latest
+월드가 포화상태입니다. 다른 월드를 이용해 주세요.
+*/
+ MSG_ID_EEA = 0xeea,
+#endif
+#if PACKETVER >= 20200701
+/*20200701 to latest
+채팅차단해제(수신거부해제)
+*/
+ MSG_ID_EEB = 0xeeb,
+/*20200701 to latest
+채팅차단(수신거부)
+*/
+ MSG_ID_EEC = 0xeec,
+#endif
};
#endif /* MAP_MESSAGES_ZERO_H */
diff --git a/src/map/npc.c b/src/map/npc.c
index 6ba088a80..7a3fa9c3f 100644
--- a/src/map/npc.c
+++ b/src/map/npc.c
@@ -2715,43 +2715,47 @@ static int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_l
char card_slot[NAME_LENGTH];
char opt_index_str[NAME_LENGTH];
char opt_value_str[NAME_LENGTH];
- int i, j;
+ char opt_param_str[NAME_LENGTH];
+ int i = 0;
+ int j = 0;
int key_nameid = 0;
int key_amount = 0;
int key_refine = 0;
- int key_attribute = 0;
+ int key_attribute = ATTR_NONE;
int key_identify = 0;
int key_card[MAX_SLOTS];
int key_opt_idx[MAX_ITEM_OPTIONS];
int key_opt_value[MAX_ITEM_OPTIONS];
+ int key_opt_param[MAX_ITEM_OPTIONS];
nullpo_ret(sd);
nullpo_ret(item_list);
nullpo_ret(nd);
// discard old contents
- script->cleararray_pc(sd, "@sold_nameid", (void*)0);
- script->cleararray_pc(sd, "@sold_quantity", (void*)0);
- script->cleararray_pc(sd, "@sold_refine", (void*)0);
- script->cleararray_pc(sd, "@sold_attribute", (void*)0);
- script->cleararray_pc(sd, "@sold_identify", (void*)0);
-
- for( j = 0; j < MAX_SLOTS; j++ )
- {// clear each of the card slot entries
+ script->cleararray_pc(sd, "@sold_nameid", (void *)0);
+ script->cleararray_pc(sd, "@sold_quantity", (void *)0);
+ script->cleararray_pc(sd, "@sold_refine", (void *)0);
+ script->cleararray_pc(sd, "@sold_attribute", (void *)0);
+ script->cleararray_pc(sd, "@sold_identify", (void *)0);
+
+ for (j = 0; j < MAX_SLOTS; j++) { // clear each of the card slot entries
key_card[j] = 0;
snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
- script->cleararray_pc(sd, card_slot, (void*)0);
+ script->cleararray_pc(sd, card_slot, (void *)0);
}
for (j = 0; j < MAX_ITEM_OPTIONS; j++) { // Clear Each item option entry
key_opt_idx[j] = 0;
key_opt_value[j] = 0;
+ key_opt_param[j] = 0;
- snprintf(opt_index_str, sizeof(opt_index_str), "@slot_opt_idx%d", j + 1);
- script->cleararray_pc(sd, opt_index_str, (void*)0);
-
- snprintf(opt_value_str, sizeof(opt_value_str), "@slot_opt_val%d", j + 1);
- script->cleararray_pc(sd, opt_value_str, (void*)0);
+ snprintf(opt_index_str, sizeof(opt_index_str), "@sold_opt_idx%d", j + 1);
+ script->cleararray_pc(sd, opt_index_str, (void *)0);
+ snprintf(opt_value_str, sizeof(opt_value_str), "@sold_opt_val%d", j + 1);
+ script->cleararray_pc(sd, opt_value_str, (void *)0);
+ snprintf(opt_param_str, sizeof(opt_param_str), "@sold_opt_param%d", j + 1);
+ script->cleararray_pc(sd, opt_param_str, (void *)0);
}
// save list of to be sold items
@@ -2764,32 +2768,31 @@ static int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_l
intptr_t attribute = item->attribute;
intptr_t identify = item->identify;
- script->setarray_pc(sd, "@sold_nameid", i, (void*)nameid, &key_nameid);
- script->setarray_pc(sd, "@sold_quantity", i, (void*)amount, &key_amount);
-
// process item based information into the arrays
- script->setarray_pc(sd, "@sold_refine", i, (void*)refine, &key_refine);
- script->setarray_pc(sd, "@sold_attribute", i, (void*)attribute, &key_attribute);
- script->setarray_pc(sd, "@sold_identify", i, (void*)identify, &key_identify);
+ script->setarray_pc(sd, "@sold_nameid", i, (void *)nameid, &key_nameid);
+ script->setarray_pc(sd, "@sold_quantity", i, (void *)amount, &key_amount);
+ script->setarray_pc(sd, "@sold_refine", i, (void *)refine, &key_refine);
+ script->setarray_pc(sd, "@sold_attribute", i, (void *)attribute, &key_attribute);
+ script->setarray_pc(sd, "@sold_identify", i, (void *)identify, &key_identify);
for (j = 0; j < MAX_SLOTS; j++) {
intptr_t card = item->card[j];
- // store each of the cards/special info from the item in the array
snprintf(card_slot, sizeof(card_slot), "@sold_card%d", j + 1);
- script->setarray_pc(sd, card_slot, i, (void*)card, &key_card[j]);
+ script->setarray_pc(sd, card_slot, i, (void *)card, &key_card[j]);
}
for (j = 0; j < MAX_ITEM_OPTIONS; j++) {
intptr_t opt_idx = item->option[j].index;
intptr_t opt_value = item->option[j].value;
+ intptr_t opt_param = item->option[j].param;
- snprintf(opt_index_str, sizeof(opt_index_str), "@slot_opt_idx%d", j + 1);
- script->setarray_pc(sd, opt_index_str, i, (void*)opt_idx, &key_opt_idx[j]);
-
- snprintf(opt_value_str, sizeof(opt_value_str), "@slot_opt_val%d", j + 1);
- script->setarray_pc(sd, opt_value_str, i, (void*)opt_value, &key_opt_value[j]);
+ snprintf(opt_index_str, sizeof(opt_index_str), "@sold_opt_idx%d", j + 1);
+ script->setarray_pc(sd, opt_index_str, i, (void *)opt_idx, &key_opt_idx[j]);
+ snprintf(opt_value_str, sizeof(opt_value_str), "@sold_opt_val%d", j + 1);
+ script->setarray_pc(sd, opt_value_str, i, (void *)opt_value, &key_opt_value[j]);
+ snprintf(opt_param_str, sizeof(opt_param_str), "@sold_opt_param%d", j + 1);
+ script->setarray_pc(sd, opt_param_str, i, (void *)opt_param, &key_opt_param[j]);
}
-
}
// invoke event
@@ -2798,104 +2801,102 @@ static int npc_selllist_sub(struct map_session_data *sd, struct itemlist *item_l
return 0;
}
-/// Player item selling to npc shop.
-///
-/// @param item_list 'n' pairs <index,amount>
-/// @return result code for clif->parse_NpcSellListSend
+/**
+ * Processes a character's request to sell items to a NPC shop.
+ *
+ * @param sd The character who wants to sell the items.
+ * @param item_list The list of items and respective amounts which should be sold.
+ * @return 1 on failure, 0 on success.
+ *
+ **/
static int npc_selllist(struct map_session_data *sd, struct itemlist *item_list)
{
- int64 z;
- int i,skill_t, skill_idx = skill->get_index(MC_OVERCHARGE);
- struct npc_data *nd;
- bool duplicates[MAX_INVENTORY] = { 0 };
-
nullpo_retr(1, sd);
nullpo_retr(1, item_list);
- if( ( nd = npc->checknear(sd, map->id2bl(sd->npc_shopid)) ) == NULL ) {
+ struct npc_data *nd = npc->checknear(sd, map->id2bl(sd->npc_shopid));
+
+ if (nd == NULL)
return 1;
- }
- if( nd->subtype != SHOP ) {
- if (!(nd->subtype == SCRIPT && nd->u.scr.shop && (nd->u.scr.shop->type == NST_ZENY || nd->u.scr.shop->type == NST_MARKET)))
+ if (nd->subtype != SHOP) {
+ if (nd->subtype != SCRIPT || nd->u.scr.shop == NULL || (nd->u.scr.shop->type != NST_ZENY && nd->u.scr.shop->type != NST_MARKET))
return 1;
}
- z = 0;
-
if (sd->status.zeny >= MAX_ZENY && nd->master_nd == NULL)
return 1;
- // verify the sell list
- for (i = 0; i < VECTOR_LENGTH(*item_list); i++) {
+ bool duplicates[MAX_INVENTORY] = { false };
+ int64 z = 0;
+
+ // Verify the sell list.
+ for (int i = 0; i < VECTOR_LENGTH(*item_list); i++) {
struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i);
- int nameid, value, idx = entry->id;
+ int idx = entry->id;
- if (idx >= sd->status.inventorySize || idx < 0 || entry->amount < 0) {
+ if (idx >= sd->status.inventorySize || idx < 0 || entry->amount < 0)
return 1;
- }
- if (duplicates[idx]) {
- // Sanity check. The client sends each inventory index at most once [Haru]
+ if (duplicates[idx]) // Sanity check. The client sends each inventory index at most once. [Haru]
return 1;
- }
+
duplicates[idx] = true;
- nameid = sd->status.inventory[idx].nameid;
+ int nameid = sd->status.inventory[idx].nameid;
- if (!nameid || !sd->inventory_data[idx] || sd->status.inventory[idx].amount < entry->amount) {
+ if (nameid == 0 || sd->inventory_data[idx] == NULL || sd->status.inventory[idx].amount < entry->amount)
return 1;
- }
- if (nd->master_nd) {
- // Script-controlled shops decide by themselves, what can be sold and at what price.
+ if (nd->master_nd != NULL) // Script-controlled shops decide by themselves, what can be sold and at what price.
continue;
- }
- value = pc->modifysellvalue(sd, sd->inventory_data[idx]->value_sell);
+ int value = pc->modifysellvalue(sd, sd->inventory_data[idx]->value_sell);
z += (int64)value * entry->amount;
}
- if( nd->master_nd ) { // Script-controlled shops
+ if (nd->master_nd != NULL) // Script-controlled shops.
return npc->selllist_sub(sd, item_list, nd->master_nd);
- }
- // delete items
- for (i = 0; i < VECTOR_LENGTH(*item_list); i++) {
+ if (z + sd->status.zeny > MAX_ZENY)
+ return 1;
+
+ // Delete items.
+ for (int i = 0; i < VECTOR_LENGTH(*item_list); i++) {
struct itemlist_entry *entry = &VECTOR_INDEX(*item_list, i);
int idx = entry->id;
if (sd->inventory_data[idx]->type == IT_PETEGG && sd->status.inventory[idx].card[0] == CARD0_PET) {
- if (pet->search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0) {
+ if (pet->search_petDB_index(sd->status.inventory[idx].nameid, PET_EGG) >= 0)
intif->delete_petdata(MakeDWord(sd->status.inventory[idx].card[1], sd->status.inventory[idx].card[2]));
- }
}
- // Achievements [Smokexyz/Hercules]
+ // Achievements. [Smokexyz/Hercules]
achievement->validate_item_sell(sd, sd->status.inventory[idx].nameid, entry->amount);
pc->delitem(sd, idx, entry->amount, 0, DELITEM_SOLD, LOG_TYPE_NPC);
-
}
- if (z + sd->status.zeny > MAX_ZENY && nd->master_nd == NULL)
- return 1;
-
if (z > MAX_ZENY)
z = MAX_ZENY;
pc->getzeny(sd, (int)z, LOG_TYPE_NPC, NULL);
- // custom merchant shop exp bonus
- if( battle_config.shop_exp > 0 && z > 0 && ( skill_t = pc->checkskill2(sd,skill_idx) ) > 0) {
- if( sd->status.skill[skill_idx].flag >= SKILL_FLAG_REPLACED_LV_0 )
+ int skill_t;
+ int skill_idx = skill->get_index(MC_OVERCHARGE);
+
+ // Custom merchant shop exp bonus.
+ if (battle_config.shop_exp > 0 && z > 0 && (skill_t = pc->checkskill2(sd, skill_idx)) > 0) {
+ if (sd->status.skill[skill_idx].flag >= SKILL_FLAG_REPLACED_LV_0)
skill_t = sd->status.skill[skill_idx].flag - SKILL_FLAG_REPLACED_LV_0;
- if( skill_t > 0 ) {
+ if (skill_t > 0) {
z = apply_percentrate64(z, skill_t * battle_config.shop_exp, 10000);
+
if (z < 1)
z = 1;
+
pc->gainexp(sd, NULL, 0, (int)z, false);
}
}
@@ -5241,6 +5242,8 @@ static const char *npc_parse_mapflag(const char *w1, const char *w2, const char
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 if (strcmpi(w3, "nopet") == 0) {
+ map->list[m].flag.nopet = (state != 0) ? 1 : 0;
} else {
npc->parse_unknown_mapflag(mapname, w3, w4, start, buffer, filepath, retval);
}
diff --git a/src/map/packets_keys_main.h b/src/map/packets_keys_main.h
index 5a2a1f846..ef8d39fb7 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, 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, 2019-07-03aRagexe, 2019-07-03bRagexeRE, 2019-07-17aRagexe, 2019-07-17cRagexeRE, 2019-07-17dRagexe, 2019-07-17dRagexeRE, 2019-07-24aRagexe, 2019-07-24bRagexeRE, 2019-07-31bRagexe, 2019-07-31bRagexeRE, 2019-08-02aRagexe, 2019-08-02aRagexeRE, 2019-08-07aRagexe, 2019-08-07dRagexeRE, 2019-08-21aRagexe, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexe, 2019-08-28aRagexeRE, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-04bRagexeRE, 2019-09-18bRagexe, 2019-09-18cRagexeRE, 2019-09-25aRagexe, 2019-09-25aRagexeRE, 2019-09-25bRagexe, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexe, 2019-10-16fRagexeRE, 2019-10-16gRagexe, 2019-10-16gRagexeRE, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-06bRagexeRE, 2019-11-07aRagexe, 2019-11-07aRagexeRE, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-13eRagexeRE, 2019-11-20aRagexe, 2019-11-20cRagexeRE, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27aRagexeRE, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04aRagexeRE, 2019-12-04bRagexe, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11aRagexe, 2019-12-11fRagexeRE, 2019-12-18bRagexe, 2019-12-18bRagexeRE, 2019-12-24aRagexe, 2019-12-24aRagexeRE, 2019-12-24bRagexe, 2019-12-24bRagexeRE, 2020-01-08aRagexe, 2020-01-08bRagexeRE, 2020-01-22cRagexe, 2020-01-22cRagexeRE, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-05aRagexeRE, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-12aRagexeRE, 2020-02-19dRagexe, 2020-02-19eRagexeRE, 2020-03-04aRagexe, 2020-03-04aRagexeRE, 2020-03-18bRagexe, 2020-04-01bRagexe, 2020-04-14_6aRagexe, 2020-04-14eRagexe, 2020-05-06aRagexe, 2020-05-20bRagexe
+// 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, 2019-07-03aRagexe, 2019-07-03bRagexeRE, 2019-07-17aRagexe, 2019-07-17cRagexeRE, 2019-07-17dRagexe, 2019-07-17dRagexeRE, 2019-07-24aRagexe, 2019-07-24bRagexeRE, 2019-07-31bRagexe, 2019-07-31bRagexeRE, 2019-08-02aRagexe, 2019-08-02aRagexeRE, 2019-08-07aRagexe, 2019-08-07dRagexeRE, 2019-08-21aRagexe, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexe, 2019-08-28aRagexeRE, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-04bRagexeRE, 2019-09-18bRagexe, 2019-09-18cRagexeRE, 2019-09-25aRagexe, 2019-09-25aRagexeRE, 2019-09-25bRagexe, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexe, 2019-10-16fRagexeRE, 2019-10-16gRagexe, 2019-10-16gRagexeRE, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-06bRagexeRE, 2019-11-07aRagexe, 2019-11-07aRagexeRE, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-13eRagexeRE, 2019-11-20aRagexe, 2019-11-20cRagexeRE, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27aRagexeRE, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04aRagexeRE, 2019-12-04bRagexe, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11aRagexe, 2019-12-11fRagexeRE, 2019-12-18bRagexe, 2019-12-18bRagexeRE, 2019-12-24aRagexe, 2019-12-24aRagexeRE, 2019-12-24bRagexe, 2019-12-24bRagexeRE, 2020-01-08aRagexe, 2020-01-08bRagexeRE, 2020-01-22cRagexe, 2020-01-22cRagexeRE, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-05aRagexeRE, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-12aRagexeRE, 2020-02-19dRagexe, 2020-02-19eRagexeRE, 2020-03-04aRagexe, 2020-03-04aRagexeRE, 2020-03-18bRagexe, 2020-04-01bRagexe, 2020-04-14_6aRagexe, 2020-04-14eRagexe, 2020-05-06aRagexe, 2020-05-20bRagexe, 2020-06-03aRagexe, 2020-06-17aRagexe, 2020-07-01bRagexe, 2020-07-01cRagexe, 2020-07-09_sakaRagexeRE, 2020-07-15bRagexe
#if PACKETVER == 20101123 || \
PACKETVER == 20101124 || \
PACKETVER == 20101125 || \
@@ -194,7 +194,12 @@
PACKETVER == 20200401 || \
PACKETVER == 20200414 || \
PACKETVER == 20200506 || \
- PACKETVER >= 20200520
+ PACKETVER == 20200520 || \
+ PACKETVER == 20200603 || \
+ PACKETVER == 20200617 || \
+ PACKETVER == 20200701 || \
+ PACKETVER == 20200709 || \
+ PACKETVER >= 20200715
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
diff --git a/src/map/packets_keys_zero.h b/src/map/packets_keys_zero.h
index 700ff4c6c..1aa370b56 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, 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, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero, 2020-04-14bRagexe_zero, 2020-05-06aRagexe_zero, 2020-05-20_5aRagexe_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, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero, 2020-04-14bRagexe_zero, 2020-05-06aRagexe_zero, 2020-05-20_5aRagexe_zero, 2020-06-03_2aRagexe_zero, 2020-06-17aRagexe_zero, 2020-07-01_2aRagexe_zero, 2020-07-01aRagexe_zero
#if PACKETVER == 20171018 || \
PACKETVER == 20171019 || \
PACKETVER == 20171023 || \
@@ -113,7 +113,10 @@
PACKETVER == 20200401 || \
PACKETVER == 20200414 || \
PACKETVER == 20200506 || \
- PACKETVER >= 20200520
+ PACKETVER == 20200520 || \
+ PACKETVER == 20200603 || \
+ PACKETVER == 20200617 || \
+ PACKETVER >= 20200701
packetKeys(0x00000000,0x00000000,0x00000000);
#endif
diff --git a/src/map/packets_shuffle_main.h b/src/map/packets_shuffle_main.h
index ba234bdb8..fc28a12a9 100644
--- a/src/map/packets_shuffle_main.h
+++ b/src/map/packets_shuffle_main.h
@@ -3345,7 +3345,7 @@
packet(0x0969,clif->pSearchStoreInfoNextPage,0);
#endif
-// 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-28bRagexe, 2018-04-04bRagexe, 2018-04-18aRagexe, 2018-04-25cRagexe, 2018-05-02bRagexe, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-23aRagexe, 2018-05-30aRagexe, 2018-06-05bRagexe, 2018-06-20cRagexe, 2018-06-20eRagexe, 2018-06-21aRagexe, 2018-07-04aRagexe, 2018-07-18bRagexe, 2018-07-18cRagexe, 2018-08-01cRagexe, 2018-08-08bRagexe, 2018-08-22cRagexe, 2018-08-29aRagexe, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-19aRagexe, 2018-10-02aRagexe, 2018-10-02bRagexe, 2018-10-17_02aRagexe, 2018-10-17_03aRagexe, 2018-10-17bRagexe, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-11-07aRagexe, 2018-11-14cRagexe, 2018-11-14dRagexe, 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, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-07-03aRagexe, 2019-07-17aRagexe, 2019-07-17dRagexe, 2019-07-24aRagexe, 2019-07-31bRagexe, 2019-08-02aRagexe, 2019-08-07aRagexe, 2019-08-21aRagexe, 2019-08-28aRagexe, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe, 2019-09-25aRagexe, 2019-09-25bRagexe, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-16fRagexe, 2019-10-16gRagexe, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-07aRagexe, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-20aRagexe, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04bRagexe, 2019-12-11aRagexe, 2019-12-18bRagexe, 2019-12-24aRagexe, 2019-12-24bRagexe, 2020-01-08aRagexe, 2020-01-22cRagexe, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-19dRagexe, 2020-03-04aRagexe, 2020-03-18bRagexe, 2020-04-01bRagexe, 2020-04-14_6aRagexe, 2020-04-14eRagexe, 2020-05-06aRagexe, 2020-05-20bRagexe
+// 2014-06-11eRagexe, 2015-02-25hRagexe, 2018-03-15aRagexe, 2018-03-21aRagexe, 2018-03-28bRagexe, 2018-04-04bRagexe, 2018-04-18aRagexe, 2018-04-25cRagexe, 2018-05-02bRagexe, 2018-05-09aRagexe, 2018-05-16cRagexe, 2018-05-23aRagexe, 2018-05-30aRagexe, 2018-06-05bRagexe, 2018-06-20cRagexe, 2018-06-20eRagexe, 2018-06-21aRagexe, 2018-07-04aRagexe, 2018-07-18bRagexe, 2018-07-18cRagexe, 2018-08-01cRagexe, 2018-08-08bRagexe, 2018-08-22cRagexe, 2018-08-29aRagexe, 2018-08-31aRagexe, 2018-09-12dRagexe, 2018-09-19aRagexe, 2018-10-02aRagexe, 2018-10-02bRagexe, 2018-10-17_02aRagexe, 2018-10-17_03aRagexe, 2018-10-17bRagexe, 2018-10-24bRagexe, 2018-10-31aRagexe, 2018-10-31bRagexe, 2018-11-07aRagexe, 2018-11-14cRagexe, 2018-11-14dRagexe, 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, 2019-06-19eRagexe, 2019-06-19hRagexe, 2019-07-03aRagexe, 2019-07-17aRagexe, 2019-07-17dRagexe, 2019-07-24aRagexe, 2019-07-31bRagexe, 2019-08-02aRagexe, 2019-08-07aRagexe, 2019-08-21aRagexe, 2019-08-28aRagexe, 2019-09-04aRagexe, 2019-09-04bRagexe, 2019-09-18bRagexe, 2019-09-25aRagexe, 2019-09-25bRagexe, 2019-10-02cRagexe, 2019-10-02dRagexe, 2019-10-16fRagexe, 2019-10-16gRagexe, 2019-10-18aRagexe, 2019-10-23aRagexe, 2019-10-30cRagexe, 2019-11-06aRagexe, 2019-11-07aRagexe, 2019-11-13cRagexe, 2019-11-13eRagexe, 2019-11-20aRagexe, 2019-11-20dRagexe, 2019-11-27aRagexe, 2019-11-27bRagexe, 2019-12-04aRagexe, 2019-12-04bRagexe, 2019-12-11aRagexe, 2019-12-18bRagexe, 2019-12-24aRagexe, 2019-12-24bRagexe, 2020-01-08aRagexe, 2020-01-22cRagexe, 2020-01-29bRagexe, 2020-01-30aRagexe, 2020-02-05aRagexe, 2020-02-06aRagexe, 2020-02-12aRagexe, 2020-02-19dRagexe, 2020-03-04aRagexe, 2020-03-18bRagexe, 2020-04-01bRagexe, 2020-04-14_6aRagexe, 2020-04-14eRagexe, 2020-05-06aRagexe, 2020-05-20bRagexe, 2020-06-03aRagexe, 2020-06-17aRagexe, 2020-07-01bRagexe, 2020-07-01cRagexe
#if PACKETVER == 20140611 || \
PACKETVER == 20150225 || \
PACKETVER == 20180315 || \
@@ -3442,7 +3442,10 @@
PACKETVER == 20200401 || \
PACKETVER == 20200414 || \
PACKETVER == 20200506 || \
- PACKETVER >= 20200520
+ PACKETVER == 20200520 || \
+ PACKETVER == 20200603 || \
+ PACKETVER == 20200617 || \
+ PACKETVER >= 20200701
packet(0x0202,clif->pFriendsListAdd,2);
packet(0x022d,clif->pHomMenu,2,4);
packet(0x023b,clif->pStoragePassword,0);
diff --git a/src/map/packets_shuffle_re.h b/src/map/packets_shuffle_re.h
index 46829fec1..e7ed71a3b 100644
--- a/src/map/packets_shuffle_re.h
+++ b/src/map/packets_shuffle_re.h
@@ -9618,7 +9618,7 @@
packet(0x0969,clif->pActionRequest,2,6);
#endif
-// 2018-03-21aRagexeRE, 2018-03-28bRagexeRE, 2018-04-04cRagexeRE, 2018-04-18bRagexeRE, 2018-04-25cRagexeRE, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-16cRagexeRE, 2018-05-23aRagexeRE, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20dRagexeRE, 2018-06-20eRagexeRE, 2018-06-21aRagexeRE, 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, 2019-07-03bRagexeRE, 2019-07-17cRagexeRE, 2019-07-17dRagexeRE, 2019-07-24bRagexeRE, 2019-07-31bRagexeRE, 2019-08-02aRagexeRE, 2019-08-07dRagexeRE, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexeRE, 2019-09-04bRagexeRE, 2019-09-18cRagexeRE, 2019-09-25aRagexeRE, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexeRE, 2019-10-16gRagexeRE, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-11-06bRagexeRE, 2019-11-07aRagexeRE, 2019-11-13eRagexeRE, 2019-11-20cRagexeRE, 2019-11-27aRagexeRE, 2019-12-04aRagexeRE, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11fRagexeRE, 2019-12-18bRagexeRE, 2019-12-24aRagexeRE, 2019-12-24bRagexeRE, 2020-01-08bRagexeRE, 2020-01-22cRagexeRE, 2020-02-05aRagexeRE, 2020-02-12aRagexeRE, 2020-02-19eRagexeRE, 2020-03-04aRagexeRE
+// 2018-03-21aRagexeRE, 2018-03-28bRagexeRE, 2018-04-04cRagexeRE, 2018-04-18bRagexeRE, 2018-04-25cRagexeRE, 2018-05-02bRagexeRE, 2018-05-02dRagexeRE, 2018-05-16cRagexeRE, 2018-05-23aRagexeRE, 2018-05-30bRagexeRE, 2018-05-30cRagexeRE, 2018-06-05bRagexeRE, 2018-06-12aRagexeRE, 2018-06-12bRagexeRE, 2018-06-20dRagexeRE, 2018-06-20eRagexeRE, 2018-06-21aRagexeRE, 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, 2019-07-03bRagexeRE, 2019-07-17cRagexeRE, 2019-07-17dRagexeRE, 2019-07-24bRagexeRE, 2019-07-31bRagexeRE, 2019-08-02aRagexeRE, 2019-08-07dRagexeRE, 2019-08-21cRagexeRE, 2019-08-21dRagexeRE, 2019-08-28aRagexeRE, 2019-09-04bRagexeRE, 2019-09-18cRagexeRE, 2019-09-25aRagexeRE, 2019-09-25bRagexeRE, 2019-10-02bRagexeRE, 2019-10-02dRagexeRE, 2019-10-02dRagexeRE_2, 2019-10-16fRagexeRE, 2019-10-16gRagexeRE, 2019-10-23aRagexeRE, 2019-10-30bRagexeRE, 2019-11-06bRagexeRE, 2019-11-07aRagexeRE, 2019-11-13eRagexeRE, 2019-11-20cRagexeRE, 2019-11-27aRagexeRE, 2019-12-04aRagexeRE, 2019-12-04bRagexeRE, 2019-12-04cRagexeRE, 2019-12-11fRagexeRE, 2019-12-18bRagexeRE, 2019-12-24aRagexeRE, 2019-12-24bRagexeRE, 2020-01-08bRagexeRE, 2020-01-22cRagexeRE, 2020-02-05aRagexeRE, 2020-02-12aRagexeRE, 2020-02-19eRagexeRE, 2020-03-04aRagexeRE, 2020-07-09_sakaRagexeRE
#if PACKETVER == 20180321 || \
PACKETVER == 20180328 || \
PACKETVER == 20180404 || \
@@ -9702,7 +9702,8 @@
PACKETVER == 20200205 || \
PACKETVER == 20200212 || \
PACKETVER == 20200219 || \
- PACKETVER >= 20200304
+ PACKETVER == 20200304 || \
+ PACKETVER >= 20200709
packet(0x0202,clif->pFriendsListAdd,2);
packet(0x022d,clif->pHomMenu,2,4);
packet(0x023b,clif->pStoragePassword,0);
diff --git a/src/map/packets_shuffle_zero.h b/src/map/packets_shuffle_zero.h
index 42459bb87..5ff03b264 100644
--- a/src/map/packets_shuffle_zero.h
+++ b/src/map/packets_shuffle_zero.h
@@ -37,7 +37,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, 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, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero, 2020-04-14bRagexe_zero, 2020-05-06aRagexe_zero, 2020-05-20_5aRagexe_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, 2019-06-26_3aRagexe_zero, 2019-07-09aRagexe_zero, 2019-07-10_3aRagexe_zero, 2019-07-17aRagexe_zero, 2019-07-24aRagexe_zero, 2019-08-14_3aRagexe_zero, 2019-08-28_2aRagexe_zero, 2019-08-28_3aRagexe_zero, 2019-09-11aRagexe_zero, 2019-09-18_2aRagexe_zero, 2019-09-18aRagexe_zero, 2019-09-25_3aRagexe_zero, 2019-09-25_5aRagexe_zero, 2019-10-08_2aRagexe_zero, 2019-10-23_2aRagexe_zero, 2019-11-06aRagexe_zero, 2019-11-13aRagexe_zero, 2019-11-27_2aRagexe_zero, 2019-11-27aRagexe_zero, 2019-12-04aRagexe_zero, 2019-12-11_2aRagexe_zero, 2019-12-24_4aRagexe_zero, 2019-12-24_5aRagexe_zero, 2020-01-15_2aRagexe_zero, 2020-01-15aRagexe_zero, 2020-01-29_2aRagexe_zero, 2020-01-29aRagexe_zero, 2020-02-12aRagexe_zero, 2020-02-26aRagexe_zero, 2020-02-26bRagexe_zero, 2020-03-04aRagexe_zero, 2020-03-18_2aRagexe_zero, 2020-04-01_2aRagexe_zero, 2020-04-14bRagexe_zero, 2020-05-06aRagexe_zero, 2020-05-20_5aRagexe_zero, 2020-06-03_2aRagexe_zero, 2020-06-17aRagexe_zero, 2020-07-01_2aRagexe_zero, 2020-07-01aRagexe_zero
#if PACKETVER == 20171018 || \
PACKETVER == 20171019 || \
PACKETVER == 20171023 || \
@@ -120,7 +120,10 @@
PACKETVER == 20200401 || \
PACKETVER == 20200414 || \
PACKETVER == 20200506 || \
- PACKETVER >= 20200520
+ PACKETVER == 20200520 || \
+ PACKETVER == 20200603 || \
+ PACKETVER == 20200617 || \
+ PACKETVER >= 20200701
packet(0x0202,clif->pFriendsListAdd,2);
packet(0x022d,clif->pHomMenu,2,4);
packet(0x023b,clif->pStoragePassword,0);
diff --git a/src/map/packets_struct.h b/src/map/packets_struct.h
index 3129a05d9..031a23b6d 100644
--- a/src/map/packets_struct.h
+++ b/src/map/packets_struct.h
@@ -3927,6 +3927,24 @@ struct PACKET_CZ_LAPINEUPGRADE_MAKE_ITEM {
DEFINE_PACKET_HEADER(CZ_LAPINEUPGRADE_MAKE_ITEM, 0x0ab6);
#endif // PACKETVER_MAIN_NUM >= 20170111 || PACKETVER_RE_NUM >= 20170111 || defined(PACKETVER_ZERO)
+#if PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
+struct PACKET_ZC_PERSONAL_INFOMATION_SUB {
+ int8 type;
+ int32 exp;
+ int32 death;
+ int32 drop;
+} __attribute__((packed));
+struct PACKET_ZC_PERSONAL_INFOMATION {
+ int16 packetType;
+ int16 length;
+ int32 total_exp;
+ int32 total_death;
+ int32 total_drop;
+ struct PACKET_ZC_PERSONAL_INFOMATION_SUB details[];
+} __attribute__((packed));
+DEFINE_PACKET_HEADER(ZC_PERSONAL_INFOMATION, 0x097b);
+#endif // PACKETVER_MAIN_NUM >= 20120503 || PACKETVER_RE_NUM >= 20120502 || defined(PACKETVER_ZERO)
+
#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/party.c b/src/map/party.c
index 8eeae2215..5eecd3fe6 100644
--- a/src/map/party.c
+++ b/src/map/party.c
@@ -330,6 +330,8 @@ static int party_recv_info(const struct party *sp, int char_id)
party->member_withdraw(sp->party_id, sd->status.account_id, sd->status.char_id);
}
+ int option_auto_changed = p->state.option_auto_changed; // Preserve state.
+
memcpy(&p->party, sp, sizeof(struct party));
memset(&p->state, 0, sizeof(p->state));
memset(&p->data, 0, sizeof(p->data));
@@ -342,6 +344,7 @@ static int party_recv_info(const struct party *sp, int char_id)
p->party.member[member_id].leader = 1;
}
party->check_state(p);
+ p->state.option_auto_changed = option_auto_changed;
while( added_count > 0 ) { // new in party
member_id = added[--added_count];
sd = p->data[member_id].sd;
@@ -349,12 +352,9 @@ static int party_recv_info(const struct party *sp, int char_id)
continue;// not online
clif->charnameupdate(sd); //Update other people's display. [Skotlex]
clif->party_member_info(p,sd);
- clif->party_option(p,sd,0x100);
clif->party_info(p,NULL);
for( j = 0; j < p->instances; j++ ) {
if( p->instance[j] >= 0 ) {
- if( instance->list[p->instance[j]].idle_timer == INVALID_TIMER && instance->list[p->instance[j]].progress_timer == INVALID_TIMER )
- continue;
clif->instance_join(sd->fd, p->instance[j]);
break;
}
@@ -488,14 +488,14 @@ static void party_member_joined(struct map_session_data *sd)
p->data[i].sd = sd;
for( j = 0; j < p->instances; j++ ) {
if( p->instance[j] >= 0 ) {
- if( instance->list[p->instance[j]].idle_timer == INVALID_TIMER && instance->list[p->instance[j]].progress_timer == INVALID_TIMER )
- continue;
clif->instance_join(sd->fd, p->instance[j]);
break;
}
}
} else
sd->status.party_id = 0; //He does not belongs to the party really?
+
+ party->send_movemap(sd);
}
/// Invoked (from char-server) when a new member is added to the party.
@@ -536,6 +536,11 @@ static int party_member_added(int party_id, int account_id, int char_id, int fla
clif->party_member_info(p,sd);
clif->party_info(p,sd);
+ if (p->state.option_auto_changed != 0)
+ clif->party_option(p, sd, 0x04);
+ else
+ clif->party_option(p, sd, 0x08);
+
if( sd2 != NULL )
clif->party_inviteack(sd2,sd->status.name,2);
@@ -551,8 +556,6 @@ static int party_member_added(int party_id, int account_id, int char_id, int fla
for( j = 0; j < p->instances; j++ ) {
if( p->instance[j] >= 0 ) {
- if( instance->list[p->instance[j]].idle_timer == INVALID_TIMER && instance->list[p->instance[j]].progress_timer == INVALID_TIMER )
- continue;
clif->instance_join(sd->fd, p->instance[j]);
break;
}
@@ -622,6 +625,7 @@ static int party_member_withdraw(int party_id, int account_id, int char_id)
prev_leader_accountId = p->party.member[i].account_id;
}
+ clif->party_option(p, sd, 0x10);
clif->party_withdraw(p,sd,account_id,p->party.member[i].name,0x0);
memset(&p->party.member[i], 0, sizeof(p->party.member[0]));
memset(&p->data[i], 0, sizeof(p->data[0]));
@@ -729,8 +733,17 @@ static int party_optionchanged(int party_id, int account_id, int exp, int item,
//Flag&0x1: Exp change denied. Flag&0x10: Item change denied.
if(!(flag&0x01) && p->party.exp != exp)
p->party.exp=exp;
- if(!(flag&0x10) && p->party.item != item) {
+ if (p->party.item != item)
p->party.item=item;
+
+ if (account_id == 0) {
+ flag |= 0x04;
+ p->state.option_auto_changed = 1;
+
+ if (p->state.member_level_changed == 0)
+ return 0; // clif_party_option() is handled in clif_parse_LoadEndAck().
+ } else {
+ flag |= 0x02;
}
clif->party_option(p,sd,flag);
@@ -811,7 +824,8 @@ static int party_recv_movemap(int party_id, int account_id, int char_id, unsigne
ShowError("party_recv_movemap: char %d/%d not found in party %s (id:%d)",account_id,char_id,p->party.name,party_id);
return 0;
}
-
+
+ p->state.member_level_changed = 0;
m = &p->party.member[i];
m->map = mapid;
m->online = online;
@@ -860,7 +874,12 @@ static void party_send_movemap(struct map_session_data *sd)
static void party_send_levelup(struct map_session_data *sd)
{
- intif->party_changemap(sd,1);
+ struct party_data *p = party->search(sd->status.party_id);
+
+ if (p != NULL)
+ p->state.member_level_changed = 1;
+
+ intif->party_changemap(sd, 1);
}
static int party_send_logout(struct map_session_data *sd)
diff --git a/src/map/party.h b/src/map/party.h
index c2306b7a8..5f3458cd4 100644
--- a/src/map/party.h
+++ b/src/map/party.h
@@ -51,6 +51,8 @@ struct party_data {
unsigned sg : 1; ///< There's at least one Star Gladiator in party?
unsigned snovice :1; ///< There's a Super Novice
unsigned tk : 1; ///< There's a taekwon
+ unsigned option_auto_changed : 1; ///< Party options were changed automatically. (inter_party_check_lv())
+ unsigned member_level_changed : 1; ///< A party member's level has changed.
} state;
struct hplugin_data_store *hdata; ///< HPM Plugin Data Store
};
diff --git a/src/map/pc.c b/src/map/pc.c
index c1261c839..04c3cd1cb 100644
--- a/src/map/pc.c
+++ b/src/map/pc.c
@@ -5163,7 +5163,7 @@ static int pc_useitem(struct map_session_data *sd, int n)
nullpo_ret(sd);
Assert_ret(n >= 0 && n < sd->status.inventorySize);
- if ((sd->npc_id != 0 && (sd->npc_item_flag & ITEMENABLEDNPC_CONSUME) == 0)
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0 && (sd->npc_item_flag & ITEMENABLEDNPC_CONSUME) == 0)
|| (sd->state.workinprogress & 1) != 0) {
#if PACKETVER >= 20110308
clif->msgtable(sd, MSG_BUSY);
@@ -5190,6 +5190,16 @@ static int pc_useitem(struct map_session_data *sd, int n)
// Store information for later use before it is lost (via pc->delitem) [Paradox924X]
nameid = sd->inventory_data[n]->nameid;
+ if (nameid == ITEMID_MEGAPHONE && ((sd->state.workinprogress & 2) != 0 || sd->state.using_megaphone != 0
+ || sd->npc_id != 0)) {
+#if PACKETVER >= 20110308
+ clif->msgtable(sd, MSG_BUSY);
+#else
+ clif->messagecolor_self(sd->fd, COLOR_WHITE, msg_sd(sd, 48));
+#endif
+ return 0;
+ }
+
if (nameid != ITEMID_NAUTHIZ && sd->sc.opt1 > 0 && sd->sc.opt1 != OPT1_STONEWAIT && sd->sc.opt1 != OPT1_BURNING)
return 0;
@@ -5320,6 +5330,9 @@ static int pc_useitem(struct map_session_data *sd, int n)
// Update item use time.
sd->canuseitem_tick = tick + battle_config.item_use_interval;
+ if (nameid == ITEMID_MEGAPHONE)
+ sd->state.using_megaphone = 1;
+
script->run_use_script(sd, sd->inventory_data[n], npc->fake_nd->bl.id);
script->potion_flag = 0;
@@ -7237,8 +7250,8 @@ static bool pc_gainexp(struct map_session_data *sd, struct block_list *src, uint
if(sd->state.showexp) {
char output[256];
sprintf(output,
- msg_sd(sd, 889), // Experience Gained Base:%"PRIu64" (%.2f%%) Job:%"PRIu64" (%.2f%%)
- base_exp, nextbp * (float)100, job_exp, nextjp * (float)100);
+ msg_sd(sd, 889), // Experience Gained Base:%llu (%.2f%%) Job:%llu (%.2f%%)
+ (unsigned long long)base_exp, nextbp * 100.0f, (unsigned long long)job_exp, nextjp * 100.0f);
clif_disp_onlyself(sd, output);
}
@@ -8148,12 +8161,10 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src)
if (sd->status.pet_id > 0 && sd->pd != NULL) {
struct pet_data *pd = sd->pd;
- if (map->list[sd->bl.m].flag.noexppenalty == 0) {
+ if (map->list[sd->bl.m].flag.noexppenalty == 0)
pet->set_intimate(pd, pd->pet.intimate - pd->petDB->die);
- clif->send_petdata(sd, sd->pd, 1, pd->pet.intimate);
- }
- if (sd->pd->target_id != 0) // Unlock all targets.
+ if (sd->pd != NULL && sd->pd->target_id != 0) // Unlock all targets.
pet->unlocktarget(sd->pd);
}
@@ -8173,7 +8184,7 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src)
duel->reject(sd->duel_invite, sd);
}
- if (sd->npc_id != 0 && sd->st != NULL && sd->st->state != RUN)
+ if (sd->npc_id != 0 && sd->state.using_megaphone == 0 && sd->st != NULL && sd->st->state != RUN)
npc->event_dequeue(sd);
pc_setglobalreg(sd, script->add_variable("PC_DIE_COUNTER"), sd->die_counter + 1);
@@ -8196,7 +8207,7 @@ static int pc_dead(struct map_session_data *sd, struct block_list *src)
npc->script_event(sd, NPCE_DIE);
// Clear anything NPC-related if character died while interacting with one.
- if ((sd->npc_id != 0 || sd->npc_shopid != 0) && sd->state.dialog != 0) {
+ if (((sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->npc_shopid != 0) && sd->state.dialog != 0) {
if (sd->state.using_fake_npc != 0) {
clif->clearunit_single(sd->npc_id, CLR_OUTSIGHT, sd->fd);
sd->state.using_fake_npc = 0;
@@ -12117,7 +12128,6 @@ static void pc_scdata_received(struct map_session_data *sd)
{
nullpo_retv(sd);
pc->inventory_rentals(sd);
- clif->show_modifiers(sd);
if (sd->expiration_time != 0) { // don't display if it's unlimited or unknow value
time_t exp_time = sd->expiration_time;
diff --git a/src/map/pc.h b/src/map/pc.h
index f2e911af3..e8e591b09 100644
--- a/src/map/pc.h
+++ b/src/map/pc.h
@@ -224,6 +224,7 @@ struct map_session_data {
unsigned int size :2; // for tiny/large types
unsigned int night :1; //Holds whether or not the player currently has the SI_NIGHT effect on. [Skotlex]
unsigned int using_fake_npc :1;
+ unsigned int using_megaphone : 1; //!< Whether the character is currently using a Megephone (ID=12221).
unsigned int rewarp :1; //Signals that a player should warp as soon as he is done loading a map. [Skotlex]
unsigned int killer : 1;
unsigned int killable : 1;
@@ -681,9 +682,11 @@ END_ZEROED_BLOCK;
#define pc_issit(sd) ( (sd)->vd.dead_sit == 2 )
#define pc_isidle(sd) ( (sd)->chat_id != 0 || (sd)->state.vending || (sd)->state.buyingstore || DIFF_TICK(sockt->last_tick, (sd)->idletime) >= battle->bc->idle_no_share )
#define pc_istrading(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->state.trading )
+#define pc_istrading_except_npc(sd) ( (sd)->state.vending != 0 || (sd)->state.buyingstore != 0 || (sd)->state.trading != 0 )
#define pc_cant_act(sd) ( (sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
#define pc_cant_act_except_lapine(sd) ((sd)->npc_id || (sd)->state.vending || (sd)->state.buyingstore || (sd)->chat_id != 0 || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1)
#define pc_cant_act_except_npc(sd) ( (sd)->state.vending != 0 || (sd)->state.buyingstore != 0 || (sd)->chat_id != 0 || ((sd)->sc.opt1 != 0 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading != 0 || (sd)->state.storage_flag != 0 || (sd)->state.prevend != 0 || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
+#define pc_cant_act_except_npc_chat(sd) ( (sd)->state.vending != 0 || (sd)->state.buyingstore != 0 || ((sd)->sc.opt1 != 0 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading != 0 || (sd)->state.storage_flag != 0 || (sd)->state.prevend != 0 || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
/* equals pc_cant_act except it doesn't check for chat rooms */
#define pc_cant_act2(sd) ( (sd)->npc_id || (sd)->state.buyingstore || ((sd)->sc.opt1 && (sd)->sc.opt1 != OPT1_BURNING) || (sd)->state.trading || (sd)->state.storage_flag || (sd)->state.prevend || (sd)->state.refine_ui == 1 || (sd)->state.lapine_ui == 1)
@@ -727,6 +730,9 @@ END_ZEROED_BLOCK;
/// Rune Knight Dragon
#define pc_isridingdragon(sd) ( (sd)->sc.option&OPTION_DRAGON )
+// Check if character has a pet.
+#define pc_has_pet(sd) ( (sd)->status.pet_id != 0 && (sd)->pd != NULL && (sd)->pd->pet.intimate > PET_INTIMACY_NONE )
+
#define pc_stop_walking(sd, type) (unit->stop_walking(&(sd)->bl, (type)))
#define pc_stop_attack(sd) (unit->stop_attack(&(sd)->bl))
@@ -873,6 +879,12 @@ struct class_exp_tables {
struct class_exp_group *class_exp_table[CLASS_COUNT][2];
};
+enum player_actions_when_dead_flags {
+ PCALLOWACTION_NONE = 0x0, // Don't allow trading and open chat rooms.
+ PCALLOWACTION_TRADE = 0x1, // Allow trading when dead.
+ PCALLOWACTION_CHAT = 0x2, // Allow open chat room when dead.
+};
+
/*=====================================
* Interface : pc.h
* Generated by HerculesInterfaceMaker
diff --git a/src/map/pet.c b/src/map/pet.c
index 2a9831ed6..f10c55f57 100644
--- a/src/map/pet.c
+++ b/src/map/pet.c
@@ -94,8 +94,41 @@ static int pet_hungry_val(struct pet_data *pd)
static void pet_set_hunger(struct pet_data *pd, int value)
{
nullpo_retv(pd);
+ nullpo_retv(pd->msd);
pd->pet.hungry = cap_value(value, PET_HUNGER_STARVING, PET_HUNGER_STUFFED);
+
+ clif->send_petdata(pd->msd, pd, 2, pd->pet.hungry);
+}
+
+/**
+ * Calculates the value to store in a pet egg's 4th card slot
+ * based on the passed rename flag and intimacy value.
+ *
+ * @param rename_flag The pet's rename flag.
+ * @param intimacy The pet's intimacy value.
+ * @return The value to store in the pet egg's 4th card slot. (Defaults to 0 in case of error.)
+ *
+ **/
+static int pet_get_card4_value(int rename_flag, int intimacy)
+{
+ Assert_ret(rename_flag == 0 || rename_flag == 1);
+ Assert_ret(intimacy >= PET_INTIMACY_NONE && intimacy <= PET_INTIMACY_MAX);
+
+ int card4 = rename_flag;
+
+ if (intimacy <= PET_INTIMACY_SHY)
+ card4 |= (1 << 1);
+ else if (intimacy <= PET_INTIMACY_NEUTRAL)
+ card4 |= (2 << 1);
+ else if (intimacy <= PET_INTIMACY_CORDIAL)
+ card4 |= (3 << 1);
+ else if (intimacy <= PET_INTIMACY_LOYAL)
+ card4 |= (4 << 1);
+ else
+ card4 |= (5 << 1);
+
+ return card4;
}
/**
@@ -115,18 +148,24 @@ static void pet_set_intimate(struct pet_data *pd, int value)
struct map_session_data *sd = pd->msd;
- status_calc_pc(sd, SCO_NONE);
-
- if (pd->pet.intimate == PET_INTIMACY_NONE) { /// Pet is lost. Delete the egg.
+ if (pd->pet.intimate == PET_INTIMACY_NONE) { // Pet is lost, delete it.
int i;
ARR_FIND(0, sd->status.inventorySize, i, sd->status.inventory[i].card[0] == CARD0_PET
- && pd->pet.pet_id == MakeDWord(sd->status.inventory[i].card[1],
- sd->status.inventory[i].card[2]));
+ && pd->pet.pet_id == MakeDWord(sd->status.inventory[i].card[1], sd->status.inventory[i].card[2]));
if (i != sd->status.inventorySize)
pc->delitem(sd, i, 1, 0, DELITEM_NORMAL, LOG_TYPE_EGG);
+
+ if (battle_config.pet_remove_immediately != 0) {
+ pet_stop_attack(pd);
+ unit->remove_map(&pd->bl, CLR_OUTSIGHT, ALC_MARK);
+ }
+ } else {
+ clif->send_petdata(sd, pd, 1, pd->pet.intimate);
}
+
+ status_calc_pc(sd, SCO_NONE);
}
/**
@@ -312,17 +351,15 @@ static int pet_hungry(int tid, int64 tick, int id, intptr_t data)
pet_stop_attack(pd);
pet->set_intimate(pd, pd->pet.intimate - pd->petDB->starving_decrement);
- if (pd->pet.intimate == PET_INTIMACY_NONE)
- pd->status.speed = pd->db->status.speed;
+ if (sd->pd == NULL)
+ return 0;
status_calc_pet(pd, SCO_NONE);
- clif->send_petdata(sd, pd, 1, pd->pet.intimate);
if (pd->petDB->starving_delay > 0)
interval = pd->petDB->starving_delay;
}
- clif->send_petdata(sd, pd, 2, pd->pet.hungry);
interval = interval * battle_config.pet_hungry_delay_rate / 100;
pd->pet_hungry_timer = timer->add(tick + max(interval, 1), pet->hungry, sd->bl.id, 0);
@@ -404,7 +441,8 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
if (i != sd->status.inventorySize) {
sd->status.inventory[i].attribute &= ~ATTR_BROKEN;
sd->status.inventory[i].bound = IBT_NONE;
- sd->status.inventory[i].card[3] = pd->pet.rename_flag;
+ sd->status.inventory[i].card[3] = pet->get_card4_value(pd->pet.rename_flag, pd->pet.intimate);
+ clif->inventoryList(sd);
} else {
// The pet egg wasn't found: it was probably hatched with the old system that deleted the egg.
struct item tmp_item = {0};
@@ -415,14 +453,13 @@ static int pet_return_egg(struct map_session_data *sd, struct pet_data *pd)
tmp_item.card[0] = CARD0_PET;
tmp_item.card[1] = GetWord(pd->pet.pet_id, 0);
tmp_item.card[2] = GetWord(pd->pet.pet_id, 1);
- tmp_item.card[3] = pd->pet.rename_flag;
+ tmp_item.card[3] = pet->get_card4_value(pd->pet.rename_flag, pd->pet.intimate);
if ((flag = pc->additem(sd, &tmp_item, 1, LOG_TYPE_EGG)) != 0) {
clif->additem(sd, 0, 0, flag);
map->addflooritem(&sd->bl, &tmp_item, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
}
}
#if PACKETVER >= 20180704
- clif->inventoryList(sd);
clif->send_petdata(sd, pd, 6, 0);
#endif
pd->pet.incubate = 1;
@@ -511,6 +548,35 @@ static int pet_data_init(struct map_session_data *sd, struct s_pet *petinfo)
return 0;
}
+/**
+ * Spawns a pet.
+ *
+ * @param sd The pet's master.
+ * @param birth_process Whether the pet is spawned during birth process.
+ * @return 1 on failure, 0 on success.
+ *
+ **/
+static int pet_spawn(struct map_session_data *sd, bool birth_process)
+{
+ nullpo_retr(1, sd);
+ nullpo_retr(1, sd->pd);
+
+ if (map->addblock(&sd->pd->bl) != 0 || !clif->spawn(&sd->pd->bl))
+ return 1;
+
+ clif->send_petdata(sd, sd->pd, 0, 0);
+ clif->send_petdata(sd, sd->pd, 5, battle_config.pet_hair_style);
+
+#if PACKETVER >= 20180704
+ if (birth_process)
+ clif->send_petdata(sd, sd->pd, 6, 1);
+#endif
+
+ clif->send_petstatus(sd);
+
+ return 0;
+}
+
static int pet_birth_process(struct map_session_data *sd, struct s_pet *petinfo)
{
nullpo_retr(1, sd);
@@ -535,17 +601,11 @@ static int pet_birth_process(struct map_session_data *sd, struct s_pet *petinfo)
if (map->save_settings&8)
chrif->save(sd,0); //is it REALLY Needed to save the char for hatching a pet? [Skotlex]
- if(sd->bl.prev != NULL) {
- map->addblock(&sd->pd->bl);
- clif->spawn(&sd->pd->bl);
- clif->send_petdata(sd,sd->pd, 0,0);
- clif->send_petdata(sd,sd->pd, 5,battle_config.pet_hair_style);
-#if PACKETVER >= 20180704
- clif->send_petdata(sd, sd->pd, 6, 1);
-#endif
- clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
- clif->send_petstatus(sd);
+ if (sd->pd != NULL && sd->bl.prev != NULL) {
+ if (pet->spawn(sd, true) != 0)
+ return 1;
}
+
Assert_retr(1, sd->status.pet_id == 0 || sd->pd == 0 || sd->pd->msd == sd);
return 0;
@@ -584,13 +644,9 @@ static int pet_recv_petdata(int account_id, struct s_pet *p, int flag)
}
} else {
pet->data_init(sd,p);
- if(sd->pd && sd->bl.prev != NULL) {
- map->addblock(&sd->pd->bl);
- clif->spawn(&sd->pd->bl);
- clif->send_petdata(sd,sd->pd,0,0);
- clif->send_petdata(sd,sd->pd,5,battle_config.pet_hair_style);
- clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
- clif->send_petstatus(sd);
+ if (sd->pd != NULL && sd->bl.prev != NULL) {
+ if (pet->spawn(sd, false) != 0)
+ return 1;
}
}
@@ -644,8 +700,6 @@ static int pet_catch_process2(struct map_session_data *sd, int target_id)
return 1;
}
- //FIXME: Delete taming item here, if this was an item-invoked capture and the item was flagged as delay-consume. [ultramage]
-
// catch_target_class == 0 is used for universal lures (except bosses for now). [Skotlex]
if (sd->catch_target_class == 0 && (md->status.mode & MD_BOSS) == 0)
sd->catch_target_class = md->class_;
@@ -729,7 +783,7 @@ static bool pet_get_egg(int account_id, int pet_class, int pet_id)
tmp_item.card[0] = CARD0_PET;
tmp_item.card[1] = GetWord(pet_id,0);
tmp_item.card[2] = GetWord(pet_id,1);
- tmp_item.card[3] = 0; //New pets are not named.
+ tmp_item.card[3] = pet->get_card4_value(0, pet->db[i].intimate);
if((ret = pc->additem(sd,&tmp_item,1,LOG_TYPE_PICKDROP_PLAYER))) {
clif->additem(sd,0,0,ret);
map->addflooritem(&sd->bl, &tmp_item, 1, sd->bl.m, sd->bl.x, sd->bl.y, 0, 0, 0, 0, false);
@@ -828,8 +882,6 @@ static int pet_change_name_ack(struct map_session_data *sd, const char *name, in
aFree(newname);
clif->blname_ack(0,&pd->bl);
pd->pet.rename_flag = 1;
- clif->send_petdata(NULL, sd->pd, 3, sd->pd->vd.head_bottom);
- clif->send_petstatus(sd);
return 1;
}
@@ -920,6 +972,7 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
{
nullpo_retr(1, sd);
nullpo_retr(1, pd);
+ Assert_retr(1, sd->status.pet_id == pd->pet.pet_id);
int i = pc->search_inventory(sd, pd->petDB->FoodID);
@@ -948,15 +1001,11 @@ static int pet_food(struct map_session_data *sd, struct pet_data *pd)
intimacy = intimacy * battle_config.pet_friendly_rate / 100;
pet->set_intimate(pd, pd->pet.intimate + intimacy);
- if (pd->pet.intimate == PET_INTIMACY_NONE) {
- pet_stop_attack(pd);
- pd->status.speed = pd->db->status.speed;
- }
+ if (sd->pd == NULL)
+ return 0;
status_calc_pet(pd, SCO_NONE);
pet->set_hunger(pd, pd->pet.hungry + pd->petDB->fullness);
- clif->send_petdata(sd, pd, 2, pd->pet.hungry);
- clif->send_petdata(sd, pd, 1, pd->pet.intimate);
clif->pet_food(sd, pd->petDB->FoodID, 1);
return 0;
@@ -1799,6 +1848,7 @@ void pet_defaults(void)
pet->hungry_val = pet_hungry_val;
pet->set_hunger = pet_set_hunger;
+ pet->get_card4_value = pet_get_card4_value;
pet->set_intimate = pet_set_intimate;
pet->create_egg = pet_create_egg;
pet->unlocktarget = pet_unlocktarget;
@@ -1811,6 +1861,7 @@ void pet_defaults(void)
pet->performance = pet_performance;
pet->return_egg = pet_return_egg;
pet->data_init = pet_data_init;
+ pet->spawn = pet_spawn;
pet->birth_process = pet_birth_process;
pet->recv_petdata = pet_recv_petdata;
pet->select_egg = pet_select_egg;
diff --git a/src/map/pet.h b/src/map/pet.h
index fa37e896a..c57df9de3 100644
--- a/src/map/pet.h
+++ b/src/map/pet.h
@@ -147,6 +147,7 @@ struct pet_interface {
/* */
int (*hungry_val) (struct pet_data *pd);
void (*set_hunger) (struct pet_data *pd, int value);
+ int (*get_card4_value) (int rename_flag, int intimacy);
void (*set_intimate) (struct pet_data *pd, int value);
int (*create_egg) (struct map_session_data *sd, int item_id);
int (*unlocktarget) (struct pet_data *pd);
@@ -159,6 +160,7 @@ struct pet_interface {
int (*performance) (struct map_session_data *sd, struct pet_data *pd);
int (*return_egg) (struct map_session_data *sd, struct pet_data *pd);
int (*data_init) (struct map_session_data *sd, struct s_pet *petinfo);
+ int (*spawn) (struct map_session_data *sd, bool birth_process);
int (*birth_process) (struct map_session_data *sd, struct s_pet *petinfo);
int (*recv_petdata) (int account_id, struct s_pet *p, int flag);
int (*select_egg) (struct map_session_data *sd, int egg_index);
diff --git a/src/map/rodex.c b/src/map/rodex.c
index 1ebed0623..f2bb8a0d4 100644
--- a/src/map/rodex.c
+++ b/src/map/rodex.c
@@ -231,7 +231,7 @@ static int rodex_send_mail(struct map_session_data *sd, const char *receiver_nam
nullpo_retr(RODEX_SEND_MAIL_FATAL_ERROR, body);
nullpo_retr(RODEX_SEND_MAIL_FATAL_ERROR, title);
- if (!rodex->isenabled() || sd->npc_id > 0) {
+ if (!rodex->isenabled() || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
rodex->clean(sd, 1);
return RODEX_SEND_MAIL_FATAL_ERROR;
}
@@ -575,6 +575,7 @@ static void rodex_clean(struct map_session_data *sd, int8 flag)
if (flag == 0)
VECTOR_CLEAR(sd->rodex.messages);
+ sd->state.workinprogress &= ~2;
memset(&sd->rodex.tmp, 0x0, sizeof(sd->rodex.tmp));
}
diff --git a/src/map/script.c b/src/map/script.c
index 743a1779a..9372299bb 100644
--- a/src/map/script.c
+++ b/src/map/script.c
@@ -11272,7 +11272,8 @@ static BUILDIN(gettimetick)
case 0:
default:
//type 0:(System Ticks)
- script_pushint(st,(int)timer->gettick()); // TODO: change this to int64 when we'll support 64 bit script values
+ // Conjunction with INT_MAX is done to prevent overflow. (Script variables are signed integers.)
+ script_pushint(st, timer->gettick() & INT_MAX); // TODO: change this to int64 when we'll support 64 bit script values
break;
}
return true;
@@ -12574,6 +12575,8 @@ static BUILDIN(loudhailer)
clif->broadcast(&sd->bl, mes_formatted, (int)len_formatted, BC_MEGAPHONE, ALL_CLIENT);
+ sd->state.using_megaphone = 0;
+
return true;
}
@@ -14043,6 +14046,7 @@ static BUILDIN(getmapflag)
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;
+ case MF_NOPET: script_pushint(st, map->list[m].flag.nopet); break;
}
}
@@ -14175,6 +14179,7 @@ static BUILDIN(setmapflag)
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;
+ case MF_NOPET: map->list[m].flag.nopet = 1; break;
}
}
@@ -14268,6 +14273,7 @@ static BUILDIN(removemapflag)
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;
+ case MF_NOPET: map->list[m].flag.nopet = 0; break;
}
}
@@ -20518,6 +20524,8 @@ static BUILDIN(setunitdata)
break;
case UDT_LEVEL:
pd->pet.level = (short)val;
+ if (pd->msd != NULL)
+ clif->send_petstatus(pd->msd); // Send pet data.
break;
case UDT_HP:
status->set_hp(bl, (unsigned int)val, STATUS_HEAL_DEFAULT);
@@ -20629,7 +20637,6 @@ static BUILDIN(setunitdata)
break;
case UDT_INTIMACY:
pet->set_intimate(pd, val);
- clif->send_petdata(pd->msd, pd, 1, pd->pet.intimate);
break;
case UDT_HUNGER:
pet->set_hunger(pd, val);
@@ -20640,7 +20647,6 @@ static BUILDIN(setunitdata)
return false;
}
- clif->send_petstatus(pd->msd); // Send pet data.
break;
}
case BL_MER: {
@@ -28358,6 +28364,11 @@ static void script_hardcoded_constants(void)
script->set_constant("P_AIRSHIP_INVALID_END_MAP", P_AIRSHIP_INVALID_END_MAP, false, false);
script->set_constant("P_AIRSHIP_ITEM_NOT_ENOUGH", P_AIRSHIP_ITEM_NOT_ENOUGH, false, false);
script->set_constant("P_AIRSHIP_ITEM_INVALID", P_AIRSHIP_ITEM_INVALID, false, false);
+
+ script->constdb_comment("player allowed actions when dead");
+ script->set_constant("PCALLOWACTION_NONE", PCALLOWACTION_NONE, false, false);
+ script->set_constant("PCALLOWACTION_TRADE", PCALLOWACTION_TRADE, false, false);
+ script->set_constant("PCALLOWACTION_CHAT", PCALLOWACTION_CHAT, false, false);
script->constdb_comment("questinfo types");
script->set_constant("QINFO_JOB", QINFO_JOB, false, false);
diff --git a/src/map/script.h b/src/map/script.h
index df5297ac0..60f403d2d 100644
--- a/src/map/script.h
+++ b/src/map/script.h
@@ -345,7 +345,8 @@ enum {
MF_PAIRSHIP_STARTABLE,
MF_PAIRSHIP_ENDABLE,
MF_NOSTORAGE,
- MF_NOGSTORAGE
+ MF_NOGSTORAGE,
+ MF_NOPET,
};
enum navigation_service {
@@ -703,7 +704,7 @@ struct script_state {
int bk_npcid;
unsigned freeloop : 1;// used by buildin_freeloop
unsigned op2ref : 1;// used by op_2
- unsigned npc_item_flag : 1;
+ unsigned npc_item_flag : 2;
unsigned int id;
};
diff --git a/src/map/skill.c b/src/map/skill.c
index 24fbe7892..c2a336d7e 100644
--- a/src/map/skill.c
+++ b/src/map/skill.c
@@ -47,6 +47,7 @@
#include "map/refine.h"
#include "map/script.h"
#include "map/status.h"
+#include "map/storage.h"
#include "map/unit.h"
#include "common/cbasetypes.h"
#include "common/ers.h"
@@ -370,6 +371,41 @@ static int skill_get_spiritball(int skill_id, int skill_lv)
}
/**
+ * Gets the index of the first required item for a skill at given level.
+ *
+ * @param skill_id The skill's ID.
+ * @param skill_lv The skill's level.
+ * @return The required item's index. Defaults to INDEX_NOT_FOUND (-1) in case of error or if no appropriate index was found.
+ *
+ **/
+static int skill_get_item_index(int skill_id, int skill_lv)
+{
+ if (skill_id == 0)
+ return INDEX_NOT_FOUND;
+
+ Assert_retr(INDEX_NOT_FOUND, skill_lv > 0);
+
+ int idx = skill->get_index(skill_id);
+
+ Assert_retr(INDEX_NOT_FOUND, idx != 0);
+
+ int item_index = INDEX_NOT_FOUND;
+ int level_index = skill_get_lvl_idx(skill_lv);
+
+ for (int i = 0; i < MAX_SKILL_ITEM_REQUIRE; i++) {
+ if (skill->dbs->db[idx].req_items.item[i].id == 0)
+ continue;
+
+ if (skill->dbs->db[idx].req_items.item[i].amount[level_index] != -1) {
+ item_index = i;
+ break;
+ }
+ }
+
+ return item_index;
+}
+
+/**
* Gets a skill's required item's ID by the skill's ID and the item's index.
*
* @param skill_id The skill's ID.
@@ -1613,11 +1649,15 @@ static int skill_additional_effect(struct block_list *src, struct block_list *bl
if( pc_iswug(sd) && (temp=pc->checkskill(sd,RA_WUGSTRIKE)) > 0 && rnd()%1000 <= sstatus->luk*3 )
skill->castend_damage_id(src,bl,RA_WUGSTRIKE,temp,tick,0);
// Gank
- if(dstmd && sd->weapontype != W_BOW &&
- (temp=pc->checkskill(sd,RG_SNATCHER)) > 0 &&
- (temp*15 + 55) + pc->checkskill(sd,TF_STEAL)*10 > rnd()%1000) {
- if(pc->steal_item(sd,bl,pc->checkskill(sd,TF_STEAL)))
- clif->skill_nodamage(src,bl,TF_STEAL,temp,1);
+ if (dstmd && sd->weapontype != W_BOW &&
+ (temp = pc->checkskill(sd, RG_SNATCHER)) > 0 &&
+#ifdef RENEWAL
+ (temp * 10) + pc->checkskill(sd, TF_STEAL) * 10 > rnd() % 1000) {
+#else
+ (temp * 15 + 55) + pc->checkskill(sd, TF_STEAL) * 10 > rnd() % 1000) {
+#endif
+ if (pc->steal_item(sd, bl, pc->checkskill(sd, TF_STEAL)))
+ clif->skill_nodamage(src, bl, TF_STEAL, temp, 1);
else
clif->skill_fail(sd, RG_SNATCHER, USESKILL_FAIL_LEVEL, 0, 0);
}
@@ -7937,7 +7977,14 @@ static int skill_castend_nodamage_id(struct block_list *src, struct block_list *
}
if( sd ) {
int bonus = 100, potion = min(500+skill_lv,505);
- int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE;
+ int item_idx = skill->get_item_index(skill_id, skill_lv);
+
+ if (item_idx == INDEX_NOT_FOUND) {
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0);
+ map->freeblock_unlock();
+ return 1;
+ }
+
int item_id = skill->get_itemid(skill_id, item_idx);
int inventory_idx = pc->search_inventory(sd, item_id);
if (inventory_idx == INDEX_NOT_FOUND || item_id <= 0) {
@@ -11312,17 +11359,21 @@ static int skill_castend_map(struct map_session_data *sd, uint16 skill_id, const
return 0;
}
- switch(skill_id) {
+ switch (skill_id) {
case AL_TELEPORT:
- // The storage window is closed automatically by the client when there's
- // any kind of map change, so we need to restore it automatically
- // issue: 8027
- if(strcmp(mapname,"Random")==0)
- pc->randomwarp(sd,CLR_TELEPORT);
- else if (sd->menuskill_val > 1) //Need lv2 to be able to warp here.
- pc->setpos(sd,sd->status.save_point.map,sd->status.save_point.x,sd->status.save_point.y,CLR_TELEPORT);
-
- clif->refresh_storagewindow(sd);
+ if (strcmp(mapname, "Random") == 0)
+ pc->randomwarp(sd, CLR_TELEPORT);
+ else if (sd->menuskill_val > 1) // Need lv2 to be able to warp here.
+ pc->setpos(sd, sd->status.save_point.map, sd->status.save_point.x, sd->status.save_point.y, CLR_TELEPORT);
+
+ if (battle_config.teleport_close_storage == 1 && sd->state.storage_flag != STORAGE_FLAG_CLOSED) {
+ if (sd->state.storage_flag == STORAGE_FLAG_NORMAL)
+ storage->close(sd);
+ if (sd->state.storage_flag == STORAGE_FLAG_GUILD)
+ gstorage->close(sd);
+ } else {
+ clif->refresh_storagewindow(sd);
+ }
break;
case AL_WARP:
@@ -11797,7 +11848,13 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill
// Slim Pitcher [Celest]
case CR_SLIMPITCHER:
if (sd) {
- int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE;
+ int item_idx = skill->get_item_index(skill_id, skill_lv);
+
+ if (item_idx == INDEX_NOT_FOUND) {
+ clif->skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0, 0);
+ return 1;
+ }
+
int item_id = skill->get_itemid(skill_id, item_idx);
int inventory_idx = pc->search_inventory(sd, item_id);
int bonus;
@@ -11830,7 +11887,11 @@ static int skill_castend_pos2(struct block_list *src, int x, int y, uint16 skill
skill->castend_nodamage_id);
}
} else {
- int item_idx = (skill_lv - 1) % MAX_SKILL_ITEM_REQUIRE;
+ int item_idx = skill->get_item_index(skill_id, skill_lv);
+
+ if (item_idx == INDEX_NOT_FOUND)
+ return 1;
+
int item_id = skill->get_itemid(skill_id, item_idx);
struct item_data *item = itemdb->search(item_id);
int bonus;
@@ -17766,13 +17827,20 @@ static int skill_get_new_group_id(void)
static struct skill_unit_group *skill_initunitgroup(struct block_list *src, int count, uint16 skill_id, uint16 skill_lv, int unit_id, int limit, int interval)
{
- struct unit_data* ud = unit->bl2ud( src );
struct skill_unit_group* group;
int i;
if(!(skill_id && skill_lv)) return 0;
nullpo_retr(NULL, src);
+
+ struct unit_data *ud;
+
+ if (src->type == BL_NPC)
+ ud = unit->bl2ud2(src);
+ else
+ ud = unit->bl2ud(src);
+
nullpo_retr(NULL, ud);
// find a free spot to store the new unit group
@@ -23937,6 +24005,7 @@ void skill_defaults(void)
skill->get_sp_rate = skill_get_sp_rate;
skill->get_state = skill_get_state;
skill->get_spiritball = skill_get_spiritball;
+ skill->get_item_index = skill_get_item_index;
skill->get_itemid = skill_get_itemid;
skill->get_itemqty = skill_get_itemqty;
skill->get_item_any_flag = skill_get_item_any_flag;
diff --git a/src/map/skill.h b/src/map/skill.h
index b505412b6..fdeaefe01 100644
--- a/src/map/skill.h
+++ b/src/map/skill.h
@@ -2007,6 +2007,7 @@ struct skill_interface {
int (*get_sp_rate) (int skill_id, int skill_lv);
int (*get_state) (int skill_id, int skill_lv);
int (*get_spiritball) (int skill_id, int skill_lv);
+ int (*get_item_index) (int skill_id, int skill_lv);
int (*get_itemid) (int skill_id, int item_idx);
int (*get_itemqty) (int skill_id, int item_idx, int skill_lv);
bool (*get_item_any_flag) (int skill_id, int skill_lv);
diff --git a/src/map/trade.c b/src/map/trade.c
index e727c3c70..31970fbf9 100644
--- a/src/map/trade.c
+++ b/src/map/trade.c
@@ -63,7 +63,7 @@ static void trade_traderequest(struct map_session_data *sd, struct map_session_d
return;
}
- if (target_sd->npc_id) {
+ if (target_sd->npc_id != 0 && target_sd->state.using_megaphone == 0) {
//Trade fails if you are using an NPC.
clif->tradestart(sd, 2);
return;
@@ -166,9 +166,10 @@ static void trade_tradeack(struct map_session_data *sd, int type)
}
//Check if you can start trade.
- if (sd->npc_id || sd->state.vending || sd->state.prevend || sd->state.buyingstore || sd->state.storage_flag != STORAGE_FLAG_CLOSED
- || tsd->npc_id || tsd->state.vending || tsd->state.prevend || tsd->state.buyingstore || tsd->state.storage_flag != STORAGE_FLAG_CLOSED
- ) {
+ if ((sd->npc_id != 0 && sd->state.using_megaphone == 0) || sd->state.vending != 0 || sd->state.prevend != 0
+ || sd->state.buyingstore != 0 || sd->state.storage_flag != STORAGE_FLAG_CLOSED
+ || (tsd->npc_id != 0 && tsd->state.using_megaphone == 0) || tsd->state.vending != 0 || tsd->state.prevend != 0
+ || tsd->state.buyingstore != 0 || tsd->state.storage_flag != STORAGE_FLAG_CLOSED) {
//Fail
clif->tradestart(sd, 2);
clif->tradestart(tsd, 2);
diff --git a/src/map/vending.c b/src/map/vending.c
index 4fd009025..9b3f48f38 100644
--- a/src/map/vending.c
+++ b/src/map/vending.c
@@ -251,8 +251,10 @@ static void vending_openvending(struct map_session_data *sd, const char *message
int vending_skill_lvl;
nullpo_retv(sd);
- if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd))
- return; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
+ if (pc_isdead(sd) || sd->state.prevend == 0 || pc_istrading_except_npc(sd)
+ || (sd->npc_id != 0 && sd->state.using_megaphone == 0)) {
+ return; // Can't open vendings lying dead. || Didn't use via the skill. (wpe/hack) || Can't have 2 shops at once.
+ }
vending_skill_lvl = pc->checkskill(sd, MC_VENDING);
// skill level and cart check
diff --git a/src/plugins/HPMHooking/HPMHooking.Defs.inc b/src/plugins/HPMHooking/HPMHooking.Defs.inc
index c04eedb05..60c00e8db 100644
--- a/src/plugins/HPMHooking/HPMHooking.Defs.inc
+++ b/src/plugins/HPMHooking/HPMHooking.Defs.inc
@@ -2674,6 +2674,8 @@ typedef time_t (*HPMHOOK_pre_clif_attendance_getendtime) (void);
typedef time_t (*HPMHOOK_post_clif_attendance_getendtime) (time_t retVal___);
typedef void (*HPMHOOK_pre_clif_pOpenUIRequest) (int *fd, struct map_session_data **sd);
typedef void (*HPMHOOK_post_clif_pOpenUIRequest) (int fd, struct map_session_data *sd);
+typedef void (*HPMHOOK_pre_clif_open_ui_send) (struct map_session_data **sd, enum zc_ui_types *ui_type);
+typedef void (*HPMHOOK_post_clif_open_ui_send) (struct map_session_data *sd, enum zc_ui_types ui_type);
typedef void (*HPMHOOK_pre_clif_open_ui) (struct map_session_data **sd, enum cz_ui_types *uiType);
typedef void (*HPMHOOK_post_clif_open_ui) (struct map_session_data *sd, enum cz_ui_types uiType);
typedef void (*HPMHOOK_pre_clif_pAttendanceRewardRequest) (int *fd, struct map_session_data **sd);
@@ -6540,6 +6542,8 @@ typedef int (*HPMHOOK_pre_pet_hungry_val) (struct pet_data **pd);
typedef int (*HPMHOOK_post_pet_hungry_val) (int retVal___, struct pet_data *pd);
typedef void (*HPMHOOK_pre_pet_set_hunger) (struct pet_data **pd, int *value);
typedef void (*HPMHOOK_post_pet_set_hunger) (struct pet_data *pd, int value);
+typedef int (*HPMHOOK_pre_pet_get_card4_value) (int *rename_flag, int *intimacy);
+typedef int (*HPMHOOK_post_pet_get_card4_value) (int retVal___, int rename_flag, int intimacy);
typedef void (*HPMHOOK_pre_pet_set_intimate) (struct pet_data **pd, int *value);
typedef void (*HPMHOOK_post_pet_set_intimate) (struct pet_data *pd, int value);
typedef int (*HPMHOOK_pre_pet_create_egg) (struct map_session_data **sd, int *item_id);
@@ -6564,6 +6568,8 @@ typedef int (*HPMHOOK_pre_pet_return_egg) (struct map_session_data **sd, struct
typedef int (*HPMHOOK_post_pet_return_egg) (int retVal___, struct map_session_data *sd, struct pet_data *pd);
typedef int (*HPMHOOK_pre_pet_data_init) (struct map_session_data **sd, struct s_pet **petinfo);
typedef int (*HPMHOOK_post_pet_data_init) (int retVal___, struct map_session_data *sd, struct s_pet *petinfo);
+typedef int (*HPMHOOK_pre_pet_spawn) (struct map_session_data **sd, bool *birth_process);
+typedef int (*HPMHOOK_post_pet_spawn) (int retVal___, struct map_session_data *sd, bool birth_process);
typedef int (*HPMHOOK_pre_pet_birth_process) (struct map_session_data **sd, struct s_pet **petinfo);
typedef int (*HPMHOOK_post_pet_birth_process) (int retVal___, struct map_session_data *sd, struct s_pet *petinfo);
typedef int (*HPMHOOK_pre_pet_recv_petdata) (int *account_id, struct s_pet **p, int *flag);
@@ -7264,6 +7270,8 @@ typedef int (*HPMHOOK_pre_skill_get_state) (int *skill_id, int *skill_lv);
typedef int (*HPMHOOK_post_skill_get_state) (int retVal___, int skill_id, int skill_lv);
typedef int (*HPMHOOK_pre_skill_get_spiritball) (int *skill_id, int *skill_lv);
typedef int (*HPMHOOK_post_skill_get_spiritball) (int retVal___, int skill_id, int skill_lv);
+typedef int (*HPMHOOK_pre_skill_get_item_index) (int *skill_id, int *skill_lv);
+typedef int (*HPMHOOK_post_skill_get_item_index) (int retVal___, int skill_id, int skill_lv);
typedef int (*HPMHOOK_pre_skill_get_itemid) (int *skill_id, int *item_idx);
typedef int (*HPMHOOK_post_skill_get_itemid) (int retVal___, int skill_id, int item_idx);
typedef int (*HPMHOOK_pre_skill_get_itemqty) (int *skill_id, int *item_idx, int *skill_lv);
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
index 60d8b7e20..62d2327da 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HPMHooksCore.inc
@@ -2264,6 +2264,8 @@ struct {
struct HPMHookPoint *HP_clif_attendance_getendtime_post;
struct HPMHookPoint *HP_clif_pOpenUIRequest_pre;
struct HPMHookPoint *HP_clif_pOpenUIRequest_post;
+ struct HPMHookPoint *HP_clif_open_ui_send_pre;
+ struct HPMHookPoint *HP_clif_open_ui_send_post;
struct HPMHookPoint *HP_clif_open_ui_pre;
struct HPMHookPoint *HP_clif_open_ui_post;
struct HPMHookPoint *HP_clif_pAttendanceRewardRequest_pre;
@@ -5116,6 +5118,8 @@ struct {
struct HPMHookPoint *HP_pet_hungry_val_post;
struct HPMHookPoint *HP_pet_set_hunger_pre;
struct HPMHookPoint *HP_pet_set_hunger_post;
+ struct HPMHookPoint *HP_pet_get_card4_value_pre;
+ struct HPMHookPoint *HP_pet_get_card4_value_post;
struct HPMHookPoint *HP_pet_set_intimate_pre;
struct HPMHookPoint *HP_pet_set_intimate_post;
struct HPMHookPoint *HP_pet_create_egg_pre;
@@ -5140,6 +5144,8 @@ struct {
struct HPMHookPoint *HP_pet_return_egg_post;
struct HPMHookPoint *HP_pet_data_init_pre;
struct HPMHookPoint *HP_pet_data_init_post;
+ struct HPMHookPoint *HP_pet_spawn_pre;
+ struct HPMHookPoint *HP_pet_spawn_post;
struct HPMHookPoint *HP_pet_birth_process_pre;
struct HPMHookPoint *HP_pet_birth_process_post;
struct HPMHookPoint *HP_pet_recv_petdata_pre;
@@ -5788,6 +5794,8 @@ struct {
struct HPMHookPoint *HP_skill_get_state_post;
struct HPMHookPoint *HP_skill_get_spiritball_pre;
struct HPMHookPoint *HP_skill_get_spiritball_post;
+ struct HPMHookPoint *HP_skill_get_item_index_pre;
+ struct HPMHookPoint *HP_skill_get_item_index_post;
struct HPMHookPoint *HP_skill_get_itemid_pre;
struct HPMHookPoint *HP_skill_get_itemid_post;
struct HPMHookPoint *HP_skill_get_itemqty_pre;
@@ -9295,6 +9303,8 @@ struct {
int HP_clif_attendance_getendtime_post;
int HP_clif_pOpenUIRequest_pre;
int HP_clif_pOpenUIRequest_post;
+ int HP_clif_open_ui_send_pre;
+ int HP_clif_open_ui_send_post;
int HP_clif_open_ui_pre;
int HP_clif_open_ui_post;
int HP_clif_pAttendanceRewardRequest_pre;
@@ -12147,6 +12157,8 @@ struct {
int HP_pet_hungry_val_post;
int HP_pet_set_hunger_pre;
int HP_pet_set_hunger_post;
+ int HP_pet_get_card4_value_pre;
+ int HP_pet_get_card4_value_post;
int HP_pet_set_intimate_pre;
int HP_pet_set_intimate_post;
int HP_pet_create_egg_pre;
@@ -12171,6 +12183,8 @@ struct {
int HP_pet_return_egg_post;
int HP_pet_data_init_pre;
int HP_pet_data_init_post;
+ int HP_pet_spawn_pre;
+ int HP_pet_spawn_post;
int HP_pet_birth_process_pre;
int HP_pet_birth_process_post;
int HP_pet_recv_petdata_pre;
@@ -12819,6 +12833,8 @@ struct {
int HP_skill_get_state_post;
int HP_skill_get_spiritball_pre;
int HP_skill_get_spiritball_post;
+ int HP_skill_get_item_index_pre;
+ int HP_skill_get_item_index_post;
int HP_skill_get_itemid_pre;
int HP_skill_get_itemid_post;
int HP_skill_get_itemqty_pre;
diff --git a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
index 899f443d1..34f968c12 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.HookingPoints.inc
@@ -1156,6 +1156,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(clif->attendance_timediff, HP_clif_attendance_timediff) },
{ HP_POP(clif->attendance_getendtime, HP_clif_attendance_getendtime) },
{ HP_POP(clif->pOpenUIRequest, HP_clif_pOpenUIRequest) },
+ { HP_POP(clif->open_ui_send, HP_clif_open_ui_send) },
{ HP_POP(clif->open_ui, HP_clif_open_ui) },
{ HP_POP(clif->pAttendanceRewardRequest, HP_clif_pAttendanceRewardRequest) },
{ HP_POP(clif->ui_action, HP_clif_ui_action) },
@@ -2618,6 +2619,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pet->final, HP_pet_final) },
{ HP_POP(pet->hungry_val, HP_pet_hungry_val) },
{ HP_POP(pet->set_hunger, HP_pet_set_hunger) },
+ { HP_POP(pet->get_card4_value, HP_pet_get_card4_value) },
{ HP_POP(pet->set_intimate, HP_pet_set_intimate) },
{ HP_POP(pet->create_egg, HP_pet_create_egg) },
{ HP_POP(pet->unlocktarget, HP_pet_unlocktarget) },
@@ -2630,6 +2632,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(pet->performance, HP_pet_performance) },
{ HP_POP(pet->return_egg, HP_pet_return_egg) },
{ HP_POP(pet->data_init, HP_pet_data_init) },
+ { HP_POP(pet->spawn, HP_pet_spawn) },
{ HP_POP(pet->birth_process, HP_pet_birth_process) },
{ HP_POP(pet->recv_petdata, HP_pet_recv_petdata) },
{ HP_POP(pet->select_egg, HP_pet_select_egg) },
@@ -2963,6 +2966,7 @@ struct HookingPointData HookingPoints[] = {
{ HP_POP(skill->get_sp_rate, HP_skill_get_sp_rate) },
{ HP_POP(skill->get_state, HP_skill_get_state) },
{ HP_POP(skill->get_spiritball, HP_skill_get_spiritball) },
+ { HP_POP(skill->get_item_index, HP_skill_get_item_index) },
{ HP_POP(skill->get_itemid, HP_skill_get_itemid) },
{ HP_POP(skill->get_itemqty, HP_skill_get_itemqty) },
{ HP_POP(skill->get_item_any_flag, HP_skill_get_item_any_flag) },
diff --git a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
index f6f1b3839..8cb425011 100644
--- a/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
+++ b/src/plugins/HPMHooking/HPMHooking_map.Hooks.inc
@@ -29508,6 +29508,32 @@ void HP_clif_pOpenUIRequest(int fd, struct map_session_data *sd) {
}
return;
}
+void HP_clif_open_ui_send(struct map_session_data *sd, enum zc_ui_types ui_type) {
+ int hIndex = 0;
+ if (HPMHooks.count.HP_clif_open_ui_send_pre > 0) {
+ void (*preHookFunc) (struct map_session_data **sd, enum zc_ui_types *ui_type);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_open_ui_send_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_clif_open_ui_send_pre[hIndex].func;
+ preHookFunc(&sd, &ui_type);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return;
+ }
+ }
+ {
+ HPMHooks.source.clif.open_ui_send(sd, ui_type);
+ }
+ if (HPMHooks.count.HP_clif_open_ui_send_post > 0) {
+ void (*postHookFunc) (struct map_session_data *sd, enum zc_ui_types ui_type);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_clif_open_ui_send_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_clif_open_ui_send_post[hIndex].func;
+ postHookFunc(sd, ui_type);
+ }
+ }
+ return;
+}
void HP_clif_open_ui(struct map_session_data *sd, enum cz_ui_types uiType) {
int hIndex = 0;
if (HPMHooks.count.HP_clif_open_ui_pre > 0) {
@@ -68086,6 +68112,33 @@ void HP_pet_set_hunger(struct pet_data *pd, int value) {
}
return;
}
+int HP_pet_get_card4_value(int rename_flag, int intimacy) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_pet_get_card4_value_pre > 0) {
+ int (*preHookFunc) (int *rename_flag, int *intimacy);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_get_card4_value_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_pet_get_card4_value_pre[hIndex].func;
+ retVal___ = preHookFunc(&rename_flag, &intimacy);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.pet.get_card4_value(rename_flag, intimacy);
+ }
+ if (HPMHooks.count.HP_pet_get_card4_value_post > 0) {
+ int (*postHookFunc) (int retVal___, int rename_flag, int intimacy);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_get_card4_value_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_pet_get_card4_value_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, rename_flag, intimacy);
+ }
+ }
+ return retVal___;
+}
void HP_pet_set_intimate(struct pet_data *pd, int value) {
int hIndex = 0;
if (HPMHooks.count.HP_pet_set_intimate_pre > 0) {
@@ -68409,6 +68462,33 @@ int HP_pet_data_init(struct map_session_data *sd, struct s_pet *petinfo) {
}
return retVal___;
}
+int HP_pet_spawn(struct map_session_data *sd, bool birth_process) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_pet_spawn_pre > 0) {
+ int (*preHookFunc) (struct map_session_data **sd, bool *birth_process);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_spawn_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_pet_spawn_pre[hIndex].func;
+ retVal___ = preHookFunc(&sd, &birth_process);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.pet.spawn(sd, birth_process);
+ }
+ if (HPMHooks.count.HP_pet_spawn_post > 0) {
+ int (*postHookFunc) (int retVal___, struct map_session_data *sd, bool birth_process);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_pet_spawn_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_pet_spawn_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, sd, birth_process);
+ }
+ }
+ return retVal___;
+}
int HP_pet_birth_process(struct map_session_data *sd, struct s_pet *petinfo) {
int hIndex = 0;
int retVal___ = 0;
@@ -77228,6 +77308,33 @@ int HP_skill_get_spiritball(int skill_id, int skill_lv) {
}
return retVal___;
}
+int HP_skill_get_item_index(int skill_id, int skill_lv) {
+ int hIndex = 0;
+ int retVal___ = 0;
+ if (HPMHooks.count.HP_skill_get_item_index_pre > 0) {
+ int (*preHookFunc) (int *skill_id, int *skill_lv);
+ *HPMforce_return = false;
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_item_index_pre; hIndex++) {
+ preHookFunc = HPMHooks.list.HP_skill_get_item_index_pre[hIndex].func;
+ retVal___ = preHookFunc(&skill_id, &skill_lv);
+ }
+ if (*HPMforce_return) {
+ *HPMforce_return = false;
+ return retVal___;
+ }
+ }
+ {
+ retVal___ = HPMHooks.source.skill.get_item_index(skill_id, skill_lv);
+ }
+ if (HPMHooks.count.HP_skill_get_item_index_post > 0) {
+ int (*postHookFunc) (int retVal___, int skill_id, int skill_lv);
+ for (hIndex = 0; hIndex < HPMHooks.count.HP_skill_get_item_index_post; hIndex++) {
+ postHookFunc = HPMHooks.list.HP_skill_get_item_index_post[hIndex].func;
+ retVal___ = postHookFunc(retVal___, skill_id, skill_lv);
+ }
+ }
+ return retVal___;
+}
int HP_skill_get_itemid(int skill_id, int item_idx) {
int hIndex = 0;
int retVal___ = 0;
diff --git a/src/plugins/Makefile.in b/src/plugins/Makefile.in
index e44412bfa..073cd8d41 100644
--- a/src/plugins/Makefile.in
+++ b/src/plugins/Makefile.in
@@ -43,7 +43,7 @@ HPMHOOKING = $(addprefix HPMHooking_, login char map)
ALLPLUGINS = $(filter-out HPMHooking, $(basename $(wildcard *.c))) $(HPMHOOKING)
# Plugins that will be built through 'make plugins' or 'make all'
-PLUGINS = sample db2sql HPMHooking_char HPMHooking_login HPMHooking_map $(MYPLUGINS)
+PLUGINS = sample db2sql constdb2doc generate-translations mapcache script_mapquit HPMHooking_char HPMHooking_login HPMHooking_map $(MYPLUGINS)
COMMON_D = ../common
# Includes private headers (plugins might need them)
diff --git a/src/plugins/mapcache.c b/src/plugins/mapcache.c
index 3dc6e3b34..2b8e4c6f8 100644
--- a/src/plugins/mapcache.c
+++ b/src/plugins/mapcache.c
@@ -402,7 +402,6 @@ bool fix_md5_truncation_sub(FILE *fp, const char *map_name)
fseek(fp, 0, SEEK_SET);
fwrite(&mheader, sizeof(mheader), 1, fp);
- fclose(fp);
return true;
}
diff --git a/tools/ci/travis.sh b/tools/ci/travis.sh
index 10c653925..a1a3c7700 100755
--- a/tools/ci/travis.sh
+++ b/tools/ci/travis.sh
@@ -37,6 +37,8 @@ function usage {
echo " $0 build [configure args]"
echo " $0 test <dbname> [dbuser] [dbpassword] [dbhost]"
echo " $0 getplugins"
+ echo " $0 startmysql"
+ echo " $0 extratest"
exit 1
}
@@ -71,7 +73,8 @@ function run_server {
function run_test {
echo "Running: test_$1"
sysctl -w kernel.core_pattern=core || true
- ./test_$1 2>runlog.txt
+ rm -rf core* || true
+ CRASH_PLEASE=1 ./test_$1 2>runlog.txt
export errcode=$?
export teststr=$(head -c 10000 runlog.txt)
if [[ -n "${teststr}" ]]; then
@@ -83,6 +86,13 @@ function run_test {
fi
if [ ${errcode} -ne 0 ]; then
echo "test $1 terminated with exit code ${errcode}"
+ echo cat runlog.txt
+ cat runlog.txt
+ echo crash dump
+ COREFILE=$(find . -maxdepth 1 -name "core*" | head -n 1)
+ if [[ -f "$COREFILE" ]]; then
+ gdb -c "$COREFILE" $1 -ex "thread apply all bt" -ex "set pagination 0" -batch
+ fi
aborterror "Test failed"
fi
}
@@ -146,7 +156,14 @@ case "$MODE" in
;;
adduser)
echo "Adding user $NEWUSER as $DBUSER, with access to database $DBNAME..."
- mysql $DBUSER_ARG $DBPASS_ARG $DBHOST_ARG --execute="GRANT SELECT,INSERT,UPDATE,DELETE ON $DBNAME.* TO '$NEWUSER'@'$DBHOST' IDENTIFIED BY '$NEWPASS';"
+ mysql $DBUSER_ARG $DBPASS_ARG $DBHOST_ARG --execute="GRANT SELECT,INSERT,UPDATE,DELETE ON $DBNAME.* TO '$NEWUSER'@'$DBHOST' IDENTIFIED BY '$NEWPASS';" || true
+ mysql $DBUSER_ARG $DBPASS_ARG $DBHOST_ARG --execute="CREATE USER '$NEWUSER'@'$DBHOST' IDENTIFIED BY '$NEWPASS';" || true
+ mysql $DBUSER_ARG $DBPASS_ARG $DBHOST_ARG --execute="GRANT SELECT,INSERT,UPDATE,DELETE ON $DBNAME.* TO '$NEWUSER'@'$DBHOST';" || true
+ mysql $DBUSER_ARG $DBPASS_ARG $DBHOST_ARG --execute="ALTER USER '$NEWUSER'@'$DBHOST' IDENTIFIED BY '$NEWPASS';" || true
+ mysql --defaults-file=/etc/mysql/debian.cnf $DBPASS_ARG $DBHOST_ARG --execute="CREATE USER '$NEWUSER'@'$DBHOST' IDENTIFIED BY '$NEWPASS';" || true
+ mysql --defaults-file=/etc/mysql/debian.cnf $DBPASS_ARG $DBHOST_ARG --execute="GRANT SELECT,INSERT,UPDATE,DELETE ON $DBNAME.* TO '$NEWUSER'@'$DBHOST';" || true
+ mysql --defaults-file=/etc/mysql/debian.cnf $DBPASS_ARG $DBHOST_ARG --execute="ALTER USER '$NEWUSER'@'$DBHOST' IDENTIFIED BY '$NEWPASS';" || true
+
;;
build)
(cd tools && ./validateinterfaces.py silent) || aborterror "Interface validation error."
@@ -207,13 +224,13 @@ EOF
[ $? -eq 0 ] || aborterror "Unable to override inter-server configuration, aborting tests."
ARGS="--load-script npc/dev/test.txt "
ARGS="--load-plugin script_mapquit $ARGS --load-script npc/dev/ci_test.txt"
- PLUGINS="--load-plugin HPMHooking --load-plugin sample"
+ PLUGINS="--load-plugin HPMHooking"
echo "run tests"
if [[ $DBUSER == "travis" ]]; then
echo "Disable leak dection on travis"
- export ASAN_OPTIONS=detect_leaks=0:detect_stack_use_after_return=true:strict_init_order=true
+ export ASAN_OPTIONS=detect_leaks=0:detect_stack_use_after_return=true:strict_init_order=true:detect_odr_violation=0
else
- export ASAN_OPTIONS=detect_stack_use_after_return=true:strict_init_order=true
+ export ASAN_OPTIONS=detect_stack_use_after_return=true:strict_init_order=true:detect_odr_violation=0
fi
# run_test spinlock # Not running the spinlock test for the time being (too time consuming)
run_test libconfig
@@ -221,7 +238,38 @@ EOF
run_server ./login-server
run_server ./char-server
run_server ./map-server "$ARGS"
- echo "run all servers wit HPM"
+ echo "run all servers with HPM"
+ run_server ./login-server "$PLUGINS"
+ run_server ./char-server "$PLUGINS"
+ run_server ./map-server "$ARGS $PLUGINS"
+ echo "run all servers with sample plugin"
+ run_server ./login-server "$PLUGINS --load-plugin sample"
+ run_server ./char-server "$PLUGINS --load-plugin sample"
+ run_server ./map-server "$PLUGINS --load-plugin sample"
+ echo "run all servers with constdb2doc"
+ run_server ./map-server "$PLUGINS --load-plugin constdb2doc --constdb2doc"
+ echo "run all servers with db2sql"
+ run_server ./map-server "$PLUGINS --load-plugin db2sql --db2sql"
+ run_server ./map-server "$PLUGINS --load-plugin db2sql --itemdb2sql"
+ run_server ./map-server "$PLUGINS --load-plugin db2sql --mobdb2sql"
+# look like works on windows only
+# echo "run all servers with dbghelpplug"
+# run_server ./login-server "$PLUGINS --load-plugin dbghelpplug"
+# run_server ./char-server "$PLUGINS --load-plugin dbghelpplug"
+# run_server ./map-server "$PLUGINS --load-plugin dbghelpplug"
+ echo "run all servers with generate-translations"
+ run_server ./map-server "$PLUGINS --load-plugin generate-translations --generate-translations"
+ echo "run all servers with mapcache"
+# for other flags need grf or other files
+ run_server ./map-server "$PLUGINS --load-plugin mapcache --fix-md5"
+ echo "run all servers with script_mapquit"
+ run_server ./map-server "$PLUGINS --load-plugin script_mapquit"
+ ;;
+ extratest)
+ export ASAN_OPTIONS=detect_stack_use_after_return=true:strict_init_order=true:detect_odr_violation=0
+ PLUGINS="--load-plugin HPMHooking"
+ echo "run map server with uncommented old and custom scripts"
+ find ./npc -type f -name "*.conf" -exec ./tools/ci/uncomment.sh {} \;
run_server ./login-server "$PLUGINS"
run_server ./char-server "$PLUGINS"
run_server ./map-server "$ARGS $PLUGINS"
@@ -238,6 +286,13 @@ EOF
# echo "Plugin not found, skipping advanced tests."
#fi
;;
+ startmysql)
+ echo "Starting mysql..."
+ service mysql status || true
+ service mysql stop || true
+ service mysql start || true
+ service mysql status || true
+ ;;
*)
usage
;;
diff --git a/tools/ci/uncomment.sh b/tools/ci/uncomment.sh
new file mode 100755
index 000000000..22fe4e966
--- /dev/null
+++ b/tools/ci/uncomment.sh
@@ -0,0 +1,4 @@
+#!/usr/bin/env bash
+
+sed -i "s|//\"npc/|\"npc/|g" $1
+sed -i "s|\"npc/location/to/script.txt\"|//\"npc/location/to/script.txt\"|g" $1
diff --git a/tools/validateinterfaces.py b/tools/validateinterfaces.py
index e031c34ab..324a2aeec 100755
--- a/tools/validateinterfaces.py
+++ b/tools/validateinterfaces.py
@@ -23,7 +23,6 @@
import os
import re
import sys
-from sets import Set
interfaceRe = re.compile("struct (?P<name1>[a-z_]+)_interface (?P<name2>[a-z_]+)_s;")
@@ -44,7 +43,7 @@ def searchStructStart(r, ifname):
return False
def readCFile(tracker, cFile):
- methods = Set()
+ methods = set()
shortIfName = ""
with open(cFile, "r") as r:
for line in r:
@@ -78,7 +77,7 @@ def readCFile(tracker, cFile):
return (None, shortIfName, methods)
def readHFile(tracker, hFile, ifname):
- methods = Set()
+ methods = set()
with open(hFile, "r") as r:
if searchStructStart(r, ifname) == False:
return methods
@@ -108,7 +107,7 @@ def checkIfFile(tracker, cFile, hFile):
tracker.arr[ifname + "_" + method] = list()
tracker.methods.add(ifname + "_" + method)
if method not in cMethods:
- print "Missing initialisation in file {0}: {1}".format(cFile, method)
+ print("Missing initialisation in file {0}: {1}".format(cFile, method))
tracker.retCode = 1
# for method in cMethods:
# if method not in hMethods:
@@ -175,13 +174,13 @@ def processDir(tracker, srcDir):
checkFile(tracker, cPath)
def reportMethods(tracker):
- print "\n"
+ print("\n")
for method in tracker.methods:
if len(tracker.arr[method]) > 2:
- print method
+ print(method)
for t in tracker.arr[method]:
- print t
- print "\n"
+ print(t)
+ print("\n")
def checkLostFile(tracker, cFile):
@@ -198,7 +197,7 @@ def checkLostFile(tracker, cFile):
continue
if name not in tracker.fullmethods:
# print "src : " + line
- print name
+ print(name)
def processLostDir(tracker, srcDir):
files = os.listdir(srcDir)
@@ -232,9 +231,9 @@ def runLong():
tracker = Tracker()
tracker.arr = dict()
-tracker.methods = Set()
-tracker.fullmethods = Set()
-tracker.interfaces = Set()
+tracker.methods = set()
+tracker.fullmethods = set()
+tracker.interfaces = set()
tracker.retCode = 0
if len(sys.argv) > 1:
@@ -245,19 +244,19 @@ else:
if cmd == "silent":
runIf()
elif cmd == "init":
- print "Checking interfaces initialisation"
+ print("Checking interfaces initialisation")
runIf()
elif cmd == "lost":
- print "Checking not added functions to interfaces"
+ print("Checking not added functions to interfaces")
runLost();
elif cmd == "long":
- print "Checking interfaces usage"
+ print("Checking interfaces usage")
runLong();
else:
- print "Checking interfaces initialisation"
+ print("Checking interfaces initialisation")
runIf()
- print "Checking not added functions to interfaces"
+ print("Checking not added functions to interfaces")
runLost();
- print "Checking interfaces usage"
+ print("Checking interfaces usage")
runLong();
exit(tracker.retCode)