Compare commits
58 Commits
cleanup/re
...
hotfix/iss
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1e01f6448f | ||
|
|
913519ed50 | ||
|
|
e64c5bce35 | ||
|
|
4836d8e77a | ||
|
|
4fb6740ebf | ||
|
|
c9aaf540bf | ||
|
|
134bfbe986 | ||
|
|
7323800838 | ||
|
|
9dda166c0e | ||
|
|
503b57dbef | ||
|
|
ea3464598d | ||
|
|
857a34832f | ||
|
|
3958a96771 | ||
|
|
b867a2171f | ||
|
|
936abe13eb | ||
|
|
1361e9c1df | ||
|
|
64228cd18f | ||
|
|
d0b51d91a0 | ||
|
|
fa0253342a | ||
|
|
42eccbb1bf | ||
|
|
50bd9cdfbe | ||
|
|
323a541074 | ||
|
|
70d729ecf8 | ||
|
|
39d5a02a31 | ||
|
|
3d5cd57c54 | ||
|
|
2c4ee64b59 | ||
|
|
ef4d52fd7b | ||
|
|
3bfead228e | ||
|
|
9e476cce31 | ||
|
|
448d8febfa | ||
|
|
3b71f77c27 | ||
|
|
5b8d0ee6a5 | ||
|
|
9b6a4de288 | ||
|
|
817b86d5e1 | ||
|
|
0e948b5f9a | ||
|
|
eda702ca2c | ||
|
|
d1e184e46c | ||
|
|
ee91ab507a | ||
|
|
165e0d668f | ||
|
|
93cf18736a | ||
|
|
b862aed75c | ||
|
|
ae686056a0 | ||
|
|
4d734abc53 | ||
|
|
ef602d98cb | ||
|
|
20dedc7918 | ||
|
|
8eac71f57f | ||
|
|
5676a45908 | ||
|
|
1c1bb9892c | ||
|
|
da375a04c1 | ||
|
|
1f4c068c39 | ||
|
|
ee2dcf816e | ||
|
|
5a533a7a12 | ||
|
|
3545a9c82f | ||
|
|
c951f68250 | ||
|
|
9440ba8929 | ||
|
|
9ff252d2b1 | ||
|
|
7a345b85cb | ||
|
|
da8d77bfc1 |
91
.github/workflows/analysis_codeql.yml
vendored
Normal file
91
.github/workflows/analysis_codeql.yml
vendored
Normal file
@@ -0,0 +1,91 @@
|
||||
name: Analyse servers with CodeQL
|
||||
# analysis_codeql.yml
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
pull_request:
|
||||
paths:
|
||||
# Always trigger all Github Actions if an action or something CI related was changed
|
||||
- '.github/workflows/**'
|
||||
- 'tools/ci/**'
|
||||
# This workflow should run when a file in a source directory has been modified.
|
||||
- 'src/**'
|
||||
- '3rdparty/**'
|
||||
|
||||
jobs:
|
||||
analyze:
|
||||
# Github Actions checks for '[ci skip]', '[skip ci]', '[no ci]', '[skip actions]', or '[actions skip]' but not a hyphenated version.
|
||||
# It's a catch-all incase a Pull Request has been opened and someone is on auto-pilot.
|
||||
if: "!contains(github.event.head_commit.message, 'ci-skip')"
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
# The ubuntu-latest label currently points to ubuntu-20.04.
|
||||
# Available: ubuntu-22.04, ubuntu-20.04
|
||||
os: [ubuntu-latest]
|
||||
# Older versions of GCC are not available via unaltered aptitude repo lists.
|
||||
gcc: ['10']
|
||||
# We run build checks for both Renewal and PRE-Renewal
|
||||
mode: ['PRE','RE']
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v3
|
||||
|
||||
# Initializes the CodeQL tools for scanning.
|
||||
- name: Initialize CodeQL
|
||||
uses: github/codeql-action/init@v2
|
||||
with:
|
||||
# CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
|
||||
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
|
||||
languages: cpp
|
||||
# Trigger security and quality findings
|
||||
# https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
|
||||
# TODO: Resolve the issues and then enable it again
|
||||
#queries: +security-and-quality
|
||||
|
||||
# A simple 'yes' and 'no' can be confusing, so we use names to display in the current job then convert them for use in the compiler.
|
||||
- name: Variable Parsing - PRE
|
||||
if: ${{ matrix.mode == 'PRE' }}
|
||||
run: |
|
||||
echo "PRERE=yes" >> $GITHUB_ENV
|
||||
- name: Variable Parsing - RE
|
||||
if: ${{ matrix.mode == 'RE' }}
|
||||
run: |
|
||||
echo "PRERE=no" >> $GITHUB_ENV
|
||||
|
||||
- name: Update & Install packages
|
||||
# Ubuntu runners already have most of the packages rAthena requires to build.
|
||||
# https://github.com/actions/virtual-environments/blob/main/images/linux/Ubuntu2004-Readme.md
|
||||
run: |
|
||||
sudo apt update
|
||||
sudo apt install zlib1g-dev libpcre3-dev gcc-${{ matrix.gcc }} g++-${{ matrix.gcc }}
|
||||
|
||||
# Autobuild attempts to build any compiled languages (C/C++, C#, or Java).
|
||||
# If this step fails, then you should remove it and run the build manually (see below)
|
||||
#- name: Autobuild
|
||||
# uses: github/codeql-action/autobuild@v2
|
||||
|
||||
# ✏️ If the Autobuild fails above, remove it and uncomment the following
|
||||
# three lines and modify them (or add more) to build your code if your
|
||||
# project uses a compiled language
|
||||
- name: Command - configure
|
||||
env:
|
||||
CONFIGURE_FLAGS: 'CC=gcc-${{ matrix.gcc }} CXX=g++-${{ matrix.gcc }} --enable-prere=${{ env.PRERE }} --enable-buildbot=yes'
|
||||
run: ./configure $CONFIGURE_FLAGS
|
||||
|
||||
- name: Command - make clean
|
||||
run: make clean
|
||||
|
||||
- name: Command - make server
|
||||
run: make server
|
||||
|
||||
- name: Perform CodeQL Analysis
|
||||
uses: github/codeql-action/analyze@v2
|
||||
2
.github/workflows/build_servers_clang.yml
vendored
2
.github/workflows/build_servers_clang.yml
vendored
@@ -3,7 +3,7 @@ name: Build servers with Clang
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
2
.github/workflows/build_servers_cmake.yml
vendored
2
.github/workflows/build_servers_cmake.yml
vendored
@@ -3,7 +3,7 @@ name: Build servers with CMake
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
2
.github/workflows/build_servers_gcc.yml
vendored
2
.github/workflows/build_servers_gcc.yml
vendored
@@ -3,7 +3,7 @@ name: Build servers with GCC
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
2
.github/workflows/build_servers_modes.yml
vendored
2
.github/workflows/build_servers_modes.yml
vendored
@@ -3,7 +3,7 @@ name: Build servers in Pre-Renewal and Renewal
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
2
.github/workflows/build_servers_msbuild.yml
vendored
2
.github/workflows/build_servers_msbuild.yml
vendored
@@ -3,7 +3,7 @@ name: Build servers with MSVS
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -3,7 +3,7 @@ name: Build servers with different packet versions
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
2
.github/workflows/build_servers_vip.yml
vendored
2
.github/workflows/build_servers_vip.yml
vendored
@@ -3,7 +3,7 @@ name: Build servers in VIP mode
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
2
.github/workflows/npc_db_validation.yml
vendored
2
.github/workflows/npc_db_validation.yml
vendored
@@ -6,7 +6,7 @@ name: Validate NPC Scripts and DB Changes
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.repository }}-${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/master' }}
|
||||
|
||||
on:
|
||||
push:
|
||||
|
||||
@@ -158,3 +158,14 @@ macro_detection_retry: 3
|
||||
// Amount of time in milliseconds before the macro detection will fail and the user will be banned.
|
||||
// Official: 60000
|
||||
macro_detection_timeout: 60000
|
||||
|
||||
// Macro Detector punishment type
|
||||
// 0 - Ban
|
||||
// 1 - Jail
|
||||
// Official: 0
|
||||
macro_detection_punishment: 0
|
||||
|
||||
// Macro Detector punishment duration
|
||||
// Amount of time in minutes that the punishment type is active for. Use 0 for infinite.
|
||||
// Official: 0
|
||||
macro_detection_punishment_time: 0
|
||||
|
||||
@@ -67,6 +67,10 @@ feature.bgqueue: on
|
||||
// Requires: 2014-10-22bRagexe or later
|
||||
feature.roulette: on
|
||||
|
||||
// Roulette bonus reward
|
||||
// Multiply amount by 2 if the reward item ID is the same as bonus item ID
|
||||
feature.roulette_bonus_reward: on
|
||||
|
||||
// Achievement (Note 1)
|
||||
// Requires: 2015-05-13aRagexe or later
|
||||
feature.achievement: on
|
||||
@@ -142,3 +146,7 @@ feature.dynamicnpc_direction: no
|
||||
// like from SHIFT+Click from player's inventory/cart/equipment window.
|
||||
// Requires: 2010-00-00RagexeRE or later
|
||||
feature.itemlink: on
|
||||
|
||||
// Stylist UI (Note 1)
|
||||
// Requires: 2015-11-04 or later
|
||||
feature.stylist: on
|
||||
|
||||
@@ -297,3 +297,8 @@ achievement_mob_share: no
|
||||
// Should slaves teleport back to their master if they get too far during chase? (Note 1)
|
||||
// Default (Official): no
|
||||
slave_stick_with_master: no
|
||||
|
||||
// Absolute minimum respawn time in milliseconds of a monster.
|
||||
// Also used in delaying the spawning of guardians when a guild is not loaded.
|
||||
// Default (Official): 1000
|
||||
mob_respawn_time: 1000
|
||||
|
||||
@@ -198,6 +198,9 @@ char_del_restriction: 3
|
||||
// Uncomment to customize the restriction
|
||||
//allowed_job_flag: 3
|
||||
|
||||
// Should parties that don't have any members be cleared from the party_db table at start up?
|
||||
clear_parties: no
|
||||
|
||||
// Folder that contains the database files.
|
||||
db_path: db
|
||||
|
||||
|
||||
@@ -147,8 +147,6 @@ item_table: item_db
|
||||
renewal-item_table: item_db_re
|
||||
item2_table: item_db2
|
||||
renewal-item2_table: item_db2_re
|
||||
item_cash_table: item_cash_db
|
||||
item_cash2_table: item_cash_db2
|
||||
mob_table: mob_db
|
||||
renewal-mob_table: mob_db_re
|
||||
mob2_table: mob_db2
|
||||
@@ -158,6 +156,7 @@ renewal-mob_skill_table: mob_skill_db_re
|
||||
mob_skill2_table: mob_skill_db2
|
||||
renewal-mob_skill2_table: mob_skill_db2_re
|
||||
mapreg_table: mapreg
|
||||
partybookings_table: party_bookings
|
||||
sales_table: sales
|
||||
vending_table: vendings
|
||||
vending_items_table: vending_items
|
||||
@@ -166,7 +165,7 @@ roulette_table: db_roulette
|
||||
guild_storage_log: guild_storage_log
|
||||
|
||||
// Web Database Tables
|
||||
// NOTE: The web server reads the login (login) and char (guild) tables, so it needs
|
||||
// NOTE: The web server reads the login (login) and char (party,guild) tables and map (party_bookings), so it needs
|
||||
// the ability to connect to those databases.
|
||||
guild_emblems: guild_emblems
|
||||
user_configs: user_configs
|
||||
|
||||
@@ -1517,6 +1517,9 @@ map: bl_grass
|
||||
map: bl_lava
|
||||
map: bl_ice
|
||||
map: bl_death
|
||||
map: bl_soul
|
||||
map: bl_temple
|
||||
map: bl_venom
|
||||
|
||||
// Clock Tower: Unknown Basement
|
||||
map: clock_01
|
||||
@@ -1535,6 +1538,11 @@ map: 1@vrcas
|
||||
map: 1@vrev
|
||||
map: 1@vrgen
|
||||
map: 1@vrpo
|
||||
map: 1@vrac1
|
||||
map: 1@vrac2
|
||||
map: 1@vrclo
|
||||
map: 1@vrhha
|
||||
map: 2@vrclo
|
||||
|
||||
// ??
|
||||
map: 1@pdb
|
||||
@@ -1558,5 +1566,9 @@ map: hero_out4
|
||||
map: hero_tra
|
||||
map: herosria
|
||||
|
||||
// Level 260 Expansion
|
||||
map: mjo_wst01
|
||||
map: ra_pol01
|
||||
|
||||
//------------------------- Clone Maps ---------------------------
|
||||
//------------------------- Extra Maps ---------------------------
|
||||
|
||||
@@ -927,7 +927,10 @@
|
||||
// Enchant UI
|
||||
829: Enchanting is not possible for your item's enchant grade.
|
||||
|
||||
//830-899 free
|
||||
// @reloadbarterdb
|
||||
830: Barter database has been reloaded.
|
||||
|
||||
//831-899 free
|
||||
|
||||
//------------------------------------
|
||||
// More atcommands message
|
||||
|
||||
172
db/castle_db.yml
172
db/castle_db.yml
@@ -26,174 +26,18 @@
|
||||
# Map Map name to be considered as the castle map.
|
||||
# Name Name of the castle (used by scripts and guardian name tags).
|
||||
# Npc NPC unique name to invoke ::OnGuildBreak on, when a occupied castle is abandoned during guild break.
|
||||
# Type The WoE type this castle belongs to. (Default: First_Edition)
|
||||
# ClientId Client side ID of the castle. (Default: 0)
|
||||
# WarpEnabled If the warp to the castle is enabled. (Default: false)
|
||||
# WarpX X coordinate to warp to. (Default: 0)
|
||||
# WarpY Y coordinate to warp to. (Default: 0)
|
||||
# WarpCost Zeny cost to use the warp. (Default: 100)
|
||||
# WarpCostSiege Zeny cost to use the warp during WoE. (Default: 100000)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: CASTLE_DB
|
||||
Version: 1
|
||||
|
||||
Body:
|
||||
# WOE FE castle
|
||||
- Id: 0
|
||||
Map: aldeg_cas01
|
||||
Name: Neuschwanstein
|
||||
#Name: Noisyubantian
|
||||
Npc: Agit#aldeg_cas01
|
||||
- Id: 1
|
||||
Map: aldeg_cas02
|
||||
Name: Hohenschwangau
|
||||
#Name: Hohensyubangawoo
|
||||
Npc: Agit#aldeg_cas02
|
||||
- Id: 2
|
||||
Map: aldeg_cas03
|
||||
Name: Nuernberg
|
||||
#Name: Nyirenverk
|
||||
Npc: Agit#aldeg_cas03
|
||||
- Id: 3
|
||||
Map: aldeg_cas04
|
||||
Name: Wuerzburg
|
||||
#Name: Byirtsburi
|
||||
Npc: Agit#aldeg_cas04
|
||||
- Id: 4
|
||||
Map: aldeg_cas05
|
||||
Name: Rothenburg
|
||||
#Name: Rotenburk
|
||||
Npc: Agit#aldeg_cas05
|
||||
- Id: 5
|
||||
Map: gefg_cas01
|
||||
Name: Repherion
|
||||
#Name: Reprion
|
||||
Npc: Agit#gefg_cas01
|
||||
- Id: 6
|
||||
Map: gefg_cas02
|
||||
Name: Eeyolbriggar
|
||||
#Name: Yolbriger
|
||||
Npc: Agit#gefg_cas02
|
||||
- Id: 7
|
||||
Map: gefg_cas03
|
||||
Name: Yesnelph
|
||||
#Name: Isinlife
|
||||
Npc: Agit#gefg_cas03
|
||||
- Id: 8
|
||||
Map: gefg_cas04
|
||||
Name: Bergel
|
||||
#Name: Berigel
|
||||
Npc: Agit#gefg_cas04
|
||||
- Id: 9
|
||||
Map: gefg_cas05
|
||||
Name: Mersetzdeitz
|
||||
#Name: Melsedetsu
|
||||
Npc: Agit#gefg_cas05
|
||||
- Id: 10
|
||||
Map: payg_cas01
|
||||
Name: Bright Arbor
|
||||
#Name: Mingting
|
||||
Npc: Agit#payg_cas01
|
||||
- Id: 11
|
||||
Map: payg_cas02
|
||||
Name: Scarlet Palace
|
||||
#Name: Tiantan
|
||||
Npc: Agit#payg_cas02
|
||||
- Id: 12
|
||||
Map: payg_cas03
|
||||
Name: Holy Shadow
|
||||
#Name: Fuying
|
||||
Npc: Agit#payg_cas03
|
||||
- Id: 13
|
||||
Map: payg_cas04
|
||||
Name: Sacred Altar
|
||||
#Name: Honglou
|
||||
Npc: Agit#payg_cas04
|
||||
- Id: 14
|
||||
Map: payg_cas05
|
||||
Name: Bamboo Grove Hill
|
||||
#Name: Zhulinxian
|
||||
Npc: Agit#payg_cas05
|
||||
- Id: 15
|
||||
Map: prtg_cas01
|
||||
Name: Kriemhild
|
||||
#Name: Creamhilt
|
||||
Npc: Agit#prtg_cas01
|
||||
- Id: 16
|
||||
Map: prtg_cas02
|
||||
Name: Swanhild
|
||||
#Name: Sbanhealt
|
||||
Npc: Agit#prtg_cas02
|
||||
- Id: 17
|
||||
Map: prtg_cas03
|
||||
Name: Fadhgridh
|
||||
#Name: Lazrigees
|
||||
Npc: Agit#prtg_cas03
|
||||
- Id: 18
|
||||
Map: prtg_cas04
|
||||
Name: Skoegul
|
||||
#Name: Squagul
|
||||
Npc: Agit#prtg_cas04
|
||||
- Id: 19
|
||||
Map: prtg_cas05
|
||||
Name: Gondul
|
||||
#Name: Guindull
|
||||
Npc: Agit#prtg_cas05
|
||||
|
||||
# WOE NGuild castle
|
||||
- Id: 20
|
||||
Map: nguild_alde
|
||||
Name: Earth
|
||||
Npc: Agit_N01
|
||||
- Id: 21
|
||||
Map: nguild_gef
|
||||
Name: Air
|
||||
Npc: Agit_N02
|
||||
- Id: 22
|
||||
Map: nguild_pay
|
||||
Name: Water
|
||||
Npc: Agit_N03
|
||||
- Id: 23
|
||||
Map: nguild_prt
|
||||
Name: Fire
|
||||
Npc: Agit_N04
|
||||
|
||||
# WOE SE castle
|
||||
- Id: 24
|
||||
Map: schg_cas01
|
||||
Name: Himinn
|
||||
Npc: Manager#schg_cas01
|
||||
- Id: 25
|
||||
Map: schg_cas02
|
||||
Name: Andlangr
|
||||
Npc: Manager#schg_cas02
|
||||
- Id: 26
|
||||
Map: schg_cas03
|
||||
Name: Viblainn
|
||||
Npc: Manager#schg_cas03
|
||||
- Id: 27
|
||||
Map: schg_cas04
|
||||
Name: Hljod
|
||||
Npc: Manager#schg_cas04
|
||||
- Id: 28
|
||||
Map: schg_cas05
|
||||
Name: Skidbladnir
|
||||
Npc: Manager#schg_cas05
|
||||
- Id: 29
|
||||
Map: arug_cas01
|
||||
Name: Mardol
|
||||
Npc: Manager#arug_cas01
|
||||
- Id: 30
|
||||
Map: arug_cas02
|
||||
Name: Cyr
|
||||
Npc: Manager#arug_cas02
|
||||
- Id: 31
|
||||
Map: arug_cas03
|
||||
Name: Horn
|
||||
Npc: Manager#arug_cas03
|
||||
- Id: 32
|
||||
Map: arug_cas04
|
||||
Name: Gefn
|
||||
Npc: Manager#arug_cas04
|
||||
- Id: 33
|
||||
Map: arug_cas05
|
||||
Name: Bandis
|
||||
Npc: Manager#arug_cas05
|
||||
Version: 2
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
|
||||
@@ -26,8 +26,15 @@
|
||||
# Map Map name to be considered as the castle map.
|
||||
# Name Name of the castle (used by scripts and guardian name tags).
|
||||
# Npc NPC unique name to invoke ::OnGuildBreak on, when a occupied castle is abandoned during guild break.
|
||||
# Type The WoE type this castle belongs to. (Default: First_Edition)
|
||||
# ClientId Client side ID of the castle. (Default: 0)
|
||||
# WarpEnabled If the warp to the castle is enabled. (Default: false)
|
||||
# WarpX X coordinate to warp to. (Default: 0)
|
||||
# WarpY Y coordinate to warp to. (Default: 0)
|
||||
# WarpCost Zeny cost to use the warp. (Default: 100)
|
||||
# WarpCostSiege Zeny cost to use the warp during WoE. (Default: 100000)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: CASTLE_DB
|
||||
Version: 1
|
||||
Version: 2
|
||||
|
||||
33
db/import-tmpl/item_cash.yml
Normal file
33
db/import-tmpl/item_cash.yml
Normal file
@@ -0,0 +1,33 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2022 rAthena Development Team
|
||||
# https://rathena.org - https://github.com/rathena
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Item Cash Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Cash Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Tab Cash shop tab. Available tabs are New, Hot, Limited, Rental, Permanent, Scrolls, Consumables, Other, Sale.
|
||||
# Items: List of possible items.
|
||||
# - Item Item name.
|
||||
# Price Item cost in cash points (#CASHPOINTS).
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: ITEM_CASH_DB
|
||||
Version: 1
|
||||
@@ -1,19 +0,0 @@
|
||||
// Cash Shop Database
|
||||
// Contains the items sold in the ingame cash shop.
|
||||
//
|
||||
// Structure of Database:
|
||||
// Type,ItemID,Price
|
||||
//
|
||||
// Type:
|
||||
// 0: New
|
||||
// 1: Hot
|
||||
// 2: Limited
|
||||
// 3: Rental
|
||||
// 4: Gear
|
||||
// 5: Buff
|
||||
// 6: Heal
|
||||
// 7: Other
|
||||
// 8: Sale
|
||||
//
|
||||
// Price:
|
||||
// Item cost, in cash points (#CASHPOINTS).
|
||||
37
db/item_cash.yml
Normal file
37
db/item_cash.yml
Normal file
@@ -0,0 +1,37 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2022 rAthena Development Team
|
||||
# https://rathena.org - https://github.com/rathena
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Item Cash Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Cash Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Tab Cash shop tab. Available tabs are New, Hot, Limited, Rental, Permanent, Scrolls, Consumables, Other, Sale.
|
||||
# Items: List of possible items.
|
||||
# - Item Item name.
|
||||
# Price Item cost in cash points (#CASHPOINTS).
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: ITEM_CASH_DB
|
||||
Version: 1
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
- Path: db/import/item_cash.yml
|
||||
BIN
db/map_cache.dat
BIN
db/map_cache.dat
Binary file not shown.
@@ -1200,6 +1200,16 @@ hero_out3
|
||||
hero_out4
|
||||
hero_tra
|
||||
herosria
|
||||
1@vrac1
|
||||
1@vrac2
|
||||
1@vrclo
|
||||
1@vrhha
|
||||
2@vrclo
|
||||
bl_soul
|
||||
bl_temple
|
||||
bl_venom
|
||||
mjo_wst01
|
||||
ra_pol01
|
||||
|
||||
//======================================================================================
|
||||
// - Other/Extra maps -
|
||||
|
||||
@@ -26,8 +26,242 @@
|
||||
# Map Map name to be considered as the castle map.
|
||||
# Name Name of the castle (used by scripts and guardian name tags).
|
||||
# Npc NPC unique name to invoke ::OnGuildBreak on, when a occupied castle is abandoned during guild break.
|
||||
# Type The WoE type this castle belongs to. (Default: First_Edition)
|
||||
# ClientId Client side ID of the castle. (Default: 0)
|
||||
# WarpEnabled If the warp to the castle is enabled. (Default: false)
|
||||
# WarpX X coordinate to warp to. (Default: 0)
|
||||
# WarpY Y coordinate to warp to. (Default: 0)
|
||||
# WarpCost Zeny cost to use the warp. (Default: 100)
|
||||
# WarpCostSiege Zeny cost to use the warp during WoE. (Default: 100000)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: CASTLE_DB
|
||||
Version: 1
|
||||
Version: 2
|
||||
|
||||
Body:
|
||||
# WOE FE castle
|
||||
- Id: 0
|
||||
Map: aldeg_cas01
|
||||
Name: Neuschwanstein
|
||||
#Name: Noisyubantian
|
||||
Npc: Agit#aldeg_cas01
|
||||
Type: First_Edition
|
||||
ClientId: 6
|
||||
- Id: 1
|
||||
Map: aldeg_cas02
|
||||
Name: Hohenschwangau
|
||||
#Name: Hohensyubangawoo
|
||||
Npc: Agit#aldeg_cas02
|
||||
Type: First_Edition
|
||||
ClientId: 7
|
||||
- Id: 2
|
||||
Map: aldeg_cas03
|
||||
Name: Nuernberg
|
||||
#Name: Nyirenverk
|
||||
Npc: Agit#aldeg_cas03
|
||||
Type: First_Edition
|
||||
ClientId: 8
|
||||
- Id: 3
|
||||
Map: aldeg_cas04
|
||||
Name: Wuerzburg
|
||||
#Name: Byirtsburi
|
||||
Npc: Agit#aldeg_cas04
|
||||
Type: First_Edition
|
||||
ClientId: 9
|
||||
- Id: 4
|
||||
Map: aldeg_cas05
|
||||
Name: Rothenburg
|
||||
#Name: Rotenburk
|
||||
Npc: Agit#aldeg_cas05
|
||||
Type: First_Edition
|
||||
ClientId: 10
|
||||
- Id: 5
|
||||
Map: gefg_cas01
|
||||
Name: Repherion
|
||||
#Name: Reprion
|
||||
Npc: Agit#gefg_cas01
|
||||
Type: First_Edition
|
||||
ClientId: 11
|
||||
- Id: 6
|
||||
Map: gefg_cas02
|
||||
Name: Eeyolbriggar
|
||||
#Name: Yolbriger
|
||||
Npc: Agit#gefg_cas02
|
||||
Type: First_Edition
|
||||
ClientId: 12
|
||||
- Id: 7
|
||||
Map: gefg_cas03
|
||||
Name: Yesnelph
|
||||
#Name: Isinlife
|
||||
Npc: Agit#gefg_cas03
|
||||
Type: First_Edition
|
||||
ClientId: 13
|
||||
- Id: 8
|
||||
Map: gefg_cas04
|
||||
Name: Bergel
|
||||
#Name: Berigel
|
||||
Npc: Agit#gefg_cas04
|
||||
Type: First_Edition
|
||||
ClientId: 14
|
||||
- Id: 9
|
||||
Map: gefg_cas05
|
||||
Name: Mersetzdeitz
|
||||
#Name: Melsedetsu
|
||||
Npc: Agit#gefg_cas05
|
||||
Type: First_Edition
|
||||
ClientId: 15
|
||||
- Id: 10
|
||||
Map: payg_cas01
|
||||
Name: Bright Arbor
|
||||
#Name: Mingting
|
||||
Npc: Agit#payg_cas01
|
||||
Type: First_Edition
|
||||
ClientId: 16
|
||||
- Id: 11
|
||||
Map: payg_cas02
|
||||
Name: Scarlet Palace
|
||||
#Name: Tiantan
|
||||
Npc: Agit#payg_cas02
|
||||
Type: First_Edition
|
||||
ClientId: 17
|
||||
- Id: 12
|
||||
Map: payg_cas03
|
||||
Name: Holy Shadow
|
||||
#Name: Fuying
|
||||
Npc: Agit#payg_cas03
|
||||
Type: First_Edition
|
||||
ClientId: 18
|
||||
- Id: 13
|
||||
Map: payg_cas04
|
||||
Name: Sacred Altar
|
||||
#Name: Honglou
|
||||
Npc: Agit#payg_cas04
|
||||
Type: First_Edition
|
||||
ClientId: 19
|
||||
- Id: 14
|
||||
Map: payg_cas05
|
||||
Name: Bamboo Grove Hill
|
||||
#Name: Zhulinxian
|
||||
Npc: Agit#payg_cas05
|
||||
Type: First_Edition
|
||||
ClientId: 20
|
||||
- Id: 15
|
||||
Map: prtg_cas01
|
||||
Name: Kriemhild
|
||||
#Name: Creamhilt
|
||||
Npc: Agit#prtg_cas01
|
||||
Type: First_Edition
|
||||
ClientId: 1
|
||||
- Id: 16
|
||||
Map: prtg_cas02
|
||||
Name: Swanhild
|
||||
#Name: Sbanhealt
|
||||
Npc: Agit#prtg_cas02
|
||||
Type: First_Edition
|
||||
ClientId: 2
|
||||
- Id: 17
|
||||
Map: prtg_cas03
|
||||
Name: Fadhgridh
|
||||
#Name: Lazrigees
|
||||
Npc: Agit#prtg_cas03
|
||||
Type: First_Edition
|
||||
ClientId: 3
|
||||
- Id: 18
|
||||
Map: prtg_cas04
|
||||
Name: Skoegul
|
||||
#Name: Squagul
|
||||
Npc: Agit#prtg_cas04
|
||||
Type: First_Edition
|
||||
ClientId: 4
|
||||
- Id: 19
|
||||
Map: prtg_cas05
|
||||
Name: Gondul
|
||||
#Name: Guindull
|
||||
Npc: Agit#prtg_cas05
|
||||
Type: First_Edition
|
||||
ClientId: 5
|
||||
|
||||
# WOE NGuild castle
|
||||
- Id: 20
|
||||
Map: nguild_alde
|
||||
Name: Earth
|
||||
Npc: Agit_N01
|
||||
Type: First_Edition
|
||||
- Id: 21
|
||||
Map: nguild_gef
|
||||
Name: Air
|
||||
Npc: Agit_N02
|
||||
Type: First_Edition
|
||||
- Id: 22
|
||||
Map: nguild_pay
|
||||
Name: Water
|
||||
Npc: Agit_N03
|
||||
Type: First_Edition
|
||||
- Id: 23
|
||||
Map: nguild_prt
|
||||
Name: Fire
|
||||
Npc: Agit_N04
|
||||
Type: First_Edition
|
||||
|
||||
# WOE SE castle
|
||||
- Id: 24
|
||||
Map: schg_cas01
|
||||
Name: Himinn
|
||||
Npc: Manager#schg_cas01
|
||||
Type: Second_Edition
|
||||
ClientId: 26
|
||||
- Id: 25
|
||||
Map: schg_cas02
|
||||
Name: Andlangr
|
||||
Npc: Manager#schg_cas02
|
||||
Type: Second_Edition
|
||||
ClientId: 27
|
||||
- Id: 26
|
||||
Map: schg_cas03
|
||||
Name: Viblainn
|
||||
Npc: Manager#schg_cas03
|
||||
Type: Second_Edition
|
||||
ClientId: 28
|
||||
- Id: 27
|
||||
Map: schg_cas04
|
||||
Name: Hljod
|
||||
Npc: Manager#schg_cas04
|
||||
Type: Second_Edition
|
||||
ClientId: 29
|
||||
- Id: 28
|
||||
Map: schg_cas05
|
||||
Name: Skidbladnir
|
||||
Npc: Manager#schg_cas05
|
||||
Type: Second_Edition
|
||||
ClientId: 30
|
||||
- Id: 29
|
||||
Map: arug_cas01
|
||||
Name: Mardol
|
||||
Npc: Manager#arug_cas01
|
||||
Type: Second_Edition
|
||||
ClientId: 21
|
||||
- Id: 30
|
||||
Map: arug_cas02
|
||||
Name: Cyr
|
||||
Npc: Manager#arug_cas02
|
||||
Type: Second_Edition
|
||||
ClientId: 22
|
||||
- Id: 31
|
||||
Map: arug_cas03
|
||||
Name: Horn
|
||||
Npc: Manager#arug_cas03
|
||||
Type: Second_Edition
|
||||
ClientId: 23
|
||||
- Id: 32
|
||||
Map: arug_cas04
|
||||
Name: Gefn
|
||||
Npc: Manager#arug_cas04
|
||||
Type: Second_Edition
|
||||
ClientId: 24
|
||||
- Id: 33
|
||||
Map: arug_cas05
|
||||
Name: Bandis
|
||||
Npc: Manager#arug_cas05
|
||||
Type: Second_Edition
|
||||
ClientId: 25
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// Cash Shop Database
|
||||
// Contains the items sold in the ingame cash shop.
|
||||
//
|
||||
// Structure of Database:
|
||||
// Type,ItemID,Price
|
||||
//
|
||||
// Type:
|
||||
// 0: New
|
||||
// 1: Hot
|
||||
// 2: Limited
|
||||
// 3: Rental
|
||||
// 4: Gear
|
||||
// 5: Buff
|
||||
// 6: Heal
|
||||
// 7: Other
|
||||
// 8: Sale
|
||||
//
|
||||
// Price:
|
||||
// Item cost, in cash points (#CASHPOINTS).
|
||||
@@ -7433,3 +7433,45 @@ Body:
|
||||
Rate: 1
|
||||
- Item: Gold_Tiara_
|
||||
Rate: 1
|
||||
- Group: MF_NOTELEPORT
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Wing_Of_Fly
|
||||
- Item: Giant_Fly_Wing
|
||||
- Item: N_Fly_Wing
|
||||
- Item: E_Giant_Fly_Wing
|
||||
- Item: F_Giant_Fly_Wing
|
||||
- Group: MF_NORETURN
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Wing_Of_Butterfly
|
||||
- Item: N_Butterfly_Wing
|
||||
- Item: Dun_Tele_Scroll1
|
||||
- Item: Dun_Tele_Scroll2
|
||||
- Item: Dun_Tele_Scroll3
|
||||
- Item: E_Dun_Tele_Scroll1
|
||||
- Item: F_Dun_Tele_Scroll1
|
||||
- Item: WOB_Rune
|
||||
- Item: E_WOB_Rune
|
||||
- Item: F_WOB_Rune
|
||||
- Item: WOB_Schwaltz
|
||||
- Item: E_WOB_Schwaltz
|
||||
- Item: F_WOB_Schwaltz
|
||||
- Item: WOB_Rachel
|
||||
- Item: E_WOB_Rachel
|
||||
- Item: F_WOB_Rachel
|
||||
- Item: WOB_Local
|
||||
- Item: E_WOB_Local
|
||||
- Item: F_WOB_Local
|
||||
- Item: Siege_Teleport_Scroll
|
||||
- Item: Siege_Teleport_Scroll2
|
||||
- Item: E_Siege_Teleport_Scroll
|
||||
- Group: GIANT_FLY_WING
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Giant_Fly_Wing
|
||||
- Item: E_Giant_Fly_Wing
|
||||
- Item: F_Giant_Fly_Wing
|
||||
|
||||
@@ -245,6 +245,7 @@ Body:
|
||||
BossResist: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Refresh: true
|
||||
Inspiration: true
|
||||
@@ -273,6 +274,7 @@ Body:
|
||||
BossResist: true
|
||||
Debuff: true
|
||||
NoSaveInfinite: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Freeze: true
|
||||
Stone: true
|
||||
@@ -296,6 +298,7 @@ Body:
|
||||
Quicken: true
|
||||
Flags:
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Decreaseagi: true
|
||||
- Status: Concentrate
|
||||
@@ -306,6 +309,7 @@ Body:
|
||||
Dex: true
|
||||
Flags:
|
||||
FailedMado: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
- Status: Hiding
|
||||
@@ -324,11 +328,10 @@ Body:
|
||||
OnTouch: true
|
||||
StopAttacking: true
|
||||
RemoveOnDamaged: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
EndOnStart:
|
||||
Closeconfine: true
|
||||
Closeconfine2: true
|
||||
@@ -357,6 +360,7 @@ Body:
|
||||
Atk_Ele: true
|
||||
Flags:
|
||||
RemoveOnUnequipWeapon: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Aspersio: true
|
||||
Fireweapon: true
|
||||
@@ -369,6 +373,8 @@ Body:
|
||||
- Status: Poisonreact
|
||||
Icon: EFST_POISONREACT
|
||||
DurationLookup: AS_POISONREACT
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Quagmire
|
||||
Icon: EFST_QUAGMIRE
|
||||
DurationLookup: WZ_QUAGMIRE
|
||||
@@ -381,6 +387,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Speedup1: true
|
||||
EndOnStart:
|
||||
@@ -408,6 +415,7 @@ Body:
|
||||
Angelus: true
|
||||
Flags:
|
||||
SendOption: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Blessing
|
||||
Icon: EFST_BLESSING
|
||||
DurationLookup: AL_BLESSING
|
||||
@@ -418,6 +426,7 @@ Body:
|
||||
Flags:
|
||||
BossResist: true
|
||||
TaekwonAngel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Signumcrucis
|
||||
Icon: EFST_CRUCIS
|
||||
DurationLookup: AL_CRUCIS
|
||||
@@ -437,6 +446,7 @@ Body:
|
||||
Flags:
|
||||
FailedMado: true
|
||||
TaekwonAngel: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
EndOnStart:
|
||||
@@ -452,6 +462,7 @@ Body:
|
||||
BossResist: true
|
||||
NoSave: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Speedup1: true
|
||||
EndOnStart:
|
||||
@@ -470,6 +481,7 @@ Body:
|
||||
DurationLookup: PR_SLOWPOISON
|
||||
Flags:
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Impositio
|
||||
Icon: EFST_IMPOSITIO
|
||||
DurationLookup: PR_IMPOSITIO
|
||||
@@ -477,6 +489,7 @@ Body:
|
||||
Watk: true
|
||||
Flags:
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Impositio: true
|
||||
- Status: Suffragium
|
||||
@@ -484,6 +497,7 @@ Body:
|
||||
DurationLookup: PR_SUFFRAGIUM
|
||||
Flags:
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Aspersio
|
||||
Icon: EFST_ASPERSIO
|
||||
DurationLookup: PR_ASPERSIO
|
||||
@@ -491,6 +505,7 @@ Body:
|
||||
Atk_Ele: true
|
||||
Flags:
|
||||
RemoveOnUnequipWeapon: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Encpoison: true
|
||||
Fireweapon: true
|
||||
@@ -509,11 +524,13 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
#RemoveOnUnequipArmor: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Kyrie
|
||||
Icon: EFST_KYRIE
|
||||
DurationLookup: PR_KYRIE
|
||||
Flags:
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Assumptio: true
|
||||
- Status: Magnificat
|
||||
@@ -525,6 +542,7 @@ Body:
|
||||
FailedMado: true
|
||||
NoSave: true
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Gloria
|
||||
Icon: EFST_GLORIA
|
||||
DurationLookup: PR_GLORIA
|
||||
@@ -532,11 +550,13 @@ Body:
|
||||
Luk: true
|
||||
Flags:
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Aeterna
|
||||
Icon: EFST_LEXAETERNA
|
||||
DurationLookup: PR_LEXAETERNA
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Stone: true
|
||||
Freeze: true
|
||||
@@ -548,6 +568,7 @@ Body:
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
Decreaseagi: true
|
||||
@@ -556,6 +577,7 @@ Body:
|
||||
DurationLookup: BS_WEAPONPERFECT
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Overthrust
|
||||
Icon: EFST_OVERTHRUST
|
||||
DurationLookup: BS_OVERTHRUST
|
||||
@@ -563,6 +585,7 @@ Body:
|
||||
OverThrust: true
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Maxoverthrust: true
|
||||
- Status: Maximizepower
|
||||
@@ -572,6 +595,7 @@ Body:
|
||||
Regen: true
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Trickdead
|
||||
Icon: EFST_TRICKDEAD
|
||||
DurationLookup: NV_TRICKDEAD
|
||||
@@ -590,7 +614,8 @@ Body:
|
||||
RemoveOnDamaged: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Dancing: true
|
||||
- Status: Loud
|
||||
@@ -600,11 +625,14 @@ Body:
|
||||
Str: true
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Energycoat
|
||||
Icon: EFST_ENERGYCOAT
|
||||
DurationLookup: MG_ENERGYCOAT
|
||||
Opt3:
|
||||
EnergyCoat: true
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Brokenarmor
|
||||
Icon: EFST_BROKENARMOR
|
||||
DurationLookup: NPC_ARMORBRAKE
|
||||
@@ -656,12 +684,14 @@ Body:
|
||||
Flags:
|
||||
NoClearance: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Aspdpotion2
|
||||
Icon: EFST_ATTHASTE_POTION3
|
||||
CalcFlags:
|
||||
Aspd: true
|
||||
Flags:
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Aspdpotion3
|
||||
Icon: EFST_ATTHASTE_INFINITY
|
||||
CalcFlags:
|
||||
@@ -669,6 +699,7 @@ Body:
|
||||
Flags:
|
||||
NoClearance: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Speedup0
|
||||
Icon: EFST_MOVHASTE_HORSE
|
||||
CalcFlags:
|
||||
@@ -686,6 +717,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Atkpotion
|
||||
Icon: EFST_PLUSATTACKPOWER
|
||||
CalcFlags:
|
||||
@@ -694,6 +726,7 @@ Body:
|
||||
NoRemoveOnDead: true
|
||||
NoClearance: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Matkpotion
|
||||
Icon: EFST_PLUSMAGICPOWER
|
||||
CalcFlags:
|
||||
@@ -702,6 +735,7 @@ Body:
|
||||
NoRemoveOnDead: true
|
||||
NoClearance: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Wedding
|
||||
States:
|
||||
NoAttack: true
|
||||
@@ -732,8 +766,7 @@ Body:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
MinDuration: 5000
|
||||
- Status: Keeping
|
||||
DurationLookup: NPC_KEEPING
|
||||
@@ -745,6 +778,8 @@ Body:
|
||||
CalcFlags:
|
||||
Mdef: true
|
||||
Def: true
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Stripweapon
|
||||
Icon: EFST_NOEQUIPWEAPON
|
||||
DurationLookup: RG_STRIPWEAPON
|
||||
@@ -757,6 +792,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Stripshield
|
||||
Icon: EFST_NOEQUIPSHIELD
|
||||
DurationLookup: RG_STRIPSHIELD
|
||||
@@ -769,6 +805,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Striparmor
|
||||
Icon: EFST_NOEQUIPARMOR
|
||||
DurationLookup: RG_STRIPARMOR
|
||||
@@ -781,6 +818,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Striphelm
|
||||
Icon: EFST_NOEQUIPHELM
|
||||
DurationLookup: RG_STRIPHELM
|
||||
@@ -793,6 +831,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Cp_Weapon
|
||||
Icon: EFST_PROTECTWEAPON
|
||||
DurationLookup: AM_CP_WEAPON
|
||||
@@ -802,6 +841,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveChemicalProtect: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Cp_Shield
|
||||
Icon: EFST_PROTECTSHIELD
|
||||
DurationLookup: AM_CP_SHIELD
|
||||
@@ -811,6 +851,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveChemicalProtect: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Cp_Armor
|
||||
Icon: EFST_PROTECTARMOR
|
||||
DurationLookup: AM_CP_ARMOR
|
||||
@@ -820,6 +861,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveChemicalProtect: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Cp_Helm
|
||||
Icon: EFST_PROTECTHELM
|
||||
DurationLookup: AM_CP_HELM
|
||||
@@ -829,18 +871,21 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveChemicalProtect: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Autoguard
|
||||
Icon: EFST_AUTOGUARD
|
||||
DurationLookup: CR_AUTOGUARD
|
||||
Flags:
|
||||
NoClearance: true
|
||||
RequireShield: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Reflectshield
|
||||
Icon: EFST_REFLECTSHIELD
|
||||
DurationLookup: CR_REFLECTSHIELD
|
||||
Flags:
|
||||
NoClearance: true
|
||||
RequireShield: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Reflectdamage: true
|
||||
- Status: Splasher
|
||||
@@ -853,6 +898,7 @@ Body:
|
||||
All: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Defender
|
||||
Icon: EFST_DEFENDER
|
||||
DurationLookup: CR_DEFENDER
|
||||
@@ -861,11 +907,13 @@ Body:
|
||||
Aspd: true
|
||||
Flags:
|
||||
RequireShield: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Magicrod
|
||||
Icon: EFST_MAGICROD
|
||||
DurationLookup: SA_MAGICROD
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Spellbreaker
|
||||
Flags:
|
||||
NoWarning: true
|
||||
@@ -899,6 +947,7 @@ Body:
|
||||
Flags:
|
||||
FailedMado: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
- Status: Autocounter
|
||||
@@ -953,6 +1002,7 @@ Body:
|
||||
Debuff: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Combo
|
||||
Flags:
|
||||
NoClearbuff: true
|
||||
@@ -965,8 +1015,7 @@ Body:
|
||||
States:
|
||||
NoMove: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Bladestop
|
||||
Icon: EFST_BLADESTOP
|
||||
DurationLookup: MO_BLADESTOP
|
||||
@@ -983,7 +1032,8 @@ Body:
|
||||
NoClearbuff: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Fireweapon
|
||||
Icon: EFST_PROPERTYFIRE
|
||||
DurationLookup: SA_FLAMELAUNCHER
|
||||
@@ -1052,6 +1102,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Deluge
|
||||
Icon: EFST_GROUNDMAGIC
|
||||
DurationLookup: SA_DELUGE
|
||||
@@ -1111,6 +1162,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Parrying
|
||||
Icon: EFST_PARRYING
|
||||
DurationLookup: LK_PARRYING
|
||||
@@ -1118,6 +1170,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Concentration
|
||||
Icon: EFST_LKCONCENTRATION
|
||||
DurationLookup: LK_CONCENTRATION
|
||||
@@ -1131,6 +1184,7 @@ Body:
|
||||
Quicken: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Tensionrelax
|
||||
Icon: EFST_TENSIONRELAX
|
||||
DurationLookup: LK_TENSIONRELAX
|
||||
@@ -1139,6 +1193,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Berserk
|
||||
Icon: EFST_BERSERK
|
||||
DurationLookup: LK_BERSERK
|
||||
@@ -1179,6 +1234,7 @@ Body:
|
||||
Aspd: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Assumptio
|
||||
Icon: EFST_ASSUMPTIO
|
||||
DurationLookup: HP_ASSUMPTIO
|
||||
@@ -1187,6 +1243,8 @@ Body:
|
||||
EndOnStart:
|
||||
Kyrie: true
|
||||
Kaite: true
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Basilica
|
||||
DurationLookup: HP_BASILICA
|
||||
States:
|
||||
@@ -1196,7 +1254,8 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Guildaura
|
||||
Flags:
|
||||
NoDispell: true
|
||||
@@ -1209,6 +1268,7 @@ Body:
|
||||
Matk: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Magicpower: true
|
||||
- Status: Edp
|
||||
@@ -1234,6 +1294,7 @@ Body:
|
||||
Flags:
|
||||
FailedMado: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
- Status: Windwalk
|
||||
@@ -1245,6 +1306,7 @@ Body:
|
||||
Flags:
|
||||
FailedMado: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
- Status: Meltdown
|
||||
@@ -1288,11 +1350,10 @@ Body:
|
||||
OnTouch: true
|
||||
StopAttacking: true
|
||||
RemoveOnDamaged: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
- Status: Rejectsword
|
||||
Icon: EFST_SWORDREJECT
|
||||
DurationLookup: ST_REJECTSWORD
|
||||
@@ -1309,8 +1370,7 @@ Body:
|
||||
Opt3:
|
||||
Marionette: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Marionette: true
|
||||
- Status: Marionette2
|
||||
@@ -1326,8 +1386,7 @@ Body:
|
||||
Opt3:
|
||||
Marionette: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Marionette2: true
|
||||
- Status: Changeundead
|
||||
@@ -1341,6 +1400,7 @@ Body:
|
||||
Debuff: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Blessing: true
|
||||
Increaseagi: true
|
||||
@@ -1356,6 +1416,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Mindbreaker
|
||||
Icon: EFST_MINDBREAKER
|
||||
DurationLookup: PF_MINDBREAKER
|
||||
@@ -1365,6 +1426,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Freeze: true
|
||||
Stone: true
|
||||
@@ -1374,6 +1436,7 @@ Body:
|
||||
DurationLookup: PF_MEMORIZE
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Fogwall
|
||||
Icon: EFST_FOGWALL
|
||||
DurationLookup: PF_FOGWALL
|
||||
@@ -1381,6 +1444,7 @@ Body:
|
||||
BossResist: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Spiderweb
|
||||
Icon: EFST_SPIDERWEB
|
||||
DurationLookup: PF_SPIDERWEB
|
||||
@@ -1401,8 +1465,9 @@ Body:
|
||||
DurationLookup: CR_DEVOTION
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
EndOnEnd:
|
||||
Autoguard: true
|
||||
Defender: true
|
||||
@@ -1410,6 +1475,8 @@ Body:
|
||||
Endure: true
|
||||
- Status: Sacrifice
|
||||
DurationLookup: PA_SACRIFICE
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Steelbody
|
||||
Icon: EFST_STEELBODY
|
||||
DurationLookup: MO_STEELBODY
|
||||
@@ -1422,6 +1489,7 @@ Body:
|
||||
Speed: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
Opt3:
|
||||
SteelBody: true
|
||||
- Status: Orcish
|
||||
@@ -1485,7 +1553,8 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Shadowweapon
|
||||
Icon: EFST_PROPERTYDARK
|
||||
DurationLookup: TK_SEVENWIND
|
||||
@@ -1494,6 +1563,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Encpoison: true
|
||||
Aspersio: true
|
||||
@@ -1511,6 +1581,7 @@ Body:
|
||||
MadoCancel: true
|
||||
NoSave: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
Decreaseagi: true
|
||||
@@ -1522,6 +1593,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Encpoison: true
|
||||
Aspersio: true
|
||||
@@ -1539,6 +1611,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Kaahi: true
|
||||
- Status: Kaupe
|
||||
@@ -1547,6 +1620,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Onehand
|
||||
Icon: EFST_ONEHANDQUICKEN
|
||||
DurationLookup: KN_ONEHAND
|
||||
@@ -1558,6 +1632,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Decreaseagi: true
|
||||
EndOnStart:
|
||||
@@ -1570,6 +1645,7 @@ Body:
|
||||
DurationLookup: ST_PRESERVE
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Battleorders
|
||||
Icon: EFST_GDSKILL_BATTLEORDER
|
||||
DurationLookup: GD_BATTLEORDER
|
||||
@@ -1593,6 +1669,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Gravitation
|
||||
Icon: EFST_GRAVITATION
|
||||
DurationLookup: HW_GRAVITATION
|
||||
@@ -1607,6 +1684,7 @@ Body:
|
||||
BossResist: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Maxoverthrust
|
||||
Icon: EFST_OVERTHRUSTMAX
|
||||
DurationLookup: WS_OVERTHRUSTMAX
|
||||
@@ -1615,6 +1693,7 @@ Body:
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Overthrust: true
|
||||
- Status: Longing
|
||||
@@ -1663,7 +1742,7 @@ Body:
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
NoRemoveOnDead: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Closeconfine2
|
||||
Icon: EFST_RG_CCONFINE_S
|
||||
DurationLookup: RG_CLOSECONFINE
|
||||
@@ -1676,7 +1755,7 @@ Body:
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
NoRemoveOnDead: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Closeconfine2: true
|
||||
- Status: Dancing
|
||||
@@ -1693,10 +1772,9 @@ Body:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RequireWeapon: true
|
||||
OverlapIgnoreLevel: true
|
||||
NoSave: true
|
||||
EndOnEnd:
|
||||
Longing: true
|
||||
- Status: Elementalchange
|
||||
@@ -1860,8 +1938,9 @@ Body:
|
||||
StopWalking: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Spurt
|
||||
Icon: EFST_STRUP
|
||||
DurationLookup: TK_RUN
|
||||
@@ -1871,6 +1950,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Spirit
|
||||
Icon: EFST_SOULLINK
|
||||
DurationLookup: SL_HIGH
|
||||
@@ -1882,6 +1962,7 @@ Body:
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
NoBanishingBuster: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Coma
|
||||
DurationLookup: NPC_DARKBLESSING
|
||||
Flags:
|
||||
@@ -2176,8 +2257,8 @@ Body:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
- Status: Sun_Comfort
|
||||
Icon: EFST_SUN_COMFORT
|
||||
DurationLookup: SG_SUN_COMFORT
|
||||
@@ -2185,7 +2266,6 @@ Body:
|
||||
Def2: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
- Status: Moon_Comfort
|
||||
Icon: EFST_MOON_COMFORT
|
||||
DurationLookup: SG_MOON_COMFORT
|
||||
@@ -2193,7 +2273,6 @@ Body:
|
||||
Flee: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
- Status: Star_Comfort
|
||||
Icon: EFST_STAR_COMFORT
|
||||
DurationLookup: SG_STAR_COMFORT
|
||||
@@ -2201,7 +2280,6 @@ Body:
|
||||
Aspd: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
- Status: Fusion
|
||||
DurationLookup: SG_FUSION
|
||||
CalcFlags:
|
||||
@@ -2232,6 +2310,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Assumptio: true
|
||||
- Status: Swoo
|
||||
@@ -2331,6 +2410,7 @@ Body:
|
||||
NoClearance: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Bunsinjyutsu
|
||||
Icon: EFST_NJ_BUNSINJYUTSU
|
||||
DurationLookup: NJ_BUNSINJYUTSU
|
||||
@@ -2341,6 +2421,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Kaensin
|
||||
Flags:
|
||||
NoWarning: true
|
||||
@@ -2397,8 +2478,7 @@ Body:
|
||||
Vit: true
|
||||
Int: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Change: true
|
||||
- Status: Bloodlust
|
||||
@@ -2456,6 +2536,7 @@ Body:
|
||||
SendVal1: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnUnequipWeapon: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Enchantarms: true
|
||||
Aspersio: true
|
||||
@@ -3209,7 +3290,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Bite
|
||||
Icon: EFST_WUGBITE
|
||||
DurationLookup: RA_WUGBITE
|
||||
@@ -3241,7 +3322,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Acceleration
|
||||
Icon: EFST_ACCELERATION
|
||||
DurationLookup: NC_ACCELERATION
|
||||
@@ -3323,7 +3404,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Stealthfield
|
||||
Icon: EFST_STEALTHFIELD
|
||||
DurationLookup: NC_STEALTHFIELD
|
||||
@@ -3346,7 +3427,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Overheat
|
||||
Icon: EFST_OVERHEAT
|
||||
Flags:
|
||||
@@ -3755,7 +3836,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Debuff: true
|
||||
Fail:
|
||||
Hallucinationwalk: true
|
||||
@@ -4142,7 +4223,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
StopAttacking: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Cursedcircle_Target
|
||||
Icon: EFST_CURSEDCIRCLE_TARGET
|
||||
DurationLookup: SR_CURSEDCIRCLE
|
||||
@@ -4484,7 +4565,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: _Bodypaint
|
||||
Icon: EFST_BODYPAINT
|
||||
DurationLookup: SC_BODYPAINT
|
||||
@@ -4618,8 +4699,7 @@ Body:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: _Bloodylust
|
||||
Icon: EFST_BLOODYLUST
|
||||
DurationLookup: SC_BLOODYLUST
|
||||
@@ -5213,7 +5293,7 @@ Body:
|
||||
Flags:
|
||||
StopWalking: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Tinder_Breaker2
|
||||
Icon: EFST_TINDER_BREAKER
|
||||
DurationLookup: MH_TINDER_BREAKER
|
||||
@@ -5224,7 +5304,7 @@ Body:
|
||||
Flags:
|
||||
StopWalking: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Cbc
|
||||
Icon: EFST_CBC
|
||||
DurationLookup: MH_CBC
|
||||
@@ -5758,9 +5838,10 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Mtf_Aspd2
|
||||
Icon: EFST_MTF_ASPD2
|
||||
CalcFlags:
|
||||
@@ -6063,6 +6144,7 @@ Body:
|
||||
Flags:
|
||||
StopAttacking: true
|
||||
RemoveOnDamaged: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnMapWarp: true
|
||||
- Status: Su_Stoop
|
||||
Icon: EFST_SU_STOOP
|
||||
@@ -6364,6 +6446,7 @@ Body:
|
||||
Flags:
|
||||
NoRemoveOnDead: true
|
||||
NoClearbuff: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Geffen_Magic2
|
||||
Icon: EFST_GEFFEN_MAGIC2
|
||||
CalcFlags:
|
||||
@@ -6628,8 +6711,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoClearbuff: true
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Entry_Queue_Apply_Delay
|
||||
Icon: EFST_ENTRY_QUEUE_APPLY_DELAY
|
||||
Flags:
|
||||
@@ -6701,7 +6783,7 @@ Body:
|
||||
Icon: EFST_FLASHKICK
|
||||
DurationLookup: SJ_FLASHKICK
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
@@ -6718,7 +6800,7 @@ Body:
|
||||
NoClearance: true
|
||||
StopAttacking: true
|
||||
RemoveOnDamaged: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Bite: true
|
||||
- Status: Starstance
|
||||
|
||||
@@ -26,51 +26,384 @@
|
||||
# Map Map name to be considered as the castle map.
|
||||
# Name Name of the castle (used by scripts and guardian name tags).
|
||||
# Npc NPC unique name to invoke ::OnGuildBreak on, when a occupied castle is abandoned during guild break.
|
||||
# Type The WoE type this castle belongs to. (Default: First_Edition)
|
||||
# ClientId Client side ID of the castle. (Default: 0)
|
||||
# WarpEnabled If the warp to the castle is enabled. (Default: false)
|
||||
# WarpX X coordinate to warp to. (Default: 0)
|
||||
# WarpY Y coordinate to warp to. (Default: 0)
|
||||
# WarpCost Zeny cost to use the warp. (Default: 100)
|
||||
# WarpCostSiege Zeny cost to use the warp during WoE. (Default: 100000)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: CASTLE_DB
|
||||
Version: 1
|
||||
Version: 2
|
||||
|
||||
Body:
|
||||
# WOE FE castle
|
||||
- Id: 0
|
||||
Map: aldeg_cas01
|
||||
Name: Neuschwanstein
|
||||
#Name: Noisyubantian
|
||||
Npc: Agit#aldeg_cas01
|
||||
Type: First_Edition
|
||||
ClientId: 6
|
||||
WarpEnabled: true
|
||||
WarpX: 212
|
||||
WarpY: 175
|
||||
- Id: 1
|
||||
Map: aldeg_cas02
|
||||
Name: Hohenschwangau
|
||||
#Name: Hohensyubangawoo
|
||||
Npc: Agit#aldeg_cas02
|
||||
Type: First_Edition
|
||||
ClientId: 7
|
||||
WarpEnabled: true
|
||||
WarpX: 82
|
||||
WarpY: 71
|
||||
- Id: 2
|
||||
Map: aldeg_cas03
|
||||
Name: Nuernberg
|
||||
#Name: Nyirenverk
|
||||
Npc: Agit#aldeg_cas03
|
||||
Type: First_Edition
|
||||
ClientId: 8
|
||||
WarpEnabled: true
|
||||
WarpX: 109
|
||||
WarpY: 112
|
||||
- Id: 3
|
||||
Map: aldeg_cas04
|
||||
Name: Wuerzburg
|
||||
#Name: Byirtsburi
|
||||
Npc: Agit#aldeg_cas04
|
||||
Type: First_Edition
|
||||
ClientId: 9
|
||||
WarpEnabled: true
|
||||
WarpX: 60
|
||||
WarpY: 116
|
||||
- Id: 4
|
||||
Map: aldeg_cas05
|
||||
Name: Rothenburg
|
||||
#Name: Rotenburk
|
||||
Npc: Agit#aldeg_cas05
|
||||
Type: First_Edition
|
||||
ClientId: 10
|
||||
WarpEnabled: true
|
||||
WarpX: 61
|
||||
WarpY: 185
|
||||
- Id: 5
|
||||
Map: gefg_cas01
|
||||
Name: Repherion
|
||||
#Name: Reprion
|
||||
Npc: Agit#gefg_cas01
|
||||
Type: First_Edition
|
||||
ClientId: 11
|
||||
WarpEnabled: true
|
||||
WarpX: 40
|
||||
WarpY: 43
|
||||
- Id: 6
|
||||
Map: gefg_cas02
|
||||
Name: Eeyolbriggar
|
||||
#Name: Yolbriger
|
||||
Npc: Agit#gefg_cas02
|
||||
Type: First_Edition
|
||||
ClientId: 12
|
||||
WarpEnabled: true
|
||||
WarpX: 22
|
||||
WarpY: 66
|
||||
- Id: 7
|
||||
Map: gefg_cas03
|
||||
Name: Yesnelph
|
||||
#Name: Isinlife
|
||||
Npc: Agit#gefg_cas03
|
||||
Type: First_Edition
|
||||
ClientId: 13
|
||||
WarpEnabled: true
|
||||
WarpX: 112
|
||||
WarpY: 23
|
||||
- Id: 8
|
||||
Map: gefg_cas04
|
||||
Name: Bergel
|
||||
#Name: Berigel
|
||||
Npc: Agit#gefg_cas04
|
||||
Type: First_Edition
|
||||
ClientId: 14
|
||||
WarpEnabled: true
|
||||
WarpX: 58
|
||||
WarpY: 46
|
||||
- Id: 9
|
||||
Map: gefg_cas05
|
||||
Name: Mersetzdeitz
|
||||
#Name: Melsedetsu
|
||||
Npc: Agit#gefg_cas05
|
||||
Type: First_Edition
|
||||
ClientId: 15
|
||||
WarpEnabled: true
|
||||
WarpX: 66
|
||||
WarpY: 48
|
||||
- Id: 10
|
||||
Map: payg_cas01
|
||||
Name: Bright Arbor
|
||||
#Name: Mingting
|
||||
Npc: Agit#payg_cas01
|
||||
Type: First_Edition
|
||||
ClientId: 16
|
||||
WarpEnabled: true
|
||||
WarpX: 115
|
||||
WarpY: 57
|
||||
- Id: 11
|
||||
Map: payg_cas02
|
||||
Name: Scarlet Palace
|
||||
#Name: Tiantan
|
||||
Npc: Agit#payg_cas02
|
||||
Type: First_Edition
|
||||
ClientId: 17
|
||||
WarpEnabled: true
|
||||
WarpX: 26
|
||||
WarpY: 265
|
||||
- Id: 12
|
||||
Map: payg_cas03
|
||||
Name: Holy Shadow
|
||||
#Name: Fuying
|
||||
Npc: Agit#payg_cas03
|
||||
Type: First_Edition
|
||||
ClientId: 18
|
||||
WarpEnabled: true
|
||||
WarpX: 43
|
||||
WarpY: 264
|
||||
- Id: 13
|
||||
Map: payg_cas04
|
||||
Name: Sacred Altar
|
||||
#Name: Honglou
|
||||
Npc: Agit#payg_cas04
|
||||
Type: First_Edition
|
||||
ClientId: 19
|
||||
WarpEnabled: true
|
||||
WarpX: 36
|
||||
WarpY: 272
|
||||
- Id: 14
|
||||
Map: payg_cas05
|
||||
Name: Bamboo Grove Hill
|
||||
#Name: Zhulinxian
|
||||
Npc: Agit#payg_cas05
|
||||
Type: First_Edition
|
||||
ClientId: 20
|
||||
WarpEnabled: true
|
||||
WarpX: 274
|
||||
WarpY: 246
|
||||
- Id: 15
|
||||
Map: prtg_cas01
|
||||
Name: Kriemhild
|
||||
#Name: Creamhilt
|
||||
Npc: Agit#prtg_cas01
|
||||
Type: First_Edition
|
||||
ClientId: 1
|
||||
WarpEnabled: true
|
||||
WarpX: 107
|
||||
WarpY: 180
|
||||
- Id: 16
|
||||
Map: prtg_cas02
|
||||
Name: Swanhild
|
||||
#Name: Sbanhealt
|
||||
Npc: Agit#prtg_cas02
|
||||
Type: First_Edition
|
||||
ClientId: 2
|
||||
WarpEnabled: true
|
||||
WarpX: 94
|
||||
WarpY: 56
|
||||
- Id: 17
|
||||
Map: prtg_cas03
|
||||
Name: Fadhgridh
|
||||
#Name: Lazrigees
|
||||
Npc: Agit#prtg_cas03
|
||||
Type: First_Edition
|
||||
ClientId: 3
|
||||
WarpEnabled: true
|
||||
WarpX: 46
|
||||
WarpY: 97
|
||||
- Id: 18
|
||||
Map: prtg_cas04
|
||||
Name: Skoegul
|
||||
#Name: Squagul
|
||||
Npc: Agit#prtg_cas04
|
||||
Type: First_Edition
|
||||
ClientId: 4
|
||||
WarpEnabled: true
|
||||
WarpX: 260
|
||||
WarpY: 262
|
||||
- Id: 19
|
||||
Map: prtg_cas05
|
||||
Name: Gondul
|
||||
#Name: Guindull
|
||||
Npc: Agit#prtg_cas05
|
||||
Type: First_Edition
|
||||
ClientId: 5
|
||||
WarpEnabled: true
|
||||
WarpX: 26
|
||||
WarpY: 38
|
||||
|
||||
# WOE NGuild castle
|
||||
- Id: 20
|
||||
Map: nguild_alde
|
||||
Name: Earth
|
||||
Npc: Agit_N01
|
||||
Type: First_Edition
|
||||
- Id: 21
|
||||
Map: nguild_gef
|
||||
Name: Air
|
||||
Npc: Agit_N02
|
||||
Type: First_Edition
|
||||
- Id: 22
|
||||
Map: nguild_pay
|
||||
Name: Water
|
||||
Npc: Agit_N03
|
||||
Type: First_Edition
|
||||
- Id: 23
|
||||
Map: nguild_prt
|
||||
Name: Fire
|
||||
Npc: Agit_N04
|
||||
Type: First_Edition
|
||||
|
||||
# WOE SE castle
|
||||
- Id: 24
|
||||
Map: schg_cas01
|
||||
Name: Himinn
|
||||
Npc: Manager#schg_cas01
|
||||
Type: Second_Edition
|
||||
ClientId: 26
|
||||
WarpEnabled: true
|
||||
WarpX: 233
|
||||
WarpY: 300
|
||||
- Id: 25
|
||||
Map: schg_cas02
|
||||
Name: Andlangr
|
||||
Npc: Manager#schg_cas02
|
||||
Type: Second_Edition
|
||||
ClientId: 27
|
||||
WarpEnabled: true
|
||||
WarpX: 101
|
||||
WarpY: 372
|
||||
- Id: 26
|
||||
Map: schg_cas03
|
||||
Name: Viblainn
|
||||
Npc: Manager#schg_cas03
|
||||
Type: Second_Edition
|
||||
ClientId: 28
|
||||
WarpEnabled: true
|
||||
WarpX: 81
|
||||
WarpY: 94
|
||||
- Id: 27
|
||||
Map: schg_cas04
|
||||
Name: Hljod
|
||||
Npc: Manager#schg_cas04
|
||||
Type: Second_Edition
|
||||
ClientId: 29
|
||||
WarpEnabled: true
|
||||
WarpX: 233
|
||||
WarpY: 300
|
||||
- Id: 28
|
||||
Map: schg_cas05
|
||||
Name: Skidbladnir
|
||||
Npc: Manager#schg_cas05
|
||||
Type: Second_Edition
|
||||
ClientId: 30
|
||||
WarpEnabled: true
|
||||
WarpX: 233
|
||||
WarpY: 300
|
||||
- Id: 29
|
||||
Map: arug_cas01
|
||||
Name: Mardol
|
||||
Npc: Manager#arug_cas01
|
||||
Type: Second_Edition
|
||||
ClientId: 21
|
||||
WarpEnabled: true
|
||||
WarpX: 77
|
||||
WarpY: 371
|
||||
- Id: 30
|
||||
Map: arug_cas02
|
||||
Name: Cyr
|
||||
Npc: Manager#arug_cas02
|
||||
Type: Second_Edition
|
||||
ClientId: 22
|
||||
WarpEnabled: true
|
||||
WarpX: 301
|
||||
WarpY: 332
|
||||
- Id: 31
|
||||
Map: arug_cas03
|
||||
Name: Horn
|
||||
Npc: Manager#arug_cas03
|
||||
Type: Second_Edition
|
||||
ClientId: 23
|
||||
WarpEnabled: true
|
||||
WarpX: 322
|
||||
WarpY: 91
|
||||
- Id: 32
|
||||
Map: arug_cas04
|
||||
Name: Gefn
|
||||
Npc: Manager#arug_cas04
|
||||
Type: Second_Edition
|
||||
ClientId: 24
|
||||
WarpEnabled: true
|
||||
WarpX: 322
|
||||
WarpY: 91
|
||||
- Id: 33
|
||||
Map: arug_cas05
|
||||
Name: Bandis
|
||||
Npc: Manager#arug_cas05
|
||||
Type: Second_Edition
|
||||
ClientId: 25
|
||||
WarpEnabled: true
|
||||
WarpX: 322
|
||||
WarpY: 91
|
||||
|
||||
# WOE TE castle
|
||||
- Id: 34
|
||||
Map: te_aldecas1
|
||||
Name: Kafragarten 1
|
||||
Npc: Manager_TE#Glaris
|
||||
Type: Third_Edition
|
||||
- Id: 35
|
||||
Map: te_aldecas2
|
||||
Name: Kafragarten 2
|
||||
Npc: Manager_TE#Defolty
|
||||
Type: Third_Edition
|
||||
- Id: 36
|
||||
Map: te_aldecas3
|
||||
Name: Kafragarten 3
|
||||
Npc: Manager_TE#Sorin
|
||||
Type: Third_Edition
|
||||
- Id: 37
|
||||
Map: te_aldecas4
|
||||
Name: Kafragarten 4
|
||||
Npc: Manager_TE#Bennit
|
||||
Type: Third_Edition
|
||||
- Id: 38
|
||||
Map: te_aldecas5
|
||||
Name: Kafragarten 5
|
||||
Npc: Manager_TE#W
|
||||
Type: Third_Edition
|
||||
- Id: 39
|
||||
Map: te_prtcas01
|
||||
Name: Gloria 1
|
||||
Npc: Manager_TE#Gaebolg
|
||||
Type: Third_Edition
|
||||
- Id: 40
|
||||
Map: te_prtcas02
|
||||
Name: Gloria 2
|
||||
Npc: Manager_TE#Richard
|
||||
Type: Third_Edition
|
||||
- Id: 41
|
||||
Map: te_prtcas03
|
||||
Name: Gloria 3
|
||||
Npc: Manager_TE#Wigner
|
||||
Type: Third_Edition
|
||||
- Id: 42
|
||||
Map: te_prtcas04
|
||||
Name: Gloria 4
|
||||
Npc: Manager_TE#Heine
|
||||
Type: Third_Edition
|
||||
- Id: 43
|
||||
Map: te_prtcas05
|
||||
Name: Gloria 5
|
||||
Npc: Manager_TE#Nerious
|
||||
Type: Third_Edition
|
||||
|
||||
@@ -1,19 +0,0 @@
|
||||
// Cash Shop Database
|
||||
// Contains the items sold in the ingame cash shop.
|
||||
//
|
||||
// Structure of Database:
|
||||
// Type,ItemID,Price
|
||||
//
|
||||
// Type:
|
||||
// 0: New
|
||||
// 1: Hot
|
||||
// 2: Limited
|
||||
// 3: Rental
|
||||
// 4: Gear
|
||||
// 5: Buff
|
||||
// 6: Heal
|
||||
// 7: Other
|
||||
// 8: Sale
|
||||
//
|
||||
// Price:
|
||||
// Item cost, in cash points (#CASHPOINTS).
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -25723,7 +25723,7 @@ Body:
|
||||
Rate: 140
|
||||
- Item: C_Pig_Nose
|
||||
Rate: 140
|
||||
- Item: C_Cat_Ears_Hat
|
||||
- Item: C_Cat_Ear_Hat
|
||||
Rate: 140
|
||||
- Item: C_Valkyrie_Circlet
|
||||
Rate: 140
|
||||
@@ -25996,7 +25996,7 @@ Body:
|
||||
Rate: 140
|
||||
- Item: C_Poring_On_Shoulder
|
||||
Rate: 140
|
||||
- Item: Costume_Yawata_Seal
|
||||
- Item: C_FortunetellinSealed
|
||||
Rate: 140
|
||||
- Item: C_Pretty_Bear_WH
|
||||
Rate: 140
|
||||
@@ -26008,7 +26008,7 @@ Body:
|
||||
Rate: 140
|
||||
- Item: C_Dark_Snake_Lord_Stall
|
||||
Rate: 140
|
||||
- Item: Costume_Twin_Cannon
|
||||
- Item: C_Twin_Canon
|
||||
Rate: 140
|
||||
- Item: C_Picnic_Basket
|
||||
Rate: 140
|
||||
@@ -26070,13 +26070,13 @@ Body:
|
||||
Rate: 140
|
||||
- Item: C_LittleGarden
|
||||
Rate: 140
|
||||
- Item: Costume_Twinkling_Red_Eyes
|
||||
- Item: C_Blinking_Eyes_RD
|
||||
Rate: 140
|
||||
- Item: C_Blink_Eyes_Sakura
|
||||
Rate: 140
|
||||
- Item: Costume_Angola_Intention
|
||||
- Item: C_Angola_Intention
|
||||
Rate: 140
|
||||
- Item: C_Stole_Of_Dominion
|
||||
- Item: C_Stall_Of_Dominions
|
||||
Rate: 140
|
||||
- Item: C_Flowery_Vision_TH
|
||||
Rate: 140
|
||||
@@ -26100,7 +26100,7 @@ Body:
|
||||
Rate: 130
|
||||
- Item: C_Blessings_Of_Soul
|
||||
Rate: 130
|
||||
- Item: C_Crow
|
||||
- Item: C_Gossip_Raven
|
||||
Rate: 130
|
||||
- Item: C_Halloween_Hat
|
||||
Rate: 130
|
||||
@@ -26118,7 +26118,7 @@ Body:
|
||||
Rate: 130
|
||||
- Item: C_Gift_Of_Snow
|
||||
Rate: 130
|
||||
- Item: C_Large_Ribbon_Muffler_Red
|
||||
- Item: C_L_RibbonMuff_Red
|
||||
Rate: 130
|
||||
- Item: C_Imperial_Glory
|
||||
Rate: 130
|
||||
@@ -48211,3 +48211,788 @@ Body:
|
||||
- Item: Trans_Scroll_Gazeti
|
||||
- Item: Trans_Scroll_Kobold_Archer
|
||||
- Item: Trans_Scroll_Necromancer
|
||||
- Group: S_W_BREATH_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_W_Breath_Armor
|
||||
- Item: S_W_Breath_Shield
|
||||
- Item: S_W_Breath_Shoes
|
||||
- Group: S_F_BREATH_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_F_Breath_Weapon
|
||||
- Item: S_F_Breath_Pendant
|
||||
- Item: S_F_Breath_Earing
|
||||
- Group: S_SONIC_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Sonic_Armor
|
||||
- Item: S_Sonic_Shield
|
||||
- Item: S_Sonic_Shoes
|
||||
- Group: S_STRAIN_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Strain_Weapon
|
||||
- Item: S_Strain_Pendant
|
||||
- Item: S_Strain_Earing
|
||||
- Group: S_JACK_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Jack_Armor
|
||||
- Item: S_Jack_Shield
|
||||
- Item: S_Jack_Shoes
|
||||
- Group: S_CHAIN_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Chain_Weapon
|
||||
- Item: S_Chain_Pendant
|
||||
- Item: S_Chain_Earing
|
||||
- Group: S_CRIMSON_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Crimson_Armor
|
||||
- Item: S_Crimson_Shield
|
||||
- Item: S_Crimson_Shoes
|
||||
- Group: S_VULCAN_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Vulcan_Armor
|
||||
- Item: S_Vulcan_Shield
|
||||
- Item: S_Vulcan_Shoes
|
||||
- Group: S_BOOMERANG_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Boomerang_Weapon
|
||||
- Item: S_Boomerang_Pendant
|
||||
- Item: S_Boomerang_Earing
|
||||
- Group: S_ARMS_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Arms_Weapon
|
||||
- Item: S_Arms_Pendant
|
||||
- Item: S_Arms_Earing
|
||||
- Group: S_TORNADO_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Tornado_Armor
|
||||
- Item: S_Tornado_Shield
|
||||
- Item: S_Tornado_Shoes
|
||||
- Group: S_DUPLELIGHT_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Duplelight_Armor
|
||||
- Item: S_Duplelight_Shield
|
||||
- Item: S_Duplelight_Shoes
|
||||
- Group: S_MAGNUS_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Magnus_Weapon
|
||||
- Item: S_Magnus_Pendant
|
||||
- Item: S_Magnus_Earing
|
||||
- Group: S_ADORAMUS_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Adoramus_Weapon
|
||||
- Item: S_Adoramus_Pendant
|
||||
- Item: S_Adoramus_Earing
|
||||
- Group: S_JUDEX_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Judex_Armor
|
||||
- Item: S_Judex_Shield
|
||||
- Item: S_Judex_Shoes
|
||||
- Group: S_ROLLING_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Rolling_Armor
|
||||
- Item: S_Rolling_Shield
|
||||
- Item: S_Rolling_Shoes
|
||||
- Group: S_RIPPER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Ripper_Weapon
|
||||
- Item: S_Ripper_Pendant
|
||||
- Item: S_Ripper_Earing
|
||||
- Group: S_SLASH_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Slash_Armor
|
||||
- Item: S_Slash_Shield
|
||||
- Item: S_Slash_Shoes
|
||||
- Group: S_KATAR_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Slash_Armor
|
||||
- Item: S_Slash_Shield
|
||||
- Item: S_Slash_Shoes
|
||||
- Group: S_SHOOTING_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Shooting_Weapon
|
||||
- Item: S_Shooting_Pendant
|
||||
- Item: S_Shooting_Earing
|
||||
- Group: S_ARROW_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Arrow_Armor
|
||||
- Item: S_Arrow_Shield
|
||||
- Item: S_Arrow_Shoes
|
||||
- Group: S_AIMED_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Aimed_Weapon
|
||||
- Item: S_Aimed_Pendant
|
||||
- Item: S_Aimed_Earing
|
||||
- Group: S_CLUSTER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Aimed_Weapon
|
||||
- Item: S_Aimed_Pendant
|
||||
- Item: S_Aimed_Earing
|
||||
- Group: S_BANISH_CANNON_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Banish_Cannon_Armor
|
||||
- Item: S_Banish_Cannon_Shield
|
||||
- Item: S_Banish_Cannon_Shoes
|
||||
- Group: S_BRAND_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Brand_Armor
|
||||
- Item: S_Brand_Shield
|
||||
- Item: S_Brand_Shoes
|
||||
- Group: S_GENESIS_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Genesis_Weapon
|
||||
- Item: S_Genesis_Pendant
|
||||
- Item: S_Genesis_Earing
|
||||
- Group: S_CHAIN_PRESS_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Chain_Press_Weapon
|
||||
- Item: S_Chain_Press_Pendant
|
||||
- Item: S_Chain_Press_Earing
|
||||
- Group: S_GRAVE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Grave_Weapon
|
||||
- Item: S_Grave_Pendant
|
||||
- Item: S_Grave_Earing
|
||||
- Group: S_DUST_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Dust_Armor
|
||||
- Item: S_Dust_Shield
|
||||
- Item: S_Dust_Shoes
|
||||
- Group: S_VARETYR_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Varetyr_Weapon
|
||||
- Item: S_Varetyr_Pendant
|
||||
- Item: S_Varetyr_Earing
|
||||
- Group: S_PSYCHIC_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Psychic_Armor
|
||||
- Item: S_Psychic_Shield
|
||||
- Item: S_Psychic_Shoes
|
||||
- Group: S_SPORE_BOMB_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Spore_Bomb_Armor
|
||||
- Item: S_Spore_Bomb_Shield
|
||||
- Item: S_Spore_Bomb_Shoes
|
||||
- Group: S_CANNON_CART_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Cannon_Cart_Weapon
|
||||
- Item: S_Cannon_Cart_Pendant
|
||||
- Item: S_Cannon_Cart_Earing
|
||||
- Group: S_CRAZY_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Crazy_Weapon
|
||||
- Item: S_Crazy_Pendant
|
||||
- Item: S_Crazy_Earing
|
||||
- Group: S_CART_TORNADO_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Cart_Tornado_Armor
|
||||
- Item: S_Cart_Tornado_Shield
|
||||
- Item: S_Cart_Tornado_Shoes
|
||||
- Group: S_KNUCKLEARROW_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Knucklearrow_Armor
|
||||
- Item: S_Knucklearrow_Shield
|
||||
- Item: S_Knucklearrow_Shoes
|
||||
- Group: S_SKYNETBLOW_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Skynetblow_Weapon
|
||||
- Item: S_Skynetblow_Pendant
|
||||
- Item: S_Skynetblow_Earing
|
||||
- Group: S_RAMPAGE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Rampage_Armor
|
||||
- Item: S_Rampage_Shield
|
||||
- Item: S_Rampage_Shoes
|
||||
- Group: S_TIGERCANNON_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_TigerCannon_Weapon
|
||||
- Item: S_Tigercannon_Pendant
|
||||
- Item: S_Tigercannon_Earing
|
||||
- Group: S_MENACE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Menace_Armor
|
||||
- Item: S_Menace_Shield
|
||||
- Item: S_Menace_Shoes
|
||||
- Group: S_SHADOWSPELL_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Shadowspell_Weapon
|
||||
- Item: S_Shadowspell_Pendant
|
||||
- Item: S_Shadowspell_Earing
|
||||
- Group: S_TRIANGLE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Triangle_Armor
|
||||
- Item: S_Triangle_Shield
|
||||
- Item: S_Triangle_Shoes
|
||||
- Group: S_PAINT_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Paint_Weapon
|
||||
- Item: S_Paint_Pendant
|
||||
- Item: S_Paint_Earing
|
||||
- Group: S_RAINSTORM_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Rainstorm_Armor
|
||||
- Item: S_Rainstorm_Shield
|
||||
- Item: S_Rainstorm_Shoes
|
||||
- Group: S_METALIC_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Metalic_Armor
|
||||
- Item: S_Metalic_Shield
|
||||
- Item: S_Metalic_Shoes
|
||||
- Group: S_ARROWVULCAN_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Arrowvulcan_Weapon
|
||||
- Item: S_Arrowvulcan_Pendant
|
||||
- Item: S_Arrowvulcan_Earing
|
||||
- Group: S_REVERBERATION_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Reverberation_Weapon
|
||||
- Item: S_Reverberation_Pendant
|
||||
- Item: S_Reverberation_Earing
|
||||
- Group: S_MOONLIGHT_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Moonlight_Earring
|
||||
- Item: S_Moonlight_Pendant
|
||||
- Item: S_Moonlight_Shoes
|
||||
- Group: S_SUNSHINE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Sunshine_Weapon
|
||||
- Item: S_Sunshine_Shield
|
||||
- Item: S_Sunshine_Armor
|
||||
- Group: S_STARDUST_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Stardust_Weapon
|
||||
- Item: S_Stardust_Shield
|
||||
- Item: S_Stardust_Armor
|
||||
- Group: S_S_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_S_Weapon
|
||||
- Item: S_S_Shield
|
||||
- Item: S_S_Armor
|
||||
- Group: S_EVILCURSE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Evilcurse_Earring
|
||||
- Item: S_Evilcurse_Pendant
|
||||
- Item: S_Evilcurse_Shoes
|
||||
- Group: S_SYURIKEN_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Syuriken_Earing
|
||||
- Item: S_Syuriken_Pendant
|
||||
- Item: S_Syuriken_Shoes
|
||||
- Group: S_KUNAI_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Kunai_Weapon
|
||||
- Item: S_Kunai_Shield
|
||||
- Item: S_Kunai_Armor
|
||||
- Group: S_HUUSOUKA_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Huusouka_Earing
|
||||
- Item: S_Huusouka_Pendant
|
||||
- Item: S_Huusouka_Shoes
|
||||
- Group: S_KAMAENRAKU_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Kamaenraku_Weapon
|
||||
- Item: S_Kamaenraku_Shield
|
||||
- Item: S_Kamaenraku_Armor
|
||||
- Group: S_GOD_HAMMER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_God_Hammer_Weapon
|
||||
- Item: S_God_Hammer_Shield
|
||||
- Item: S_God_Hammer_Armor
|
||||
- Group: S_SHATTER_BUSTER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Shatter_Buster_Earing
|
||||
- Item: S_Shatter_B_Pendant
|
||||
- Item: S_Shatter_Buster_Shoes
|
||||
- Group: S_TAIL_DRAGON_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Tail_Dragon_Weapon
|
||||
- Item: S_Tail_Dragon_Shield
|
||||
- Item: S_Tail_Dragon_Armor
|
||||
- Group: S_TRIP_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Trip_Weapon
|
||||
- Item: S_Trip_Shield
|
||||
- Item: S_Trip_Armor
|
||||
- Group: S_FLARE_DANCE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Flare_Dance_Earing
|
||||
- Item: S_Flare_Dance_Pendant
|
||||
- Item: S_Flare_Dance_Shoes
|
||||
- Group: S_SUPER_MAGIC_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Super_Magic_Shield
|
||||
- Item: S_Super_Magic_Armor
|
||||
- Item: S_Super_Magic_Shoes
|
||||
- Group: S_SUPER_POWER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Super_Power_Weapon
|
||||
- Item: S_Super_Power_Pendant
|
||||
- Item: S_Super_Power_Earing
|
||||
- Group: S_SILVERVINE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Silvervine_Earing
|
||||
- Item: S_Silvervine_Pendant
|
||||
- Item: S_Silvervine_Shoes
|
||||
- Group: S_CATNIP_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Catnip_Weapon
|
||||
- Item: S_Catnip_Shield
|
||||
- Item: S_Catnip_Armor
|
||||
- Group: S_SAVAGERABBIT_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_SavageRabbit_Earing
|
||||
- Item: S_SavageRabbit_Pendant
|
||||
- Item: S_SavageRabbit_Shoes
|
||||
- Group: S_PICKYRUSH_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Pickyrush_Weapon
|
||||
- Item: S_Pickyrush_Shield
|
||||
- Item: S_Pickyrush_Armor
|
||||
- Group: S_RUNEKNIGHT_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Swordman_earring
|
||||
- Item: S_Swordman_Pendant
|
||||
- Item: S_Knight_Shoes
|
||||
- Item: S_Knight_Armor
|
||||
- Item: S_Runeknight_Weapon
|
||||
- Item: S_Runeknight_Shield
|
||||
- Group: S_ROYALGUARD_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Swordman_earring
|
||||
- Item: S_Swordman_Pendant
|
||||
- Item: S_Crusader_Shoes
|
||||
- Item: S_Crusader_Armor
|
||||
- Item: S_Royalguard_Weapon
|
||||
- Item: S_Royalguard_Shield
|
||||
- Group: S_WARLOCK_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Magician_earring
|
||||
- Item: S_Magician_Pendant
|
||||
- Item: S_Wizard_Shoes
|
||||
- Item: S_Wizard_Armor
|
||||
- Item: S_Warlock_Weapon
|
||||
- Item: S_Warlock_Shield
|
||||
- Group: S_SORCERER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Magician_earring
|
||||
- Item: S_Magician_Pendant
|
||||
- Item: S_Sage_Shoes
|
||||
- Item: S_Sage_Armor
|
||||
- Item: S_Sorcerer_Weapon
|
||||
- Item: S_Sorcerer_Shield
|
||||
- Group: S_MECHANIC_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Merchant_earring
|
||||
- Item: S_Merchant_Pendant
|
||||
- Item: S_Blacksmith_Shoes
|
||||
- Item: S_Blacksmith_Armor
|
||||
- Item: S_Mechanic_weapon
|
||||
- Item: S_Mechanic_Shield
|
||||
- Group: S_GENERIC_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Merchant_earring
|
||||
- Item: S_Merchant_Pendant
|
||||
- Item: S_Alchemist_Shoes
|
||||
- Item: S_Alchemist_Armor
|
||||
- Item: S_Genetic_Weapon
|
||||
- Item: S_Genetic_Shield
|
||||
- Group: S_ARCHBISHOP_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Acolyte_earring
|
||||
- Item: S_Acolyte_Pendant
|
||||
- Item: S_Priest_Shoes
|
||||
- Item: S_Priest_Armor
|
||||
- Item: S_Archbishop_Weapon
|
||||
- Item: S_Archbishop_Shield
|
||||
- Group: S_SURA_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Acolyte_earring
|
||||
- Item: S_Acolyte_Pendant
|
||||
- Item: S_Monk_Shoes
|
||||
- Item: S_Monk_Armor
|
||||
- Item: S_Sura_weapon
|
||||
- Item: S_Sura_Shield
|
||||
- Group: S_GUILLOTINECROSS_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Thief_Pendant
|
||||
- Item: S_Assassin_Shoes
|
||||
- Item: S_Assassin_Armor
|
||||
- Item: S_Guillotine_Weapon
|
||||
- Item: S_Guillotine_Shield
|
||||
- Item: S_Thief_earring
|
||||
- Group: S_SHADOWCHASER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Thief_Pendant
|
||||
- Item: S_Rogue_Shoes
|
||||
- Item: S_Rogue_Armor
|
||||
- Item: S_Shadowchaser_Weapon
|
||||
- Item: S_Shadowchaser_Shield
|
||||
- Item: S_Thief_earring
|
||||
- Group: S_RANGER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Archer_Pendant
|
||||
- Item: S_Hunter_Shoes
|
||||
- Item: S_Hunter_Armor
|
||||
- Item: S_Ranger_Weapon
|
||||
- Item: S_Ranger_Shield
|
||||
- Item: S_Archer_earring
|
||||
- Group: S_WANDERER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Archer_Pendant
|
||||
- Item: S_Dancer_Shoes
|
||||
- Item: S_Dancer_Armor
|
||||
- Item: S_Wanderer_Weapon
|
||||
- Item: S_Wanderer_Shield
|
||||
- Item: S_Archer_earring
|
||||
- Group: S_MINSTREL_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Archer_Pendant
|
||||
- Item: S_Bard_Shoes
|
||||
- Item: S_Bard_Armor
|
||||
- Item: S_Minstrel_Weapon
|
||||
- Item: S_Minstrel_Shield
|
||||
- Item: S_Archer_earring
|
||||
- Group: S_STAR_EMPEROR_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Taekwon_Weapon
|
||||
- Item: S_Taekwon_Shield
|
||||
- Item: S_Star_Emperor_Armor
|
||||
- Item: S_Star_Emperor_Shoes
|
||||
- Group: S_SOUL_REAPER_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Taekwon_Weapon
|
||||
- Item: S_Taekwon_Shield
|
||||
- Item: S_Soul_Reaper_Armor
|
||||
- Item: S_Soul_Reaper_Shoes
|
||||
- Group: S_KAGEROU_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Ninja_Weapon
|
||||
- Item: S_Ninja_Shield
|
||||
- Item: S_Kagerou_Armor
|
||||
- Item: S_Kagerou_Shoes
|
||||
- Group: S_OBORO_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Ninja_Weapon
|
||||
- Item: S_Ninja_Shield
|
||||
- Item: S_Oboro_Armor
|
||||
- Item: S_Oboro_Shoes
|
||||
- Group: S_REBELLION_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Gunslinger_Weapon
|
||||
- Item: S_Gunslinger_Shield
|
||||
- Item: S_Rebellion_Armor
|
||||
- Item: S_Rebellion_Shoes
|
||||
- Group: S_SUPERNOVICE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_SuperNovice_Weapon
|
||||
- Item: S_SuperNovice_Shield
|
||||
- Group: S_DORAM_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_DoramMagical_Weapon
|
||||
- Item: S_DoramPhysical_Weapon
|
||||
- Item: S_DoramPhysical_Shield
|
||||
- Item: S_DoramMagical_Shield
|
||||
- Item: S_DoramPhysical_Armor
|
||||
- Item: S_DoramPhysical_Shoes
|
||||
- Item: S_DoramMagical_Armor
|
||||
- Item: S_DoramMagical_Shoes
|
||||
- Group: S_MAMMOTH_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Mammoth_Armor
|
||||
- Item: S_Mammoth_Shoes
|
||||
- Item: S_Mammoth_Pendant
|
||||
- Item: S_Mammoth_Earring
|
||||
- Item: S_Mammoth_Weapon
|
||||
- Item: S_Mammoth_Shield
|
||||
- Group: S_GEMSTONE_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Gemstone_Armor
|
||||
- Item: S_Gemstone_Shoes
|
||||
- Item: S_Gemstone_Shield
|
||||
- Item: S_Gemstone_Weapon
|
||||
- Item: S_Gemstone_Earring
|
||||
- Item: S_Gemstone_Pendent
|
||||
- Group: S_PENE1_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Penetration_Earring
|
||||
- Item: S_Penetration_Pendent
|
||||
- Item: S_Exe_Ho_Weapon
|
||||
- Item: S_Fis_In_Weapon
|
||||
- Item: S_Sci_Hu_Weapon
|
||||
- Item: S_Viv_Dr_Weapon
|
||||
- Item: S_Exo_Co_Weapon
|
||||
- Group: S_PENE2_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Penetration_Shoes
|
||||
- Item: S_Penetration_Shield
|
||||
- Item: S_ExeHoly_Armor
|
||||
- Item: S_ExoCorrupt_Armor
|
||||
- Item: S_DragonVib_Armor
|
||||
- Item: S_SciHunting_Armor
|
||||
- Item: S_FishInsect_Armor
|
||||
- Group: S_TEMP1_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Tempest_Earring
|
||||
- Item: S_Tempest_Pendent
|
||||
- Item: S_M_Exo_Co_Weapon
|
||||
- Item: S_M_Viv_Dr_Weapon
|
||||
- Item: S_M_Sci_Hu_Weapon
|
||||
- Item: S_M_Fis_In_Weapon
|
||||
- Item: S_M_Exe_Ho_Weapon
|
||||
- Group: S_TEMP2_CUBE
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: S_Tempest_Shield
|
||||
- Item: S_Tempest_Shoes
|
||||
- Item: S_M_ExeHoly_Armor
|
||||
- Item: S_M_ExoCorrupt_Armor
|
||||
- Item: S_M_DragonVib_Armor
|
||||
- Item: S_M_SciHunting_Armor
|
||||
- Item: S_M_FishInsect_Armor
|
||||
- Group: BLACKSMITH_BLESS_BOX_3
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Blacksmith_Blessing
|
||||
Amount: 3
|
||||
- Group: SHADOW_HAMMER_BOX_3
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Shadow_Refine_Hammer
|
||||
Amount: 3
|
||||
- Group: EDP
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Poison_Bottle
|
||||
- Item: Poison_Bottle_B
|
||||
- Group: MF_NOTELEPORT
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Wing_Of_Fly
|
||||
- Item: Giant_Fly_Wing
|
||||
- Item: N_Fly_Wing
|
||||
- Item: E_Giant_Fly_Wing
|
||||
- Item: F_Giant_Fly_Wing
|
||||
- Item: C_Wing_Of_Fly
|
||||
- Item: N_Fly_Wing_
|
||||
- Item: Compressed_Wing_Of_Fly
|
||||
- Item: Comp_Wing_Of_Fly
|
||||
- Group: MF_NORETURN
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Wing_Of_Butterfly
|
||||
- Item: N_Butterfly_Wing
|
||||
- Item: Dun_Tele_Scroll1
|
||||
- Item: Dun_Tele_Scroll2
|
||||
- Item: Dun_Tele_Scroll3
|
||||
- Item: E_Dun_Tele_Scroll1
|
||||
- Item: F_Dun_Tele_Scroll1
|
||||
- Item: WOB_Rune
|
||||
- Item: E_WOB_Rune
|
||||
- Item: F_WOB_Rune
|
||||
- Item: WOB_Schwaltz
|
||||
- Item: E_WOB_Schwaltz
|
||||
- Item: F_WOB_Schwaltz
|
||||
- Item: WOB_Rachel
|
||||
- Item: E_WOB_Rachel
|
||||
- Item: F_WOB_Rachel
|
||||
- Item: WOB_Local
|
||||
- Item: E_WOB_Local
|
||||
- Item: F_WOB_Local
|
||||
- Item: Siege_Teleport_Scroll
|
||||
- Item: Siege_Teleport_Scroll2
|
||||
- Item: E_Siege_Teleport_Scroll
|
||||
- Group: GIANT_FLY_WING
|
||||
SubGroups:
|
||||
- SubGroup: 0
|
||||
List:
|
||||
- Item: Giant_Fly_Wing
|
||||
- Item: E_Giant_Fly_Wing
|
||||
- Item: F_Giant_Fly_Wing
|
||||
|
||||
@@ -6892,3 +6892,91 @@ Body:
|
||||
# Amount: 150
|
||||
# ResultItem: Blessed_Knife_LT
|
||||
# ChangeRefine: 1
|
||||
- Item: Dimmen_A_Reform
|
||||
BaseItems:
|
||||
- BaseItem: Under_Seal_D_Key
|
||||
MaximumRefine: 0
|
||||
CardsAllowed: false
|
||||
Materials:
|
||||
- Material: Dimmension_Jewel
|
||||
Amount: 1
|
||||
- Material: Dimmension_Jewelry
|
||||
Amount: 1
|
||||
- Material: Herosria_Jewel
|
||||
Amount: 1
|
||||
- Material: Creed_Of_Herosria
|
||||
Amount: 1
|
||||
ResultItem: Dimmension_W_Key
|
||||
- BaseItem: Under_Seal_D_Padlock
|
||||
MaximumRefine: 0
|
||||
CardsAllowed: false
|
||||
Materials:
|
||||
- Material: Dimmension_Jewel
|
||||
Amount: 1
|
||||
- Material: Dimmension_Jewelry
|
||||
Amount: 1
|
||||
- Material: Herosria_Jewel
|
||||
Amount: 1
|
||||
- Material: Justice_Of_Herosria
|
||||
Amount: 1
|
||||
ResultItem: Dimmension_W_Padlock
|
||||
- BaseItem: Under_Seal_D_keyring
|
||||
MaximumRefine: 0
|
||||
CardsAllowed: false
|
||||
Materials:
|
||||
- Material: Dimmension_Jewel
|
||||
Amount: 1
|
||||
- Material: Dimmension_Jewelry
|
||||
Amount: 1
|
||||
- Material: Herosria_Jewel
|
||||
Amount: 1
|
||||
- Material: Glory_Of_Herosria
|
||||
Amount: 1
|
||||
ResultItem: Dimmension_W_Keyring
|
||||
- Item: Dimmen_A_Refine
|
||||
BaseItems:
|
||||
- BaseItem: Dimmension_W_Key
|
||||
MinimumRefine: 9
|
||||
MaximumRefine: 11
|
||||
CardsAllowed: false
|
||||
Materials:
|
||||
- Material: Heros_Gold_Bar
|
||||
Amount: 50
|
||||
- Material: Heros_Silver_Bar
|
||||
Amount: 100
|
||||
- Material: Heros_Copper_Bar
|
||||
Amount: 200
|
||||
- Material: Heros_Iron_Bar
|
||||
Amount: 300
|
||||
ResultItem: Dimmension_W_Key
|
||||
ChangeRefine: 1
|
||||
- BaseItem: Dimmension_W_Padlock
|
||||
MinimumRefine: 9
|
||||
MaximumRefine: 11
|
||||
CardsAllowed: false
|
||||
Materials:
|
||||
- Material: Heros_Gold_Bar
|
||||
Amount: 50
|
||||
- Material: Heros_Silver_Bar
|
||||
Amount: 100
|
||||
- Material: Heros_Copper_Bar
|
||||
Amount: 200
|
||||
- Material: Heros_Iron_Bar
|
||||
Amount: 300
|
||||
ResultItem: Dimmension_W_Padlock
|
||||
ChangeRefine: 1
|
||||
- BaseItem: Dimmension_W_Keyring
|
||||
MinimumRefine: 9
|
||||
MaximumRefine: 11
|
||||
CardsAllowed: false
|
||||
Materials:
|
||||
- Material: Heros_Gold_Bar
|
||||
Amount: 50
|
||||
- Material: Heros_Silver_Bar
|
||||
Amount: 100
|
||||
- Material: Heros_Copper_Bar
|
||||
Amount: 200
|
||||
- Material: Heros_Iron_Bar
|
||||
Amount: 300
|
||||
ResultItem: Dimmension_W_Keyring
|
||||
ChangeRefine: 1
|
||||
|
||||
@@ -1387,7 +1387,7 @@ Body:
|
||||
Amount: 10
|
||||
- Item: Frozen_Stone_Fragment
|
||||
Amount: 10
|
||||
- Item: Spirit_Jewel
|
||||
- Item: SpritJewel
|
||||
Amount: 10
|
||||
- Item: Snowball
|
||||
Amount: 10
|
||||
@@ -1419,7 +1419,7 @@ Body:
|
||||
Amount: 10
|
||||
- Item: Fine_Old_Doll
|
||||
Amount: 10
|
||||
- Item: Old_Shell
|
||||
- Item: OldShell
|
||||
Amount: 10
|
||||
- Item: Ein_SOLIDDUST
|
||||
Amount: 10
|
||||
@@ -1602,7 +1602,7 @@ Body:
|
||||
- Item: C_Charleston_Antenna
|
||||
- Item: C_Wings_of_Uriel
|
||||
- Item: C_Pig_Nose
|
||||
- Item: C_Cat_Ears_Hat
|
||||
- Item: C_Cat_Ear_Hat
|
||||
- Item: C_Valkyrie_Circlet
|
||||
- Item: C_Eremes_Scarf_Black
|
||||
- Item: C_Eleanor_Wig
|
||||
@@ -1738,13 +1738,13 @@ Body:
|
||||
- Item: C_Big_Foxtail
|
||||
- Item: C_T_Bear_Bag
|
||||
- Item: C_Poring_On_Shoulder
|
||||
- Item: Costume_Yawata_Seal
|
||||
- Item: C_FortunetellinSealed
|
||||
- Item: C_Pretty_Bear_WH
|
||||
- Item: C_Bicolor_Cat_Witch_Hat
|
||||
- Item: C_Nifl_Bloom
|
||||
- Item: C_Floating_Ball_TW
|
||||
- Item: C_Dark_Snake_Lord_Stall
|
||||
- Item: Costume_Twin_Cannon
|
||||
- Item: C_Twin_Canon
|
||||
- Item: C_Picnic_Basket
|
||||
- Item: C_Magic_Helm
|
||||
- Item: C_ManyStars_TW
|
||||
@@ -1773,13 +1773,13 @@ Body:
|
||||
- Item: C_Disapear_Time_TW
|
||||
- Item: C_Magic_Heir_TW
|
||||
- Item: C_Blink_Eyes_Sakura
|
||||
- Item: Costume_Angola_Intention
|
||||
- Item: C_Stole_Of_Dominion
|
||||
- Item: C_Angola_Intention
|
||||
- Item: C_Stall_Of_Dominions
|
||||
- Item: C_Flowery_Vision_TH
|
||||
- Item: C_Frill_Collar
|
||||
- Item: C_Rose_Gothic_Bonnet
|
||||
- Item: C_LittleGarden
|
||||
- Item: Costume_Twinkling_Red_Eyes
|
||||
- Item: C_Blinking_Eyes_RD
|
||||
- Item: C_P_Ulysses_Feather
|
||||
- Item: C_DancingButterfly_TW
|
||||
- Item: C_Blue_Pencil_In_Mouth
|
||||
@@ -1790,7 +1790,7 @@ Body:
|
||||
- Item: C_Frog_Hood
|
||||
- Item: C_Lude_Hood
|
||||
- Item: C_Blessings_Of_Soul
|
||||
- Item: C_Crow
|
||||
- Item: C_Gossip_Raven
|
||||
- Item: C_Halloween_Hat
|
||||
- Item: C_Blessed_Veil
|
||||
- Item: C_Eyes_Of_Ifrit
|
||||
@@ -1799,7 +1799,7 @@ Body:
|
||||
- Item: C_Wildcat_Knit_Cap
|
||||
- Item: C_Pink_Fur_Hat
|
||||
- Item: C_Gift_Of_Snow
|
||||
- Item: C_Large_Ribbon_Muffler_Red
|
||||
- Item: C_L_RibbonMuff_Red
|
||||
- Item: C_Imperial_Glory
|
||||
- Item: C_Black_Shiba_Inu_Hat
|
||||
- Item: C_Black_Glasses
|
||||
@@ -3272,11 +3272,11 @@ Body:
|
||||
# RewardGroup: ENCHANTSTONE_RECIPE_3M
|
||||
# Requirements:
|
||||
# - Item: C_Pretty_Bear_WH
|
||||
# - Item: Costume_Yawata_Seal
|
||||
# - Item: C_FortunetellinSealed
|
||||
# - Item: C_Floating_Ball_TW
|
||||
# - Item: C_Dark_Snake_Lord_Stall
|
||||
# - Item: C_Bicolor_Cat_Witch_Hat
|
||||
# - Item: Costume_Twin_Cannon
|
||||
# - Item: C_Twin_Canon
|
||||
# - Item: C_Picnic_Basket
|
||||
# - Item: C_Magic_Helm
|
||||
# - Item: C_Fawn_Ear
|
||||
@@ -3291,7 +3291,7 @@ Body:
|
||||
# - Item: C_Frill_Collar
|
||||
# - Item: C_Rose_Gothic_Bonnet
|
||||
# - Item: C_LittleGarden
|
||||
# - Item: Costume_Twinkling_Red_Eyes
|
||||
# - Item: C_Blinking_Eyes_RD
|
||||
# - Item: Egirnion_Box
|
||||
# RewardGroup: EGIRNION_BOX
|
||||
# Requirements:
|
||||
@@ -3700,11 +3700,11 @@ Body:
|
||||
# - Item: S_AllMighty_Pendant
|
||||
# - Item: S_Tempest_Shield
|
||||
# - Item: S_Tempest_Shoes
|
||||
# - Item: S_Magic_Executioner_Holy_Water_Armor
|
||||
# - Item: S_Magic_Exorcist_Corrupted_Armor
|
||||
# - Item: S_Magic_Vibration_Dragon_Killer_Armor
|
||||
# - Item: S_Magic_Scissor_Hunting_Armor
|
||||
# - Item: S_Magic_Fishing_Insect_Net_Armor
|
||||
# - Item: S_M_ExeHoly_Armor
|
||||
# - Item: S_M_ExoCorrupt_Armor
|
||||
# - Item: S_M_DragonVib_Armor
|
||||
# - Item: S_M_SciHunting_Armor
|
||||
# - Item: S_M_FishInsect_Armor
|
||||
# - Item: S_Plasterer's_Armor_II
|
||||
# - Item: S_Insomniac_Shoes_II
|
||||
# - Item: S_Peerless_Armor_II
|
||||
@@ -3728,11 +3728,11 @@ Body:
|
||||
# - Item: S_Mortal_Blow_Pendant
|
||||
# - Item: S_Penetration_Shoes
|
||||
# - Item: S_Penetration_Shield
|
||||
# - Item: S_Executioner_Holy_Water_Armor
|
||||
# - Item: S_Exorcist_Corrupted_Armor
|
||||
# - Item: S_Vibration_Dragon_Killer_Armor
|
||||
# - Item: S_Scissor_Hunting_Armor
|
||||
# - Item: S_Fishing_Insect_Net_Armor
|
||||
# - Item: S_ExeHoly_Armor
|
||||
# - Item: S_ExoCorrupt_Armor
|
||||
# - Item: S_DragonVib_Armor
|
||||
# - Item: S_SciHunting_Armor
|
||||
# - Item: S_FishInsect_Armor
|
||||
# - Item: Sentimental_Weapone_S
|
||||
# - Item: Sentimental_Earring_S
|
||||
# - Item: Sentimental_Pendant_S
|
||||
|
||||
@@ -60,7 +60,7 @@ Body:
|
||||
# - Item: Ein_1HSWORD
|
||||
# - Item: Ein_1HGUN
|
||||
# - Item: Ein_1H_Foxtail
|
||||
- Item: Metal_Smelting_Ticket
|
||||
- Item: Metal_Rifine_Ticket
|
||||
ResultRefine: 7
|
||||
CardsAllowed: true
|
||||
TargetItems:
|
||||
@@ -74,7 +74,7 @@ Body:
|
||||
- Item: Metal_Bow
|
||||
- Item: Metal_Two_Hand_Sword
|
||||
- Item: Metal_Revolver
|
||||
- Item: Huuma_Metal_Shuriken
|
||||
- Item: Metal_Huuma_Shuriken
|
||||
- Item: Metal_Foxtail
|
||||
# - Item: Ein_Ddbox2
|
||||
# TargetItems:
|
||||
@@ -2657,21 +2657,21 @@ Body:
|
||||
TargetItems:
|
||||
- Item: Boost_TH_Sword
|
||||
- Item: Boost_Katar
|
||||
- Item: Boost_Mace
|
||||
- Item: Boost_Hall
|
||||
- Item: Boost_Staff
|
||||
- Item: Boost_Bow
|
||||
- Item: Boost_Spear
|
||||
- Item: Boost_Sword
|
||||
- Item: Boost_Dagger
|
||||
- Item: Boost_Spellbook
|
||||
- Item: Boost_Spl_Book
|
||||
- Item: Boost_Guitar
|
||||
- Item: Boost_Knuckles
|
||||
- Item: Boost_Knuckle
|
||||
- Item: Boost_Whip
|
||||
- Item: Boost_Nindo
|
||||
- Item: Boost_Gatling
|
||||
- Item: Boost_Axe
|
||||
- Item: Boost_Book
|
||||
- Item: Boost_Rod
|
||||
- Item: Boost_Text
|
||||
- Item: Boost_Soul_Rod
|
||||
- Item: Boost_Foxtail
|
||||
- Item: Metal_7_Ticket
|
||||
ResultRefine: 7
|
||||
@@ -2689,7 +2689,7 @@ Body:
|
||||
- Item: Metal_Bow
|
||||
- Item: Metal_Foxtail
|
||||
- Item: Metal_Revolver
|
||||
- Item: Huuma_Metal_Shuriken
|
||||
- Item: Metal_Huuma_Shuriken
|
||||
- Item: Noblesse_Rifine_Ticket
|
||||
ResultRefine: 9
|
||||
CardsAllowed: true
|
||||
|
||||
1077
db/re/mob_db.yml
1077
db/re/mob_db.yml
File diff suppressed because it is too large
Load Diff
@@ -13041,6 +13041,69 @@
|
||||
20837,ABR_INFINITY@ABR_INFINITY_BUSTER,chase,8605,1,10000,500,5000,yes,target,always,0,,,,,,,
|
||||
20837,ABR_INFINITY@ABR_INFINITY_BUSTER,attack,8605,1,10000,500,5000,yes,target,always,0,,,,,,,
|
||||
|
||||
// sp_rudus4
|
||||
20929,GIANT_CAPUT@NPC_EMOTION,chase,197,1,1000,0,30000,yes,self,always,0,,,,,,19,
|
||||
20929,GIANT_CAPUT@NPC_EMOTION,idle,197,1,8000,0,30000,yes,self,always,0,,,,,,44,
|
||||
20929,GIANT_CAPUT@NPC_COMBOATTACK,attack,171,2,1000,500,15000,no,target,always,0,,,,,,,
|
||||
20929,GIANT_CAPUT@LK_SPIRALPIERCE,chase,397,3,3000,500,30000,no,target,always,0,,,,,,,
|
||||
20929,GIANT_CAPUT@NPC_DARKNESSATTACK,chase,190,3,5000,500,10000,no,target,always,0,,,,,,,
|
||||
20929,GIANT_CAPUT@NPC_DARKNESSATTACK,attack,190,3,5000,500,10000,no,target,always,0,,,,,,,
|
||||
20929,GIANT_CAPUT@NPC_HELMBRAKE,attack,345,5,3000,0,30000,yes,target,always,0,,,,,,,
|
||||
20929,GIANT_CAPUT@NPC_PULSESTRIKE,attack,661,3,2000,1000,60000,no,self,always,0,,,,,,,
|
||||
20929,GIANT_CAPUT@NPC_POWERUP,attack,349,3,5000,0,60000,yes,self,myhpltmaxrate,30,,,,,,,
|
||||
20929,GIANT_CAPUT@NPC_POWERUP,chase,349,3,5000,0,60000,yes,self,myhpltmaxrate,30,,,,,,,
|
||||
20930,DOLORIAN@AL_TELEPORT,chase,26,1,3000,0,300000,yes,self,mobnearbygt,23,,,,,,12,
|
||||
20930,DOLORIAN@NPC_EMOTION,chase,197,1,500,0,30000,yes,self,always,0,,,,,,19,
|
||||
20930,DOLORIAN@NPC_CRITICALWOUND,attack,673,1,2000,0,60000,yes,target,always,0,,,,,,,
|
||||
20930,DOLORIAN@NPC_EMOTION,idle,197,1,2000,0,30000,yes,self,always,0,,,,,,44,
|
||||
20930,DOLORIAN@NPC_BLOODDRAIN,chase,199,1,3000,0,30000,yes,target,always,0,,,,,,,
|
||||
20930,DOLORIAN@NPC_STONESKIN,chase,675,3,3000,500,30000,no,self,myhpltmaxrate,30,,,,,,47,
|
||||
20930,DOLORIAN@NPC_POISONATTACK,attack,188,3,2000,500,10000,no,target,always,0,,,,,,,
|
||||
20931,PLAGARION@AL_TELEPORT,chase,26,1,3000,0,300000,yes,self,mobnearbygt,23,,,,,,12,
|
||||
20931,PLAGARION@NPC_EMOTION,chase,197,1,500,0,30000,yes,self,always,0,,,,,,19,
|
||||
20931,PLAGARION@NPC_EMOTION,idle,197,1,2000,0,30000,yes,self,always,0,,,,,,44,
|
||||
20931,PLAGARION@NPC_CRITICALWOUND,attack,673,3,2000,0,60000,yes,target,always,0,,,,,,,
|
||||
20931,PLAGARION@MG_FIREBALL,chase,17,3,3000,500,30000,no,target,always,0,,,,,,,
|
||||
20931,PLAGARION@NPC_FIREATTACK,chase,186,2,2000,500,30000,no,target,always,0,,,,,,,
|
||||
20931,PLAGARION@NPC_DARKSTRIKE,chase,340,5,3000,500,30000,no,target,always,0,,,,,,,
|
||||
20932,DEADRE@AL_TELEPORT,chase,26,1,3000,0,300000,yes,self,mobnearbygt,23,,,,,,12,
|
||||
20932,DEADRE@NPC_EMOTION,chase,197,1,500,0,30000,yes,self,always,0,,,,,,19,
|
||||
20932,DEADRE@AL_HEAL,idle,28,9,7000,500,5000,no,friend,myhpltmaxrate,50,,,,,,3,
|
||||
20932,DEADRE@NPC_EMOTION,idle,197,1,2000,0,30000,yes,self,always,0,,,,,,14,
|
||||
20932,DEADRE@AL_HEAL,attack,28,9,3000,500,15000,no,friend,always,0,,,,,,3,
|
||||
20932,DEADRE@NPC_DARKCROSS,attack,338,5,3000,500,15000,no,target,always,0,,,,,,,
|
||||
20932,DEADRE@AL_HOLYLIGHT,chase,156,1,3000,300,15000,no,target,always,0,,,,,,,
|
||||
20932,DEADRE@NPC_HOLYATTACK,chase,189,3,4000,500,15000,no,target,always,0,,,,,,,
|
||||
20932,DEADRE@AL_HEAL,idle,28,9,10000,700,3000,no,friend,friendhpltmaxrate,50,,,,,,,
|
||||
20933,VENEDI@NPC_EMOTION,chase,197,1,500,0,30000,yes,self,always,0,,,,,,19,
|
||||
20933,VENEDI@NPC_EMOTION,idle,197,1,2000,0,30000,yes,self,always,0,,,,,,44,
|
||||
20933,VENEDI@NPC_BLINDATTACK,chase,177,3,3000,500,30000,no,target,always,0,,,,,,,
|
||||
20933,VENEDI@NPC_POISONATTACK,attack,188,5,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
20933,VENEDI@NPC_POISON_BUSTER,attack,742,1,2000,1500,30000,no,self,always,0,,,,,,,
|
||||
20933,VENEDI@NPC_CLOUD_KILL,attack,739,3,2000,500,15000,no,target,always,0,,,,,,,
|
||||
20934,R001_BESTIA@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,0,,,,,,,
|
||||
20934,R001_BESTIA@WZ_METEOR,idle,83,9,10000,0,5000,no,target,longrangeattacked,0,,,,,,,
|
||||
20934,R001_BESTIA@AL_PNEUMA,idle,25,1,10000,0,1000,no,self,longrangeattacked,0,,,,,,,
|
||||
20934,R001_BESTIA@AL_HEAL,idle,28,11,10000,0,3000,no,friend,myhpltmaxrate,50,,,,,,,
|
||||
20934,R001_BESTIA@AL_HEAL,idle,28,5,10000,0,3000,no,friend,myhpltmaxrate,99,,,,,,,
|
||||
20934,R001_BESTIA@NPC_SUMMONSLAVE,idle,196,1,10000,1000,30000,no,self,slavele,1,,,,,,,
|
||||
20934,R001_BESTIA@NPC_CALLSLAVE,idle,352,1,10000,0,30000,no,self,always,0,,,,,,,
|
||||
20934,R001_BESTIA@NPC_FIREBREATH,chase,654,10,2000,500,5000,no,target,myhpltmaxrate,80,,,,,,,
|
||||
// 20934,R001_BESTIA@NPC_EARTHQUAKE_K,chase,750,5,10000,500,20000,no,target,myhpltmaxrate,40,,,,,,,
|
||||
20934,R001_BESTIA@NPC_EARTHQUAKE,chase,653,5,10000,500,20000,no,target,myhpltmaxrate,40,,,,,,,
|
||||
20934,R001_BESTIA@NPC_CALLSLAVE,attack,352,1,10000,0,30000,no,self,always,0,,,,,,,
|
||||
20934,R001_BESTIA@NPC_SUMMONSLAVE,attack,196,1,10000,700,10000,no,self,slavele,2,,,,,,,
|
||||
20934,R001_BESTIA@ST_FULLSTRIP,attack,476,5,2000,0,5000,no,target,always,0,,,,,,,
|
||||
20934,R001_BESTIA@NPC_CRITICALWOUND,attack,673,3,2000,0,30000,no,target,always,0,,,,,,,
|
||||
20934,R001_BESTIA@NPC_FIREBREATH,attack,654,10,2000,500,5000,no,target,myhpltmaxrate,80,,,,,,,
|
||||
20934,R001_BESTIA@WZ_METEOR,attack,83,11,2000,500,5000,no,target,myhpltmaxrate,90,,,,,,,
|
||||
20934,R001_BESTIA@KN_TWOHANDQUICKEN,attack,60,9,10000,0,100000,no,self,myhpltmaxrate,30,,,,,,,
|
||||
// 20934,R001_BESTIA@NPC_EARTHQUAKE_K,attack,750,5,10000,500,20000,no,target,myhpltmaxrate,40,,,,,,,
|
||||
20934,R001_BESTIA@NPC_EARTHQUAKE,attack,653,5,10000,500,20000,no,target,myhpltmaxrate,40,,,,,,,
|
||||
20934,R001_BESTIA@NPC_PULSESTRIKE,attack,661,5,10000,0,15000,no,self,myhpltmaxrate,60,,,,,,,
|
||||
20934,R001_BESTIA@NPC_DRAGONFEAR,attack,659,5,10000,0,10000,no,self,always,0,,,,,,,
|
||||
// 20934,R001_BESTIA@NPC_DAMAGE_HEAL,attack,753,1,3000,1500,40000,no,target,myhpltmaxrate,20,,,,,,,
|
||||
|
||||
// Training Ground outside Prontera
|
||||
21064,S_DUMMY_100_SMALL@NPC_ALLHEAL,attack,687,1,10000,0,500,no,self,myhpltmaxrate,90,,,,,,,
|
||||
21064,S_DUMMY_100_SMALL@NPC_ALLHEAL,idle,687,1,10000,0,500,no,self,myhpltmaxrate,90,,,,,,,
|
||||
|
||||
@@ -10420,15 +10420,37 @@ Body:
|
||||
- Id: 16439
|
||||
Title: Award Garden-Waiting
|
||||
TimeLimit: 4h
|
||||
- Id: 16521
|
||||
Title: 4th floor of Rudus, an organic field for waste specimens
|
||||
- Id: 16522
|
||||
Title: 4th floor of Rudus, an organic field for waste specimens
|
||||
- Id: 16523
|
||||
Title: The solitude of the abyss
|
||||
Title: Abyssal Solitude - Standby
|
||||
TimeLimit: 4h
|
||||
- Id: 16524
|
||||
Title: Abyssal Solitude
|
||||
Targets:
|
||||
- Mob: DEADRE
|
||||
Count: 10
|
||||
- Mob: DOLORIAN
|
||||
Count: 10
|
||||
- Mob: PLAGARION
|
||||
Count: 10
|
||||
- Id: 16525
|
||||
Title: Transformation and development - Standby
|
||||
Title: Transformation and Evolution - Standby
|
||||
TimeLimit: 4h
|
||||
- Id: 16526
|
||||
Title: Transformation and Evolution
|
||||
Targets:
|
||||
- Mob: GIANT_CAPUT
|
||||
Count: 15
|
||||
- Mob: VENEDI
|
||||
Count: 15
|
||||
- Id: 16527
|
||||
Title: Data backup - Waiting
|
||||
TimeLimit: 4h
|
||||
- Id: 16528
|
||||
Title: Data Backup
|
||||
- Id: 16530
|
||||
Title: The ground and fire
|
||||
TimeLimit: 4h
|
||||
@@ -10444,6 +10466,8 @@ Body:
|
||||
- Id: 16538
|
||||
Title: Natural change - Waiting
|
||||
TimeLimit: 4h
|
||||
- Id: 16540
|
||||
Title: Data Backup
|
||||
- Id: 16546
|
||||
Title: Farm Worker
|
||||
- Id: 16547
|
||||
|
||||
@@ -10516,9 +10516,6 @@ Body:
|
||||
Amount: 90
|
||||
- Level: 5
|
||||
Amount: 100
|
||||
ItemCost:
|
||||
- Item: Poison_Bottle
|
||||
Amount: 1
|
||||
Status: Edp
|
||||
- Id: 379
|
||||
Name: ASC_BREAKER
|
||||
|
||||
168
db/re/status.yml
168
db/re/status.yml
@@ -254,6 +254,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
SpreadEffect: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Refresh: true
|
||||
Inspiration: true
|
||||
@@ -282,6 +283,7 @@ Body:
|
||||
BossResist: true
|
||||
Debuff: true
|
||||
NoSaveInfinite: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Freeze: true
|
||||
Stone: true
|
||||
@@ -307,6 +309,7 @@ Body:
|
||||
Quicken: true
|
||||
Flags:
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Decreaseagi: true
|
||||
- Status: Concentrate
|
||||
@@ -317,6 +320,7 @@ Body:
|
||||
Dex: true
|
||||
Flags:
|
||||
FailedMado: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
- Status: Hiding
|
||||
@@ -335,11 +339,10 @@ Body:
|
||||
OnTouch: true
|
||||
StopAttacking: true
|
||||
RemoveOnDamaged: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
EndOnStart:
|
||||
Closeconfine: true
|
||||
Closeconfine2: true
|
||||
@@ -368,6 +371,7 @@ Body:
|
||||
Atk_Ele: true
|
||||
Flags:
|
||||
RemoveOnUnequipWeapon: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Aspersio: true
|
||||
Fireweapon: true
|
||||
@@ -379,6 +383,8 @@ Body:
|
||||
- Status: Poisonreact
|
||||
Icon: EFST_POISONREACT
|
||||
DurationLookup: AS_POISONREACT
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Quagmire
|
||||
Icon: EFST_QUAGMIRE
|
||||
DurationLookup: WZ_QUAGMIRE
|
||||
@@ -391,6 +397,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Speedup1: true
|
||||
EndOnStart:
|
||||
@@ -419,6 +426,7 @@ Body:
|
||||
Angelus: true
|
||||
Flags:
|
||||
SendOption: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Blessing
|
||||
Icon: EFST_BLESSING
|
||||
DurationLookup: AL_BLESSING
|
||||
@@ -430,6 +438,7 @@ Body:
|
||||
Flags:
|
||||
BossResist: true
|
||||
TaekwonAngel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Signumcrucis
|
||||
Icon: EFST_CRUCIS
|
||||
DurationLookup: AL_CRUCIS
|
||||
@@ -450,6 +459,7 @@ Body:
|
||||
Flags:
|
||||
FailedMado: true
|
||||
TaekwonAngel: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
EndOnStart:
|
||||
@@ -465,6 +475,7 @@ Body:
|
||||
BossResist: true
|
||||
NoSave: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Speedup1: true
|
||||
EndOnStart:
|
||||
@@ -483,6 +494,7 @@ Body:
|
||||
DurationLookup: PR_SLOWPOISON
|
||||
Flags:
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Impositio
|
||||
Icon: EFST_IMPOSITIO
|
||||
DurationLookup: PR_IMPOSITIO
|
||||
@@ -491,6 +503,7 @@ Body:
|
||||
Matk: true
|
||||
Flags:
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Impositio: true
|
||||
- Status: Suffragium
|
||||
@@ -498,6 +511,7 @@ Body:
|
||||
DurationLookup: PR_SUFFRAGIUM
|
||||
Flags:
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Aspersio
|
||||
Icon: EFST_ASPERSIO
|
||||
DurationLookup: PR_ASPERSIO
|
||||
@@ -505,6 +519,7 @@ Body:
|
||||
Atk_Ele: true
|
||||
Flags:
|
||||
RemoveOnUnequipWeapon: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Encpoison: true
|
||||
Fireweapon: true
|
||||
@@ -523,11 +538,13 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
#RemoveOnUnequipArmor: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Kyrie
|
||||
Icon: EFST_KYRIE
|
||||
DurationLookup: PR_KYRIE
|
||||
Flags:
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Magnificat
|
||||
Icon: EFST_MAGNIFICAT
|
||||
DurationLookup: PR_MAGNIFICAT
|
||||
@@ -537,6 +554,7 @@ Body:
|
||||
FailedMado: true
|
||||
NoSave: true
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Offertorium: true
|
||||
- Status: Gloria
|
||||
@@ -546,11 +564,13 @@ Body:
|
||||
Luk: true
|
||||
Flags:
|
||||
SuperNoviceAngel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Aeterna
|
||||
Icon: EFST_LEXAETERNA
|
||||
DurationLookup: PR_LEXAETERNA
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Stone: true
|
||||
Freeze: true
|
||||
@@ -563,6 +583,7 @@ Body:
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
Decreaseagi: true
|
||||
@@ -571,6 +592,7 @@ Body:
|
||||
DurationLookup: BS_WEAPONPERFECT
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Overthrust
|
||||
Icon: EFST_OVERTHRUST
|
||||
DurationLookup: BS_OVERTHRUST
|
||||
@@ -578,6 +600,7 @@ Body:
|
||||
OverThrust: true
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Maxoverthrust: true
|
||||
- Status: Maximizepower
|
||||
@@ -587,6 +610,7 @@ Body:
|
||||
Regen: true
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Trickdead
|
||||
Icon: EFST_TRICKDEAD
|
||||
DurationLookup: NV_TRICKDEAD
|
||||
@@ -605,7 +629,8 @@ Body:
|
||||
RemoveOnDamaged: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Dancing: true
|
||||
- Status: Loud
|
||||
@@ -613,6 +638,7 @@ Body:
|
||||
DurationLookup: MC_LOUD
|
||||
Flags:
|
||||
MadoCancel: true
|
||||
RemoveOnHermode: true
|
||||
CalcFlags:
|
||||
Str: true
|
||||
Batk: true
|
||||
@@ -621,6 +647,8 @@ Body:
|
||||
DurationLookup: MG_ENERGYCOAT
|
||||
Opt3:
|
||||
EnergyCoat: true
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Brokenarmor
|
||||
Icon: EFST_BROKENARMOR
|
||||
DurationLookup: NPC_ARMORBRAKE
|
||||
@@ -673,12 +701,14 @@ Body:
|
||||
Flags:
|
||||
NoClearance: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Aspdpotion2
|
||||
Icon: EFST_ATTHASTE_POTION3
|
||||
CalcFlags:
|
||||
Aspd: true
|
||||
Flags:
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Aspdpotion3
|
||||
Icon: EFST_ATTHASTE_INFINITY
|
||||
CalcFlags:
|
||||
@@ -686,6 +716,7 @@ Body:
|
||||
Flags:
|
||||
NoClearance: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Speedup0
|
||||
Icon: EFST_MOVHASTE_HORSE
|
||||
CalcFlags:
|
||||
@@ -703,6 +734,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Atkpotion
|
||||
Icon: EFST_PLUSATTACKPOWER
|
||||
CalcFlags:
|
||||
@@ -711,6 +743,7 @@ Body:
|
||||
NoRemoveOnDead: true
|
||||
NoClearance: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Matkpotion
|
||||
Icon: EFST_PLUSMAGICPOWER
|
||||
CalcFlags:
|
||||
@@ -719,6 +752,7 @@ Body:
|
||||
NoRemoveOnDead: true
|
||||
NoClearance: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Wedding
|
||||
States:
|
||||
NoAttack: true
|
||||
@@ -749,8 +783,7 @@ Body:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
MinDuration: 5000
|
||||
- Status: Keeping
|
||||
DurationLookup: NPC_KEEPING
|
||||
@@ -762,6 +795,8 @@ Body:
|
||||
CalcFlags:
|
||||
Mdef: true
|
||||
Def: true
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Stripweapon
|
||||
Icon: EFST_NOEQUIPWEAPON
|
||||
DurationLookup: RG_STRIPWEAPON
|
||||
@@ -774,6 +809,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Stripshield
|
||||
Icon: EFST_NOEQUIPSHIELD
|
||||
DurationLookup: RG_STRIPSHIELD
|
||||
@@ -786,6 +822,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Striparmor
|
||||
Icon: EFST_NOEQUIPARMOR
|
||||
DurationLookup: RG_STRIPARMOR
|
||||
@@ -798,6 +835,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Striphelm
|
||||
Icon: EFST_NOEQUIPHELM
|
||||
DurationLookup: RG_STRIPHELM
|
||||
@@ -810,6 +848,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Cp_Weapon
|
||||
Icon: EFST_PROTECTWEAPON
|
||||
DurationLookup: AM_CP_WEAPON
|
||||
@@ -819,6 +858,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveChemicalProtect: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Cp_Shield
|
||||
Icon: EFST_PROTECTSHIELD
|
||||
DurationLookup: AM_CP_SHIELD
|
||||
@@ -828,6 +868,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveChemicalProtect: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Cp_Armor
|
||||
Icon: EFST_PROTECTARMOR
|
||||
DurationLookup: AM_CP_ARMOR
|
||||
@@ -837,6 +878,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveChemicalProtect: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Cp_Helm
|
||||
Icon: EFST_PROTECTHELM
|
||||
DurationLookup: AM_CP_HELM
|
||||
@@ -846,18 +888,21 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveChemicalProtect: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Autoguard
|
||||
Icon: EFST_AUTOGUARD
|
||||
DurationLookup: CR_AUTOGUARD
|
||||
Flags:
|
||||
NoClearance: true
|
||||
RequireShield: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Reflectshield
|
||||
Icon: EFST_REFLECTSHIELD
|
||||
DurationLookup: CR_REFLECTSHIELD
|
||||
Flags:
|
||||
NoClearance: true
|
||||
RequireShield: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Reflectdamage: true
|
||||
- Status: Splasher
|
||||
@@ -870,6 +915,7 @@ Body:
|
||||
All: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Defender
|
||||
Icon: EFST_DEFENDER
|
||||
DurationLookup: CR_DEFENDER
|
||||
@@ -878,11 +924,13 @@ Body:
|
||||
Aspd: true
|
||||
Flags:
|
||||
RequireShield: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Magicrod
|
||||
Icon: EFST_MAGICROD
|
||||
DurationLookup: SA_MAGICROD
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Spellbreaker
|
||||
Flags:
|
||||
NoWarning: true
|
||||
@@ -916,6 +964,7 @@ Body:
|
||||
Flags:
|
||||
FailedMado: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
- Status: Autocounter
|
||||
@@ -970,6 +1019,7 @@ Body:
|
||||
Debuff: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Combo
|
||||
Flags:
|
||||
NoClearbuff: true
|
||||
@@ -982,8 +1032,7 @@ Body:
|
||||
States:
|
||||
NoMove: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Bladestop
|
||||
Icon: EFST_BLADESTOP
|
||||
DurationLookup: MO_BLADESTOP
|
||||
@@ -1000,7 +1049,8 @@ Body:
|
||||
NoClearbuff: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Fireweapon
|
||||
Icon: EFST_PROPERTYFIRE
|
||||
DurationLookup: SA_FLAMELAUNCHER
|
||||
@@ -1070,6 +1120,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Deluge
|
||||
Icon: EFST_GROUNDMAGIC
|
||||
DurationLookup: SA_DELUGE
|
||||
@@ -1129,6 +1180,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Parrying
|
||||
Icon: EFST_PARRYING
|
||||
DurationLookup: LK_PARRYING
|
||||
@@ -1136,6 +1188,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Concentration
|
||||
Icon: EFST_LKCONCENTRATION
|
||||
DurationLookup: LK_CONCENTRATION
|
||||
@@ -1146,6 +1199,7 @@ Body:
|
||||
Quicken: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Tensionrelax
|
||||
Icon: EFST_TENSIONRELAX
|
||||
DurationLookup: LK_TENSIONRELAX
|
||||
@@ -1154,6 +1208,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Berserk
|
||||
Icon: EFST_BERSERK
|
||||
DurationLookup: LK_BERSERK
|
||||
@@ -1194,6 +1249,7 @@ Body:
|
||||
Aspd: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Assumptio
|
||||
Icon: EFST_ASSUMPTIO2
|
||||
DurationLookup: HP_ASSUMPTIO
|
||||
@@ -1203,6 +1259,8 @@ Body:
|
||||
Assumptio: true
|
||||
EndOnStart:
|
||||
Kaite: true
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Basilica
|
||||
Icon: EFST_BASILICA_BUFF
|
||||
DurationLookup: HP_BASILICA
|
||||
@@ -1213,6 +1271,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Guildaura
|
||||
Flags:
|
||||
NoDispell: true
|
||||
@@ -1225,6 +1284,7 @@ Body:
|
||||
Matk: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Magicpower: true
|
||||
- Status: Edp
|
||||
@@ -1251,6 +1311,7 @@ Body:
|
||||
Flags:
|
||||
FailedMado: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
- Status: Windwalk
|
||||
@@ -1262,6 +1323,7 @@ Body:
|
||||
Flags:
|
||||
FailedMado: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
- Status: Meltdown
|
||||
@@ -1304,7 +1366,7 @@ Body:
|
||||
OnTouch: true
|
||||
StopAttacking: true
|
||||
RemoveOnDamaged: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
@@ -1324,8 +1386,7 @@ Body:
|
||||
Opt3:
|
||||
Marionette: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Marionette: true
|
||||
- Status: Marionette2
|
||||
@@ -1341,8 +1402,7 @@ Body:
|
||||
Opt3:
|
||||
Marionette: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Marionette2: true
|
||||
- Status: Changeundead
|
||||
@@ -1356,6 +1416,7 @@ Body:
|
||||
Debuff: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Blessing: true
|
||||
Increaseagi: true
|
||||
@@ -1371,6 +1432,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Mindbreaker
|
||||
Icon: EFST_MINDBREAKER
|
||||
DurationLookup: PF_MINDBREAKER
|
||||
@@ -1380,6 +1442,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Freeze: true
|
||||
Stone: true
|
||||
@@ -1389,6 +1452,7 @@ Body:
|
||||
DurationLookup: PF_MEMORIZE
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Fogwall
|
||||
Icon: EFST_FOGWALL
|
||||
DurationLookup: PF_FOGWALL
|
||||
@@ -1396,6 +1460,7 @@ Body:
|
||||
BossResist: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Spiderweb
|
||||
Icon: EFST_SPIDERWEB
|
||||
DurationLookup: PF_SPIDERWEB
|
||||
@@ -1416,8 +1481,9 @@ Body:
|
||||
DurationLookup: CR_DEVOTION
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnHermode: true
|
||||
EndOnEnd:
|
||||
Autoguard: true
|
||||
Defender: true
|
||||
@@ -1425,6 +1491,8 @@ Body:
|
||||
Endure: true
|
||||
- Status: Sacrifice
|
||||
DurationLookup: PA_SACRIFICE
|
||||
Flags:
|
||||
RemoveOnHermode: true
|
||||
- Status: Steelbody
|
||||
Icon: EFST_STEELBODY
|
||||
DurationLookup: MO_STEELBODY
|
||||
@@ -1437,6 +1505,7 @@ Body:
|
||||
Speed: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
Opt3:
|
||||
SteelBody: true
|
||||
- Status: Orcish
|
||||
@@ -1500,7 +1569,8 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Shadowweapon
|
||||
Icon: EFST_PROPERTYDARK
|
||||
DurationLookup: TK_SEVENWIND
|
||||
@@ -1509,6 +1579,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Encpoison: true
|
||||
Aspersio: true
|
||||
@@ -1526,6 +1597,7 @@ Body:
|
||||
MadoCancel: true
|
||||
NoSave: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Quagmire: true
|
||||
Decreaseagi: true
|
||||
@@ -1537,6 +1609,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Encpoison: true
|
||||
Aspersio: true
|
||||
@@ -1554,6 +1627,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Kaahi: true
|
||||
- Status: Kaupe
|
||||
@@ -1562,6 +1636,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Onehand
|
||||
Icon: EFST_ONEHANDQUICKEN
|
||||
DurationLookup: KN_ONEHAND
|
||||
@@ -1573,6 +1648,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Decreaseagi: true
|
||||
EndOnStart:
|
||||
@@ -1585,6 +1661,7 @@ Body:
|
||||
DurationLookup: ST_PRESERVE
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Battleorders
|
||||
Icon: EFST_GDSKILL_BATTLEORDER
|
||||
DurationLookup: GD_BATTLEORDER
|
||||
@@ -1608,6 +1685,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Maxoverthrust
|
||||
Icon: EFST_OVERTHRUSTMAX
|
||||
DurationLookup: WS_OVERTHRUSTMAX
|
||||
@@ -1617,6 +1695,7 @@ Body:
|
||||
MadoCancel: true
|
||||
NoSave: true
|
||||
RemoveOnUnequipWeapon: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Overthrust: true
|
||||
- Status: Hermode
|
||||
@@ -1659,7 +1738,7 @@ Body:
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
NoRemoveOnDead: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Closeconfine2
|
||||
Icon: EFST_RG_CCONFINE_S
|
||||
DurationLookup: RG_CLOSECONFINE
|
||||
@@ -1672,7 +1751,7 @@ Body:
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
NoRemoveOnDead: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Closeconfine2: true
|
||||
- Status: Dancing
|
||||
@@ -1689,10 +1768,9 @@ Body:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
RequireWeapon: true
|
||||
OverlapIgnoreLevel: true
|
||||
NoSave: true
|
||||
EndOnEnd:
|
||||
EnsembleFatigue: true
|
||||
- Status: Elementalchange
|
||||
@@ -1968,8 +2046,9 @@ Body:
|
||||
StopWalking: true
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Debuff: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Spurt
|
||||
Icon: EFST_STRUP
|
||||
DurationLookup: TK_RUN
|
||||
@@ -1979,6 +2058,7 @@ Body:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RequireWeapon: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Spirit
|
||||
Icon: EFST_SOULLINK
|
||||
DurationLookup: SL_HIGH
|
||||
@@ -1990,6 +2070,7 @@ Body:
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
NoBanishingBuster: true
|
||||
RemoveOnHermode: true
|
||||
Fail:
|
||||
Soulgolem: true
|
||||
Soulshadow: true
|
||||
@@ -2289,8 +2370,8 @@ Body:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
- Status: Sun_Comfort
|
||||
Icon: EFST_SUN_COMFORT
|
||||
DurationLookup: SG_SUN_COMFORT
|
||||
@@ -2298,7 +2379,6 @@ Body:
|
||||
Def2: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
- Status: Moon_Comfort
|
||||
Icon: EFST_MOON_COMFORT
|
||||
DurationLookup: SG_MOON_COMFORT
|
||||
@@ -2306,7 +2386,6 @@ Body:
|
||||
Flee: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
- Status: Star_Comfort
|
||||
Icon: EFST_STAR_COMFORT
|
||||
DurationLookup: SG_STAR_COMFORT
|
||||
@@ -2314,7 +2393,6 @@ Body:
|
||||
Aspd: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
- Status: Fusion
|
||||
DurationLookup: SG_FUSION
|
||||
CalcFlags:
|
||||
@@ -2345,6 +2423,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Assumptio: true
|
||||
- Status: Swoo
|
||||
@@ -2442,6 +2521,7 @@ Body:
|
||||
NoClearance: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Bunsinjyutsu
|
||||
Icon: EFST_NJ_BUNSINJYUTSU
|
||||
DurationLookup: NJ_BUNSINJYUTSU
|
||||
@@ -2452,6 +2532,7 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Kaensin
|
||||
Flags:
|
||||
NoWarning: true
|
||||
@@ -2508,8 +2589,7 @@ Body:
|
||||
Vit: true
|
||||
Int: true
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Change: true
|
||||
- Status: Bloodlust
|
||||
@@ -2567,6 +2647,7 @@ Body:
|
||||
SendVal1: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnUnequipWeapon: true
|
||||
RemoveOnHermode: true
|
||||
EndOnStart:
|
||||
Enchantarms: true
|
||||
Aspersio: true
|
||||
@@ -3332,7 +3413,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Bite
|
||||
Icon: EFST_WUGBITE
|
||||
DurationLookup: RA_WUGBITE
|
||||
@@ -3364,7 +3445,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Acceleration
|
||||
Icon: EFST_ACCELERATION
|
||||
DurationLookup: NC_ACCELERATION
|
||||
@@ -3451,7 +3532,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Stealthfield
|
||||
Icon: EFST_STEALTHFIELD
|
||||
DurationLookup: NC_STEALTHFIELD
|
||||
@@ -3475,7 +3556,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Overheat
|
||||
Icon: EFST_OVERHEAT
|
||||
Flags:
|
||||
@@ -3914,7 +3995,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Debuff: true
|
||||
Fail:
|
||||
Hallucinationwalk: true
|
||||
@@ -4309,7 +4390,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
StopAttacking: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
SendVal3: true
|
||||
- Status: Cursedcircle_Target
|
||||
Icon: EFST_CURSEDCIRCLE_TARGET
|
||||
@@ -4657,7 +4738,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
SendVal3: true
|
||||
- Status: _Bodypaint
|
||||
Icon: EFST_BODYPAINT
|
||||
@@ -4808,8 +4889,7 @@ Body:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: _Bloodylust
|
||||
Icon: EFST_BLOODYLUST
|
||||
DurationLookup: SC_BLOODYLUST
|
||||
@@ -5482,7 +5562,7 @@ Body:
|
||||
Flee: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Tinder_Breaker2
|
||||
Icon: EFST_TINDER_BREAKER
|
||||
DurationLookup: MH_TINDER_BREAKER
|
||||
@@ -5490,7 +5570,7 @@ Body:
|
||||
Flee: true
|
||||
Flags:
|
||||
NoSave: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Tinder_Breaker2: true
|
||||
- Status: Cbc
|
||||
@@ -6030,9 +6110,10 @@ Body:
|
||||
Flags:
|
||||
NoSave: true
|
||||
NoClearance: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Extremityfist2
|
||||
Icon: EFST_EXTREMITYFIST
|
||||
DurationLookup: MO_EXTREMITYFIST
|
||||
@@ -6369,6 +6450,7 @@ Body:
|
||||
Flags:
|
||||
StopAttacking: true
|
||||
RemoveOnDamaged: true
|
||||
RemoveOnChangeMap: true
|
||||
RemoveOnMapWarp: true
|
||||
- Status: Su_Stoop
|
||||
Icon: EFST_SU_STOOP
|
||||
@@ -6678,6 +6760,7 @@ Body:
|
||||
Flags:
|
||||
NoRemoveOnDead: true
|
||||
NoClearbuff: true
|
||||
RemoveOnHermode: true
|
||||
- Status: Geffen_Magic2
|
||||
Icon: EFST_GEFFEN_MAGIC2
|
||||
CalcFlags:
|
||||
@@ -6960,8 +7043,7 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
NoClearbuff: true
|
||||
RemoveOnMapWarp: true
|
||||
NoSave: true
|
||||
RemoveOnChangeMap: true
|
||||
- Status: Entry_Queue_Apply_Delay
|
||||
Icon: EFST_ENTRY_QUEUE_APPLY_DELAY
|
||||
Flags:
|
||||
@@ -7045,7 +7127,7 @@ Body:
|
||||
Icon: EFST_FLASHKICK
|
||||
DurationLookup: SJ_FLASHKICK
|
||||
Flags:
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
@@ -7064,7 +7146,7 @@ Body:
|
||||
NoClearance: true
|
||||
StopAttacking: true
|
||||
RemoveOnDamaged: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
Fail:
|
||||
Bite: true
|
||||
- Status: Starstance
|
||||
@@ -7629,7 +7711,7 @@ Body:
|
||||
BlEffect: true
|
||||
DisplayPc: true
|
||||
OverlapIgnoreLevel: true
|
||||
RemoveOnMapWarp: true
|
||||
RemoveOnChangeMap: true
|
||||
NoBanishingBuster: true
|
||||
NoDispell: true
|
||||
NoClearance: true
|
||||
|
||||
@@ -1419,6 +1419,7 @@ This will also send a packet to clients causing them to close.
|
||||
@reloadstatusdb
|
||||
@reloadachievementdb
|
||||
@reloadattendancedb
|
||||
@reloadbarterdb
|
||||
|
||||
Reloads a database or configuration file.
|
||||
|
||||
@@ -1427,10 +1428,11 @@ Databases:
|
||||
-- itemdb: Item Database
|
||||
-- mobdb: Monster Database
|
||||
-- questdb: Quest Database
|
||||
-- script: NPC Scripts
|
||||
-- script: NPC Scripts and Barter Database
|
||||
-- skilldb: Skill Database
|
||||
-- achievementdb: Achievement Database
|
||||
-- attendancedb: Attendance Database
|
||||
-- barterdb: Barter Database
|
||||
|
||||
Configuration files:
|
||||
-- atcommand: Atcommand Settings
|
||||
@@ -1450,11 +1452,12 @@ Affected files:
|
||||
-- msgconf: atcommands.yml
|
||||
-- pcdb: statpoint.yml, job_exp.yml, skill_tree.yml, attr_fix.yml, job_stats.yml, job_basepoints.yml, level_penalty.yml
|
||||
-- questdb: quest_db.yml
|
||||
-- script: /npc/*.txt, /npc/*.conf
|
||||
-- script: /npc/*.txt, /npc/*.conf, /npc/barters.yml
|
||||
-- skilldb: skill_db.yml, skill_nocast_db.txt, skill_changematerial_db.txt, skill_damage_db.txt, abra_db.yml, create_arrow_db.yml, produce_db.txt, spellbook_db.yml, magicmushroom_db.yml
|
||||
-- statusdb: attr_fix.yml, size_fix.yml, refine.yml
|
||||
-- achievementdb: achievement_db.yml
|
||||
-- attendancedb: attendance.yml
|
||||
-- barterdb: /npc/barters.yml
|
||||
|
||||
Restriction:
|
||||
- Used from 'atcommand' or 'useatcmd'. For @reload & @reloadscript
|
||||
|
||||
@@ -159,7 +159,8 @@ executed, it is affected by spawn rates in 'battle_athena.conf'.
|
||||
Delay1 and delay2 control monster respawn delays - the first one is the fixed
|
||||
base respawn time, and the second is random variance on top of the base time.
|
||||
Both values are given in milliseconds (1000 = 1 second).
|
||||
Note that the server also enforces a minimum respawn delay of 5 seconds.
|
||||
Note that the server also enforces a minimum respawn delay of 1 second (See
|
||||
/conf/battle/monster.conf::mob_respawn_time).
|
||||
|
||||
Event is a script event to be executed when the mob is killed. The event must
|
||||
be in the form "NPCName::OnEventName" to execute, and the event name label
|
||||
@@ -2730,7 +2731,7 @@ See 'getequipid' for a full list of valid equipment slots.
|
||||
|
||||
Given the database ID number of an item, this function will return the text
|
||||
stored in the 'Name' field in item_db_*.yml for text version
|
||||
or 'name_english' field for SQL version.
|
||||
or 'name_english' field for SQL version. The function returns "null" if the item doesn't exist.
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@@ -6579,6 +6580,28 @@ Examples:
|
||||
|
||||
---------------------------------------
|
||||
|
||||
macro_detector({<account ID>});
|
||||
macro_detector({"<character name>"});
|
||||
|
||||
This command will display the captcha UI challenge onto the invoking character or the given <account ID>/<character name>.
|
||||
|
||||
Example:
|
||||
// Use 'getareaunits' to gather an area of players to test.
|
||||
// Build an int array of the account IDs.
|
||||
.@num = getareaunits(BL_PC, "prontera", 150, 150, 160, 160, .@array[0]);
|
||||
|
||||
mes "The number of Players in Prontera in between 150x150 and 160x160 is " + .@num + " .";
|
||||
mes "Players to challenge:";
|
||||
freeloop(1); // If the list is too big
|
||||
for(.@i = 0; .@i < getarraysize(.@array); .@i++) {
|
||||
mes (.@i + 1) + " " + convertpcinfo(.@array[.@i], CPC_NAME);
|
||||
macro_detector .@array[.@i];
|
||||
}
|
||||
freeloop(0);
|
||||
end;
|
||||
|
||||
---------------------------------------
|
||||
|
||||
==================================
|
||||
|5.- Mob / NPC -related commands.|
|
||||
==================================
|
||||
@@ -9647,9 +9670,13 @@ returns an empty string instead.
|
||||
|
||||
*instance_id({<instance mode>})
|
||||
|
||||
Returns the unique instance ID of the given mode. By default it returns the
|
||||
attached script instance. If <instance mode> is provided then the instance
|
||||
of the currently attached player is used. If that fails, the function will return 0.
|
||||
Returns the unique instance ID of the given mode.
|
||||
|
||||
By default (no parameter given) the command returns the instance ID from the attached NPC.
|
||||
If <instance mode> is provided the instance ID of the currently attached player is returned.
|
||||
If that fails, the function will return 0.
|
||||
|
||||
Please note that the command always requires the parameter <instance mode> to get the instance ID of an attached player!
|
||||
|
||||
Instance Mode options:
|
||||
IM_CHAR: Attached to character.
|
||||
@@ -9657,6 +9684,13 @@ Instance Mode options:
|
||||
IM_GUILD: Attached to character's guild.
|
||||
IM_CLAN: Attached to character's clan.
|
||||
|
||||
Examples:
|
||||
// Example with an attached player :
|
||||
npctalk "The current instance ID (mode party) from the attached player is : " + instance_id(IM_PARTY);
|
||||
|
||||
// Example with an attached NPC on an instance map :
|
||||
npctalk "The current instance ID from the attached NPC is : " + instance_id();
|
||||
|
||||
---------------------------------------
|
||||
|
||||
*instance_warpall "<map name>",<x>,<y>{,<instance id>};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//===== By: ==================================================
|
||||
//= rAthena Dev Team
|
||||
//===== Last Updated: ========================================
|
||||
//= 20221013
|
||||
//= 20221216
|
||||
//===== Description: =========================================
|
||||
//= Explanation of the status.yml file and structure.
|
||||
//============================================================
|
||||
@@ -226,11 +226,13 @@ Flags: Various status flags for specific status change events.
|
||||
RemoveOnRefresh - Removed by RK_REFRESH.
|
||||
RemoveOnLuxAnima - Removed by RK_LUXANIMA.
|
||||
RemoveOnMapWarp - Removed when warping to another map.
|
||||
RemoveOnChangeMap - Removed when changing map-server.
|
||||
RemoveChemicalProtect - Removed by AM_CP_ARMOR/AM_CP_HELM/AM_CP_SHIELD/AM_CP_WEAPON.
|
||||
RemoveElementalOption - Removed by elemental changing modes/quitting/EL_TIDAL_WEAPON/EL_WATER_SCREEN on the master and elemental.
|
||||
RemoveOnUnequip - Removed when unequipping any type of equipment.
|
||||
RemoveOnUnequipWeapon - Removed when unequipping a weapon.
|
||||
RemoveOnUnequipArmor - Removed when unequipping an armor.
|
||||
RemoveOnHermode - Removed by CG_HERMODE.
|
||||
|
||||
StopAttacking - Makes the unit stop attacking.
|
||||
StopCasting - Makes the unit stop casting skills.
|
||||
|
||||
12
doc/yaml/db/item_cash.yml
Normal file
12
doc/yaml/db/item_cash.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
###########################################################################
|
||||
# Item Cash Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Cash Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Tab Cash shop tab. Available tabs are New, Hot, Limited, Rental, Permanent, Scrolls, Consumables, Other, Sale.
|
||||
# Items: List of possible items.
|
||||
# - Item Item name.
|
||||
# Price Item cost in cash points (#CASHPOINTS).
|
||||
###########################################################################
|
||||
@@ -127,13 +127,14 @@ function Restrict {
|
||||
Towns:
|
||||
// --------------------------------------------------
|
||||
menu "Prontera",T1, "Alberta",T2, "Aldebaran",T3, "Amatsu",T4, "Ayothaya",T5,
|
||||
"Brasilis",T6, "Comodo",T7, "Dewata",T8, "Eclage",T9, "Einbech",T10,
|
||||
"Einbroch",T11, "El Dicastes",T12, "Geffen",T13, "Kunlun",T14, "Hugel",T15,
|
||||
"Izlude",T16, "Jawaii",T17, "Lasagna",T18, "Lighthalzen",T19, "Luoyang",T20,
|
||||
"Lutie",T21, "Malangdo",T22, "Malaya",T23, "Manuk",T24,
|
||||
"Midgarts Expedition Camp",T25, "Mora",T26, "Morocc",T27, "Moscovia",T28,
|
||||
"Nameless Island",T29, "Niflheim",T30, "Payon",T31, "Rachel",T32, "Splendide",T33,
|
||||
"Thor Camp",T34, "Umbala",T35, "Veins",T36, "Juno",T37;
|
||||
"Brasilis",T6, "Comodo",T7, "Dewata",T8, "Eclage",T9, "Einbech",T10,
|
||||
"Einbroch",T11, "El Dicastes",T12, "Geffen",T13, "Hugel",T14, "Ice Castle",T15,
|
||||
"Izlude",T16, "Jawaii",T17, "Juno",T18, "Kunlun",T19, "Lasagna",T20,
|
||||
"Lighthalzen",T21, "Luoyang",T22, "Lutie",T23, "Malangdo",T24, "Malaya",T25,
|
||||
"Manuk",T26, "Midgarts Expedition Camp",T27, "Mora",T28, "Morocc",T29, "Moscovia",T30,
|
||||
"Nameless Island (Day)",T31, "Nameless Island (Night)",T32, "Niflheim",T33, "Payon",T34, "Rachel",T35,
|
||||
"Rockridge",T36, "Special Security Area, Cor",T37, "Splendide",T38, "Thor Camp",T39, "Umbala",T40,
|
||||
"Varmundt's Mansion",T41, "Veins",T42, "Verus Findspot",T43, "Wolf Village",T44;
|
||||
|
||||
T1: Go("prontera",155,183);
|
||||
T2: Go("alberta",28,234);
|
||||
@@ -152,34 +153,47 @@ T11: Go("einbroch",64,200);
|
||||
T12: Restrict("RE");
|
||||
Go("dicastes01",198,187);
|
||||
T13: Go("geffen",119,59);
|
||||
T14: Go("gonryun",160,120);
|
||||
T15: Go("hugel",96,145);
|
||||
T14: Go("hugel",96,145);
|
||||
T15: Restrict("RE");
|
||||
Go("icecastle",185,212);
|
||||
T16: Go("izlude",128,(checkre(3)?146:114));
|
||||
T17: Go("jawaii",251,132);
|
||||
T18: Restrict("RE");
|
||||
T18: Go("yuno",157,51);
|
||||
T19: Go("gonryun",160,120);
|
||||
T20: Restrict("RE");
|
||||
Go("lasagna",193,182);
|
||||
T19: Go("lighthalzen",158,92);
|
||||
T20: Go("louyang",217,100);
|
||||
T21: Go("xmas",147,134);
|
||||
T22: Restrict("RE");
|
||||
T21: Go("lighthalzen",158,92);
|
||||
T22: Go("louyang",217,100);
|
||||
T23: Go("xmas",147,134);
|
||||
T24: Restrict("RE");
|
||||
Go("malangdo",140,114);
|
||||
T23: Restrict("RE");
|
||||
T25: Restrict("RE");
|
||||
Go("malaya",231,200);
|
||||
T24: Go("manuk",282,138);
|
||||
T25: Go("mid_camp",210,288);
|
||||
T26: Restrict("RE");
|
||||
T26: Go("manuk",282,138);
|
||||
T27: Go("mid_camp",210,288);
|
||||
T28: Restrict("RE");
|
||||
Go("mora",55,146);
|
||||
T27: Go("morocc",156,93);
|
||||
T28: Go("moscovia",223,184);
|
||||
T29: Go("nameless_n",256,215);
|
||||
T30: Go("niflheim",202,174);
|
||||
T31: Go("payon",179,100);
|
||||
T32: Go("rachel",130,110);
|
||||
T33: Go("splendide",201,147);
|
||||
T34: Go("thor_camp",246,68);
|
||||
T35: Go("umbala",97,153);
|
||||
T36: Go("veins",216,123);
|
||||
T37: Go("yuno",157,51);
|
||||
T29: Go("morocc",156,93);
|
||||
T30: Go("moscovia",223,184);
|
||||
T31: Go("nameless_i",256,215);
|
||||
T32: Go("nameless_n",256,215);
|
||||
T33: Go("niflheim",202,174);
|
||||
T34: Go("payon",179,100);
|
||||
T35: Go("rachel",130,110);
|
||||
T36: Restrict("RE");
|
||||
Go("harboro1",298,206);
|
||||
T37: Restrict("RE");
|
||||
Go("sp_cor",160,166);
|
||||
T38: Go("splendide",201,147);
|
||||
T39: Go("thor_camp",246,68);
|
||||
T40: Go("umbala",97,153);
|
||||
T41: Restrict("RE");
|
||||
Go("ba_maison",72,146);
|
||||
T42: Go("veins",216,123);
|
||||
T43: Restrict("RE");
|
||||
Go("verus04",123,250);
|
||||
T44: Restrict("RE");
|
||||
Go("wolfvill",144,144);
|
||||
|
||||
// --------------------------------------------------
|
||||
Fields:
|
||||
@@ -188,13 +202,14 @@ T37: Go("yuno",157,51);
|
||||
menu "Amatsu Fields",F1, "Ayothaya Fields",F2, "Bifrost Fields", F3,
|
||||
"Brasilis Fields",F4, "Comodo Fields",F5, "Dewata Fields",F6,
|
||||
"Eclage Fields",F7, "Einbroch Fields",F8, "El Dicastes Fields",F9,
|
||||
"Geffen Fields",F10, "Kunlun Fields",F11, "Hugel Fields",F12,
|
||||
"Lasagna Fields",F13, "Lighthalzen Fields",F14, "Luoyang Field",F15,
|
||||
"Lutie Field",F16, "Malaya Fields",F17, "Manuk Fields",F18,
|
||||
"Mjolnir Fields",F19, "Moscovia Fields",F20, "Niflheim Fields",F21,
|
||||
"Payon Forests",F22, "Prontera Fields",F23, "Rachel Fields",F24,
|
||||
"Sograt Deserts",F25, "Splendide Fields",F26, "Umbala Fields",F27,
|
||||
"Veins Fields",F28, "Juno Fields",F29;
|
||||
"Frozen Scale Fields",F10, "Geffen Fields",F11, "Grey Wolf Forest",F12,
|
||||
"Hugel Fields",F13, "Juno Fields",F14, "Kiwawa Desert",F15,
|
||||
"Kunlun Fields",F16, "Lasagna Fields",F17, "Lighthalzen Fields",F18,
|
||||
"Luoyang Field",F19, "Lutie Field",F20, "Malaya Fields",F21,
|
||||
"Manuk Fields",F22, "Mjolnir Fields",F23, "Moscovia Fields",F24,
|
||||
"Niflheim Fields",F25, "Payon Forests",F26, "Prontera Fields",F27,
|
||||
"Rachel Fields",F28, "Sograt Deserts",F29, "Splendide Fields",F30,
|
||||
"Umbala Fields",F31, "Veins Fields",F32;
|
||||
|
||||
F1: setarray @c[2],190,197;
|
||||
Disp("Amatsu Field",1,1); Pick("ama_fild");
|
||||
@@ -221,43 +236,55 @@ F8: Restrict("Pre-RE",2,10);
|
||||
F9: Restrict("RE");
|
||||
setarray @c[2],143,132,143,217;
|
||||
Disp("El Dicastes Field",1,2); Pick("dic_fild");
|
||||
F10: Restrict("Pre-RE",13,15);
|
||||
F10: Restrict("RE");
|
||||
setarray @c[2],378,223,223,18,365,241,140,280;
|
||||
Disp("Frozen Scale Hill:Frozen Scale Plains:Frozen Scale Glacier:Frozen Tail"); Pick("","jor_back1","jor_back2","jor_back3","jor_tail");
|
||||
F11: Restrict("Pre-RE",13,15);
|
||||
setarray @c[0],46,199,213,204,195,212,257,192,188,171,166,263,248,158,195,191,186,183,221,117,178,218,136,328,240,181,235,235,211,185;
|
||||
Disp("Geffen Field",0,14); Pick("gef_fild",1);
|
||||
F11: setarray @c[2],220,227;
|
||||
Disp("Kunlun Field",1,1); Pick("gon_fild");
|
||||
F12: Restrict("Pre-RE",3,7);
|
||||
F12: Restrict("RE");
|
||||
setarray @c[2],22,315,122,388;
|
||||
Disp("Grey Wolf Forest",1,2); Pick("gw_fild");
|
||||
F13: Restrict("Pre-RE",3,7);
|
||||
setarray @c[2],268,101,222,193,232,185,252,189,196,106,216,220,227,197;
|
||||
Disp("Hugel Field",1,7); Pick("hu_fild");
|
||||
F13: Restrict("RE");
|
||||
F14: Restrict("Pre-RE",5,10);
|
||||
setarray @c[2],189,224,192,207,221,157,226,199,223,177,187,232,231,174,196,203,183,214,200,124,195,226,210,304;
|
||||
Disp("Juno Field",1,12); Pick("yuno_fild");
|
||||
F15: Restrict("RE");
|
||||
setarray @c[2],38,246,31,207;
|
||||
Disp("Kiwawa Desert",1,2); Pick("","rockrdg1","rockrdg2");
|
||||
F16: setarray @c[2],220,227;
|
||||
Disp("Kunlun Field",1,1); Pick("gon_fild");
|
||||
F17: Restrict("RE");
|
||||
setarray @c[2],344,371,20,98;
|
||||
Disp("Lasagna Field",1,2); Pick("lasa_fild");
|
||||
F14: setarray @c[2],240,179,185,235,240,226;
|
||||
F18: setarray @c[2],240,179,185,235,240,226;
|
||||
Disp("Lighthalzen Field",1,3); Pick("lhz_fild");
|
||||
F15: setarray @c[2],229,187;
|
||||
F19: setarray @c[2],229,187;
|
||||
Disp("Luoyang Field",1,1); Pick("lou_fild");
|
||||
F16: setarray @c[2],115,145;
|
||||
F20: setarray @c[2],115,145;
|
||||
Disp("Lutie Field",1,1); Pick("xmas_fild");
|
||||
F17: Restrict("RE");
|
||||
F21: Restrict("RE");
|
||||
setarray @c[2],40,272,207,180;
|
||||
Disp("Malaya Field",1,2); Pick("ma_fild");
|
||||
F18: setarray @c[2],35,236,35,262,84,365;
|
||||
F22: setarray @c[2],35,236,35,262,84,365;
|
||||
Disp("Manuk Field",1,3); Pick("man_fild");
|
||||
F19: setarray @c[2],204,120,175,193,208,213,179,180,181,240,195,270,235,202,188,215,205,144,245,223,180,206,196,208;
|
||||
F23: setarray @c[2],204,120,175,193,208,213,179,180,181,240,195,270,235,202,188,215,205,144,245,223,180,206,196,208;
|
||||
Disp("Mjolnir Field",1,12); Pick("mjolnir_");
|
||||
F20: setarray @c[2],82,104,131,147;
|
||||
F24: setarray @c[2],82,104,131,147;
|
||||
Disp("Moscovia Field",1,2); Pick("mosk_fild");
|
||||
F21: setarray @c[2],215,229,167,234;
|
||||
F25: setarray @c[2],215,229,167,234;
|
||||
Disp("Niflheim Field",1,2); Pick("nif_fild");
|
||||
F22: Restrict("Pre-RE",5,11);
|
||||
F26: Restrict("Pre-RE",5,11);
|
||||
setarray @c[2],158,206,151,219,205,148,186,247,134,204,193,235,200,177,137,189,201,224,160,205,194,150;
|
||||
Disp("Payon Forest",1,11); Pick("pay_fild");
|
||||
F23: setarray @c[0],208,227,190,206,240,206,190,143,307,252,239,213,185,188,193,194,187,218,210,183,195,149,198,164;
|
||||
F27: setarray @c[0],208,227,190,206,240,206,190,143,307,252,239,213,185,188,193,194,187,218,210,183,195,149,198,164;
|
||||
Disp("Prontera Field",0,11); Pick("prt_fild",1);
|
||||
F24: Restrict("Pre-RE",2,7,9,10,11,13);
|
||||
F28: Restrict("Pre-RE",2,7,9,10,11,13);
|
||||
setarray @c[2],192,162,235,166,202,206,202,208,225,202,202,214,263,196,217,201,87,121,277,181,221,185,175,200,174,197;
|
||||
Disp("Rachel Field",1,13); Pick("ra_fild");
|
||||
F25: if(.Satan_Morocc){
|
||||
F29: if(.Satan_Morocc){
|
||||
setarray @c[2],219,205,177,206,194,182,224,170,198,216,156,187,185,263,206,228,208,238,209,223,85,97,207,202,31,195,38,195;
|
||||
Disp("Sograt Desert 1:Sograt Desert 2:Sograt Desert 3:Sograt Desert 7:Sograt Desert 11:Sograt Desert 12:Sograt Desert 13:Sograt Desert 16:Sograt Desert 17:Sograt Desert 18:Sograt Desert 19:Sograt Desert 20:Sograt Desert 21:Sograt Desert 22");
|
||||
Pick("","moc_fild01","moc_fild02","moc_fild03","moc_fild07","moc_fild11","moc_fild12","moc_fild13","moc_fild16","moc_fild17","moc_fild18","moc_fild19","moc_fild20","moc_fild21","moc_fild22");
|
||||
@@ -265,133 +292,194 @@ F25: if(.Satan_Morocc){
|
||||
setarray @c[2],219,205,177,206,194,182,146,297,204,197,275,302,224,170,139,123,101,110,341,39,198,216,156,187,185,263,223,222,170,257,206,228,208,238,209,223,85,97;
|
||||
Disp("Sograt Desert",1,19); Pick("moc_fild");
|
||||
}
|
||||
F26: setarray @c[2],175,186,236,184,188,204;
|
||||
F30: setarray @c[2],175,186,236,184,188,204;
|
||||
Disp("Splendide Field",1,3); Pick("spl_fild");
|
||||
F27: setarray @c[2],217,206,223,221,237,215,202,197;
|
||||
F31: setarray @c[2],217,206,223,221,237,215,202,197;
|
||||
Disp("Umbala Field",1,4); Pick("um_fild");
|
||||
F28: Restrict("Pre-RE",5);
|
||||
F32: Restrict("Pre-RE",5);
|
||||
setarray @c[2],186,175,196,370,222,45,51,250,202,324,150,223,149,307;
|
||||
Disp("Veins Field",1,7); Pick("ve_fild");
|
||||
F29: Restrict("Pre-RE",5,10);
|
||||
setarray @c[2],189,224,192,207,221,157,226,199,223,177,187,232,231,174,196,203,183,214,200,124,195,226,210,304;
|
||||
Disp("Juno Field",1,12); Pick("yuno_fild");
|
||||
|
||||
// --------------------------------------------------
|
||||
Dungeons:
|
||||
// --------------------------------------------------
|
||||
@d = true;
|
||||
menu "Abyss Lakes",D1, "Amatsu Dungeon",D2, "Anthell",D3,
|
||||
"Ayothaya Dungeon",D4, "Beach Dungeon",D5, "Bifrost Tower",D42,
|
||||
"Bio Labs",D6, "Brasilis Dungeon",D7, "Byalan Dungeon",D8, "Clock Tower",D9,
|
||||
"Coal Mines",D10, "Culvert",D11, "Cursed Abbey",D12, "Dewata Dungeon",D13,
|
||||
"Einbroch Dungeon",D14, "Gefenia",D15, "Geffen Dungeon",D16,
|
||||
"Glast Heim",D17, "Kunlun Dungeon",D18, "Hidden Dungeon",D19,
|
||||
"Ice Dungeon",D20, "Juperos",D21, "Kiel Dungeon",D22, "Lasagna Dungeon",D23,
|
||||
"Luoyang Dungeon",D24, "Magma Dungeon",D25, "Malangdo Dungeon",D26,
|
||||
"Moscovia Dungeon",D27, "Nidhogg's Dungeon",D28, "Odin Temple",D29,
|
||||
"Orc Dungeon",D30, "Payon Dungeon",D31, "Pyramids",D32, "Rachel Sanctuary",D33,
|
||||
"Scaraba Hole",D34, "Sphinx",D35, "Sunken Ship",D36, "Thanatos Tower",D37,
|
||||
"Thor Volcano",D38, "Toy Factory",D39, "Turtle Dungeon",D40, "Umbala Dungeon",D41;
|
||||
menu "Abandoned Lab Amicitia",D1, "Abyss Lakes",D2, "Amatsu Dungeon",D3,
|
||||
"Anthell",D4, "Ayothaya Dungeon",D5, "Beach Dungeon",D6,
|
||||
"Bifrost Tower",D7, "Bio Labs",D8, "Brasilis Dungeon",D9,
|
||||
"Byalan Dungeon",D10, "Clock Tower",D11, "Coal Mines",D12,
|
||||
"Culvert",D13, "Cursed Abbey",D14, "Dewata Dungeon",D15,
|
||||
"Einbroch Dungeon",D16, "Flame Basin",D17, "Gefenia",D18,
|
||||
"Geffen Dungeon",D19, "Glast Heim",D20, "Hidden Dungeon",D21,
|
||||
"Ice Dungeon",D22, "Illusion Dungeon",D23, "Issgard Dungeon",D24,
|
||||
"Juperos",D25, "Kiel Dungeon",D26, "Kunlun Dungeon",D27,
|
||||
"Lasagna Dungeon",D28, "Luoyang Dungeon",D29, "Magma Dungeon",D30,
|
||||
"Malangdo Dungeon",D31, "Moscovia Dungeon",D32, "Nidhogg's Dungeon",D33,
|
||||
"Niflheim Dungeon",D34, "Odin Temple",D35, "Orc Dungeon",D36,
|
||||
"Oz Labyrinth Dungeon",D37, "Payon Dungeon",D38, "Prontera Underground",D39,
|
||||
"Pyramids",D40, "Rachel Sanctuary",D41, "Rock Ridge Dungeon",D42,
|
||||
"Rudus Dungeon",D43, "Scaraba Hole",D44, "Sphinx",D45,
|
||||
"Sunken Ship",D46, "Thanatos Tower",D47, "Thor Volcano",D48,
|
||||
"Toy Factory",D49, "Turtle Dungeon",D50, "Umbala Dungeon",D51,
|
||||
"Varmundt's Dungeon",D52, "Verus Area",D53;
|
||||
|
||||
D1: setarray @c[2],261,272,275,270,116,27;
|
||||
Disp("Abyss Lakes",1,3); Pick("abyss_");
|
||||
D2: setarray @c[2],228,11,34,41,119,14;
|
||||
D1: Restrict("RE");
|
||||
setarray @c[2],253,244,145,278;
|
||||
Disp("1st Floor - Comprehensive Lab:2nd Floor - Intensive Culture Room"); Pick("","amicitia1","amicitia2");
|
||||
D2: Restrict("RE",4);
|
||||
setarray @c[2],261,272,275,270,116,27,169,159;
|
||||
Disp("Abyss Lakes",1,4); Pick("abyss_");
|
||||
D3: setarray @c[2],228,11,34,41,119,14;
|
||||
Disp("Amatsu Dungeon",1,3); Pick("ama_dun");
|
||||
D3: setarray @c[2],35,262,168,170;
|
||||
D4: setarray @c[2],35,262,168,170;
|
||||
Disp("Anthell",1,2); Pick("anthell");
|
||||
D4: setarray @c[2],275,19,24,26;
|
||||
D5: setarray @c[2],275,19,24,26;
|
||||
Disp("Ancient Shrine Maze:Inside Ancient Shrine"); Pick("ayo_dun");
|
||||
D5: setarray @c[2],266,67,255,244,23,260;
|
||||
D6: setarray @c[2],266,67,255,244,23,260;
|
||||
Disp("Beach Dungeon",1,3); Pick("","beach_dun","beach_dun2","beach_dun3");
|
||||
D6: Restrict("RE",4);
|
||||
setarray @c[2],150,288,150,18,140,134,244,52;
|
||||
Disp("Bio Lab",1,4); Pick("lhz_dun");
|
||||
D7: Restrict("RE");
|
||||
setarray @c[2],57,13,64,88,45,14,26,23;
|
||||
Disp("Bifrost Tower",1,4); Pick("ecl_tdun");
|
||||
D8: Restrict("RE",4,5);
|
||||
setarray @c[2],150,288,150,18,140,134,244,52,100,202;
|
||||
Disp("Bio Lab 1:Bio Lab 2:Bio Lab 3:Bio Lab 4:Tomb of the Fallen"); Pick("","lhz_dun01","lhz_dun02","lhz_dun03","lhz_dun04","lhz_dun_n");
|
||||
D9: Restrict("RE");
|
||||
setarray @c[2],87,47,262,262;
|
||||
Disp("Brasilis Dungeon",1,2); Pick("bra_dun");
|
||||
D8: Restrict("RE",6);
|
||||
setarray @c[0],168,168,253,252,236,204,32,63,26,27,141,187;
|
||||
Disp("Byalan Dungeon",1,6); Pick("iz_dun",1);
|
||||
D9: setarray @c[2],199,159,148,283,65,147,56,155,297,25,127,169,277,178,268,74;
|
||||
Disp("Clock Tower 1:Clock Tower 2:Clock Tower 3:Clock Tower 4:Basement 1:Basement 2:Basement 3:Basement 4");
|
||||
Pick("","c_tower1","c_tower2","c_tower3","c_tower4","alde_dun01","alde_dun02","alde_dun03","alde_dun04");
|
||||
D10: setarray @c[2],52,17,381,343,302,262;
|
||||
D10: Restrict("RE",6);
|
||||
setarray @c[0],168,168,253,252,236,204,32,63,26,27,141,187;
|
||||
Disp("Byalan Dungeon",1,6); Pick("iz_dun",1);
|
||||
D11: Restrict("RE",9,10,11);
|
||||
setarray @c[2],199,159,148,283,65,147,56,155,297,25,127,169,277,178,268,74,266,27,60,142,79,39;
|
||||
Disp("Clock Tower 1:Clock Tower 2:Clock Tower 3:Clock Tower 4:Basement 1:Basement 2:Basement 3:Basement 4:Nightmare Clock Tower, 2nd Floor:Nightmare Clock Tower, 3rd Floor:Unknown Basement");
|
||||
Pick("","c_tower1","c_tower2","c_tower3","c_tower4","alde_dun01","alde_dun02","alde_dun03","alde_dun04","c_tower2_","c_tower3_","clock_01");
|
||||
D12: setarray @c[2],52,17,381,343,302,262;
|
||||
Disp("Coal Mines",1,3); Pick("mjo_dun");
|
||||
D11: setarray @c[2],131,247,19,19,180,169,100,92;
|
||||
D13: setarray @c[2],131,247,19,19,180,169,100,92;
|
||||
Disp("Culvert",1,4); Pick("","prt_sewb1","prt_sewb2","prt_sewb3","prt_sewb4");
|
||||
D12: setarray @c[2],51,14,150,11,120,10;
|
||||
D14: setarray @c[2],51,14,150,11,120,10;
|
||||
Disp("Cursed Abbey",1,3); Pick("abbey");
|
||||
D13: Restrict("RE");
|
||||
D15: Restrict("RE");
|
||||
setarray @c[2],285,160,299,29;
|
||||
Disp("Dewata Dungeon",1,2); Pick("dew_dun");
|
||||
D14: setarray @c[2],22,14,292,290;
|
||||
Disp("Einbroch Dungeon",1,2); Pick("ein_dun");
|
||||
D15: setarray @c[2],40,103,203,34,266,168,130,272;
|
||||
D16: Restrict("RE",3);
|
||||
setarray @c[2],22,14,292,290,269,279;
|
||||
Disp("Einbroch Dungeon",1,3); Pick("ein_dun");
|
||||
D17: Restrict("RE");
|
||||
Go("moro_vol",97,107);
|
||||
D18: setarray @c[2],40,103,203,34,266,168,130,272;
|
||||
Disp("Gefenia",1,4); Pick("gefenia",0);
|
||||
D16: setarray @c[0],104,99,115,236,106,132,203,200;
|
||||
D19: setarray @c[0],104,99,115,236,106,132,203,200;
|
||||
Disp("Geffen Dungeon",1,4); Pick("gef_dun",1);
|
||||
D17: setarray @c[2],370,304,199,29,104,25,150,15,157,287,147,15,258,255,108,291,171,283,68,277,156,7,12,7,133,271,224,274,14,70,150,14;
|
||||
Disp("Entrance:Castle 1:Castle 2:Chivalry 1:Chivalry 2:Churchyard:Culvert 1:Culvert 2:Culvert 3:Culvert 4:St. Abbey:Staircase Dungeon:Underground Cave 1:Underground Cave 2:Underground Prison 1:Underground Prison 2");
|
||||
Pick("","glast_01","gl_cas01","gl_cas02","gl_knt01","gl_knt02","gl_chyard","gl_sew01","gl_sew02","gl_sew03","gl_sew04","gl_church","gl_step","gl_dun01","gl_dun02","gl_prison","gl_prison1");
|
||||
D18: setarray @c[2],153,53,28,113,68,16;
|
||||
Disp("Kunlun Dungeon",1,3); Pick("gon_dun");
|
||||
D19: setarray @c[2],176,7,93,20,23,8;
|
||||
D20: Restrict("RE",17,18,19);
|
||||
setarray @c[2],370,304,199,29,104,25,150,15,157,287,147,15,258,255,108,291,171,283,68,277,156,7,12,7,133,271,224,274,14,70,150,14,104,31,148,144,199,29;
|
||||
Disp("Entrance:Castle 1:Castle 2:Chivalry 1:Chivalry 2:Churchyard:Culvert 1:Culvert 2:Culvert 3:Culvert 4:St. Abbey:Staircase Dungeon:Underground Cave 1:Underground Cave 2:Underground Prison 1:Underground Prison 2:Castle 2 - Nightmare Mode:Churchyard - Nightmare Mode:Abyss Glastheim Castle F1");
|
||||
Pick("","glast_01","gl_cas01","gl_cas02","gl_knt01","gl_knt02","gl_chyard","gl_sew01","gl_sew02","gl_sew03","gl_sew04","gl_church","gl_step","gl_dun01","gl_dun02","gl_prison","gl_prison1","gl_cas02_","gl_chyard_","gl_cas01_");
|
||||
D21: setarray @c[2],99,31,93,20,182,88;
|
||||
Disp("Hidden Dungeon",1,3); Pick("prt_maze");
|
||||
D20: setarray @c[2],157,14,151,155,149,22,33,158;
|
||||
D22: setarray @c[2],157,14,151,155,149,22,33,158;
|
||||
Disp("Ice Dungeon",1,4); Pick("ice_dun");
|
||||
D21: setarray @c[2],140,51,53,247,37,63,150,285;
|
||||
Disp("Entrance:Juperos 1:Juperos 2:Core");
|
||||
Pick("","jupe_cave","juperos_01","juperos_02","jupe_core");
|
||||
D22: setarray @c[2],28,226,41,198;
|
||||
D23: menu "Illusion of Abyss",SubD1, "Illusion of Frozen",SubD2, "Illusion of Labyrinth",SubD3,
|
||||
"Illusion of Luanda",SubD4, "Illusion of Moonlight",SubD5, "Illusion of Teddy Bear",SubD6,
|
||||
"Illusion of Twins",SubD7, "Illusion of Underwater",SubD8, "Illusion of Vampire",SubD9;
|
||||
SubD1: Restrict("RE");
|
||||
setarray @c[2],132,189,100,192;
|
||||
Disp("Desolate Village:Bleak Turtle Palace"); Pick("","tur_d03_i","tur_d04_i");
|
||||
SubD2: Restrict("RE");
|
||||
Go("ice_d03_i",149,22);
|
||||
SubD3: Restrict("RE");
|
||||
Go("prt_mz03_i",100,100);
|
||||
SubD4: Restrict("RE");
|
||||
Go("com_d02_i",250,245);
|
||||
SubD5: Restrict("RE");
|
||||
Go("pay_d03_i",140,44);
|
||||
SubD6: Restrict("RE");
|
||||
Go("ein_d02_i",164,184);
|
||||
SubD7: Restrict("RE");
|
||||
Go("ant_d02_i",168,170);
|
||||
SubD8: Restrict("RE");
|
||||
setarray @c[2],130,230,141,188;
|
||||
Disp("Deep Sea Cave",1,2); Pick("","iz_d04_i","iz_d05_i");
|
||||
SubD9: Restrict("RE");
|
||||
Go("gef_d01_i",114,216);
|
||||
D24: Restrict("RE");
|
||||
setarray @c[2],112,15,280,87,112,12,274,85;
|
||||
Disp("Abandoned Pit Floor 1:Abandoned Pit Floor 2:Snake God's Warmth 1st Floor:Snake God's Warmth 2nd Floor"); Pick("","jor_ab01","jor_ab02","jor_dun01","jor_dun02");
|
||||
D25: Restrict("RE",5);
|
||||
setarray @c[2],140,51,53,247,37,63,150,285,146,215;
|
||||
Disp("Entrance:Juperos 1:Juperos 2:Core:Eastern Ruins of Juperos");
|
||||
Pick("","jupe_cave","juperos_01","juperos_02","jupe_core","ver_eju");
|
||||
D26: setarray @c[2],28,226,41,198;
|
||||
Disp("Kiel Dungeon",1,2); Pick("kh_dun");
|
||||
D23: Restrict("RE");
|
||||
D27: setarray @c[2],153,53,28,113,68,16;
|
||||
Disp("Kunlun Dungeon",1,3); Pick("gon_dun");
|
||||
D28: Restrict("RE");
|
||||
setarray @c[2],24,143,22,171,190,18;
|
||||
Disp("Lasagna Dungeon",1,3); Pick("lasa_dun");
|
||||
D24: setarray @c[2],218,196,282,20,165,38;
|
||||
D29: setarray @c[2],218,196,282,20,165,38;
|
||||
Disp("The Royal Tomb:Inside the Royal Tomb:Suei Long Gon"); Pick("lou_dun");
|
||||
D25: setarray @c[2],126,68,47,30;
|
||||
Disp("Magma Dungeon",1,2); Pick("mag_dun");
|
||||
D26: Restrict("RE");
|
||||
D30: Restrict("RE",3);
|
||||
setarray @c[2],126,68,47,30,118,113;
|
||||
Disp("Magma Dungeon",1,3); Pick("mag_dun");
|
||||
D31: Restrict("RE");
|
||||
setarray @c[2],33,230;
|
||||
Disp("Malangdo Dungeon",1,1); Pick("mal_dun");
|
||||
D27: setarray @c[2],189,48,165,30,32,135;
|
||||
D32: setarray @c[2],189,48,165,30,32,135;
|
||||
Disp("Moscovia Dungeon",1,3); Pick("mosk_dun");
|
||||
D28: setarray @c[2],61,239,60,271;
|
||||
D33: setarray @c[2],61,239,60,271;
|
||||
Disp("Nidhogg's Dungeon",1,2); Pick("nyd_dun");
|
||||
D29: setarray @c[2],298,167,224,149,266,280;
|
||||
Disp("Odin Temple",1,3); Pick("odin_tem");
|
||||
D30: setarray @c[2],32,170,21,185;
|
||||
D34: Restrict("RE");
|
||||
setarray @c[2],145,90,150,20;
|
||||
Disp("Niflheim Dungeon - 1st Floor:Niflheim Dungeon - 2nd Floor"); Pick("nif_dun");
|
||||
D35: Restrict("RE",4);
|
||||
setarray @c[2],298,167,224,149,266,280,276,236;
|
||||
Disp("Odin Temple 1:Odin Temple 2:Odin Temple 3:Odin Past"); Pick("","odin_tem01","odin_tem02","odin_tem03","odin_past");
|
||||
D36: setarray @c[2],32,170,21,185;
|
||||
Disp("Orc Dungeon",1,2); Pick("orcsdun");
|
||||
D31: setarray @c[0],21,183,19,33,19,63,155,159,201,204;
|
||||
D37: Restrict("RE");
|
||||
setarray @c[2],21,191,141,277;
|
||||
Disp("Oz Labyrinth Floor 1:Oz Labyrinth Floor 2"); Pick("oz_dun");
|
||||
D38: setarray @c[0],21,183,19,33,19,63,155,159,201,204;
|
||||
Disp("Payon Dungeon",1,5); Pick("pay_dun",1);
|
||||
D32: Restrict("RE",7,8);
|
||||
D39: Restrict("RE");
|
||||
setarray @c[2],159,289,155,353;
|
||||
Disp("Prontera Underground Prison:Prontera Invasion"); Pick("","prt_prison","prt_q");
|
||||
D40: Restrict("RE",7,8);
|
||||
setarray @c[2],192,9,10,192,100,92,181,11,94,96,192,8,94,96,192,8;
|
||||
Disp("Pyramids 1:Pyramids 2:Pyramids 3:Pyramids 4:Basement 1:Basement 2:Basement 1 - Nightmare Mode:Basement 2 - Nightmare Mode");
|
||||
Pick("","moc_pryd01","moc_pryd02","moc_pryd03","moc_pryd04","moc_pryd05","moc_pryd06","moc_prydn1","moc_prydn2");
|
||||
D33: setarray @c[2],140,11,32,21,8,149,204,218,150,9;
|
||||
D41: setarray @c[2],140,11,32,21,8,149,204,218,150,9;
|
||||
Disp("Rachel Sanctuary",1,5); Pick("ra_san");
|
||||
D34: Restrict("RE");
|
||||
setarray @c[2],364,44,101,141;
|
||||
Disp("Scaraba Hole",1,2); Pick("dic_dun");
|
||||
D35: setarray @c[2],288,9,149,81,210,54,10,222,100,99;
|
||||
D42: Restrict("RE");
|
||||
setarray @c[2],247,19,281,104;
|
||||
Disp("Rock Ridge Mine:Underground Waterway Culvert"); Pick("","rockmi1","harboro2");
|
||||
D43: Restrict("RE");
|
||||
setarray @c[2],200,377,185,258,366,207,378,178;
|
||||
Disp("Rudus Dungeon",1,4); Pick("","sp_rudus","sp_rudus2","sp_rudus3","sp_rudus4");
|
||||
D44: Restrict("RE");
|
||||
setarray @c[2],364,44,101,141,101,141;
|
||||
Disp("Scaraba Hole",1,3); Pick("dic_dun");
|
||||
D45: setarray @c[2],288,9,149,81,210,54,10,222,100,99;
|
||||
Disp("Sphinx",1,5); Pick("","in_sphinx1","in_sphinx2","in_sphinx3","in_sphinx4","in_sphinx5");
|
||||
D36: setarray @c[2],69,24,102,27;
|
||||
D46: setarray @c[2],69,24,102,27;
|
||||
Disp("Sunken Ship",1,2); Pick("treasure");
|
||||
D37: setarray @c[2],150,39,150,136,220,158,59,143,62,11,89,221,35,166,93,148,29,107,159,138,19,20,130,52;
|
||||
D47: setarray @c[2],150,39,150,136,220,158,59,143,62,11,89,221,35,166,93,148,29,107,159,138,19,20,130,52;
|
||||
Disp("Thanatos Tower",1,12); Pick("tha_t");
|
||||
D38: setarray @c[2],21,228,75,205,34,272;
|
||||
D48: setarray @c[2],21,228,75,205,34,272;
|
||||
Disp("Thor Volcano",1,3); Pick("thor_v");
|
||||
D39: setarray @c[2],205,15,129,133;
|
||||
D49: setarray @c[2],205,15,129,133;
|
||||
Disp("Toy Factory",1,2); Pick("xmas_dun");
|
||||
D40: setarray @c[2],154,49,148,261,132,189,100,192;
|
||||
D50: setarray @c[2],154,49,148,261,132,189,100,192;
|
||||
Disp("Entrance:Turtle Dungeon 1:Turtle Dungeon 2:Turtle Dungeon 3"); Pick("tur_dun");
|
||||
D41: Restrict("Pre-RE",1,2);
|
||||
D51: Restrict("Pre-RE",1,2);
|
||||
setarray @c[2],42,31,48,30,204,78;
|
||||
Disp("Carpenter's Shop in the Tree:Passage to a Foreign World:Hvergermil's Fountain");
|
||||
Pick("","um_dun01","um_dun02","yggdrasil01");
|
||||
D42: Restrict("RE");
|
||||
setarray @c[2],57,13,64,88,45,14,26,23;
|
||||
Disp("Bifrost Tower",1,4); Pick("ecl_tdun");
|
||||
D52: Restrict("RE");
|
||||
setarray @c[2],275,21,15,115,15,115,159,27,162,36,159,11,156,33,337,333,314,64,163,18,156,20,39,81;
|
||||
Disp("Sewage Treatment Plant:1st Power Plant:2nd Power Plant:Large Bath Meditathio:Lost Farm Valley:Library Memory Corridor:Upper Floor of Tartaros Storage:Lower Floor of Tartaros Storage:Death Rune:Fire Rune:Grass Rune:Ice Rune"); Pick("","ba_pw02","ba_pw01","ba_pw03","ba_bath","ba_lost","ba_lib","ba_2whs01","ba_2whs02","bl_death","bl_lava","bl_grass","bl_ice");
|
||||
D53: Restrict("RE");
|
||||
setarray @c[2],244,61,72,20,122,22;
|
||||
Disp("Lab-OPTATIO:R&D-WISH:Verus Center Square"); Pick("verus");
|
||||
|
||||
// --------------------------------------------------
|
||||
Castles:
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
//===== rAthena Script =======================================
|
||||
//= Cash Hair Stylist
|
||||
//===== By: ==================================================
|
||||
//= Kisuka
|
||||
//===== Current Version: =====================================
|
||||
//= 1.0
|
||||
//===== Compatible With: =====================================
|
||||
//= rAthena Project
|
||||
//===== Description: =========================================
|
||||
//= Exchange cash item, New_Style_Coupon, for new hair styles.
|
||||
//===== Additional Comments: =================================
|
||||
//= 1.0 First Version. [Kisuka]
|
||||
//============================================================
|
||||
|
||||
itemmall,19,74,5 script Stylist#cash 91,{
|
||||
mes "[Stylist]";
|
||||
mes "Hey, I'm Kaniki.";
|
||||
mes "I'm here to start a new";
|
||||
mes "trend by introducing my";
|
||||
mes "special new hairstyles!";
|
||||
mes "Give me a ^FF0000New Style Coupon^000000,";
|
||||
mes "and I'll change your hair~";
|
||||
next;
|
||||
if (Sex == SEX_MALE) {
|
||||
mes "[Kaniki]";
|
||||
mes "I have two special";
|
||||
mes "hairstyles for men, the";
|
||||
mes "Emergency Heal Perm";
|
||||
mes "and the Aura Blade Cut.";
|
||||
mes "and aura blade cut.";
|
||||
next;
|
||||
cutin "hair_m_24.bmp",4;
|
||||
mes "[Kaniki]";
|
||||
mes "This is the Emergency";
|
||||
mes "Heal Perm. It's a brand";
|
||||
mes "new style I invented recently.";
|
||||
mes "What do you think? Cool, huh?";
|
||||
next;
|
||||
cutin "",255;
|
||||
cutin "hair_m_25.bmp",4;
|
||||
mes "[Kaniki]";
|
||||
mes "Now this is the Aura";
|
||||
mes "Blade Cut. You haven't";
|
||||
mes "seen anything like it";
|
||||
mes "before, haven't you?";
|
||||
next;
|
||||
cutin "",255;
|
||||
}else{
|
||||
mes "[Kaniki]";
|
||||
mes "I have two new hairstyles for";
|
||||
mes "women, the Assumptio Perm";
|
||||
mes "and the Soul Changer Cut.";
|
||||
mes "Do you want to see how";
|
||||
mes "these styles look?";
|
||||
next;
|
||||
cutin "hair_f_24.bmp",4;
|
||||
mes "[Kaniki]";
|
||||
mes "This is the Assumptio";
|
||||
mes "Perm. It'd really good";
|
||||
mes "on you, wouldn't it?";
|
||||
next;
|
||||
cutin "",255;
|
||||
cutin "hair_f_25.bmp",4;
|
||||
mes "[Kaniki]";
|
||||
mes "Next is the Soul";
|
||||
mes "Changer Cut. What do";
|
||||
mes "you think? Isn't it nice?";
|
||||
next;
|
||||
cutin "",255;
|
||||
}
|
||||
mes "[Kaniki]";
|
||||
mes "Have you decided";
|
||||
mes "if you'd like me to";
|
||||
mes "change your hairstyle?";
|
||||
next;
|
||||
if(select("Change Hairstyle:Don't Change") == 1) {
|
||||
if (countitem(7622) > 0) {
|
||||
mes "[Kaniki]";
|
||||
mes "Great, you brought";
|
||||
mes "a New Style Coupon!";
|
||||
mes "Alright, which hairstyle";
|
||||
mes "did you want to have?";
|
||||
next;
|
||||
if (Sex == SEX_MALE) {
|
||||
if(select("Emergency Heal Perm:Aura Blade Cut") == 1) {
|
||||
delitem 7622,1; // New_Style_Coupon
|
||||
setlook 1,24;
|
||||
}else{
|
||||
delitem 7622,1; // New_Style_Coupon
|
||||
setlook 1,25;
|
||||
}
|
||||
}else{
|
||||
if(select("Assumptio Perm:Soul Changer Cut") == 1) {
|
||||
delitem 7622,1; // New_Style_Coupon
|
||||
setlook 1,24;
|
||||
}else{
|
||||
delitem 7622,1; // New_Style_Coupon
|
||||
setlook 1,25;
|
||||
}
|
||||
}
|
||||
mes "[Kaniki]";
|
||||
mes "There--! It's done!";
|
||||
mes "How do you like your";
|
||||
mes "new hair? Well, I hope";
|
||||
mes "to see you again. Take care!";
|
||||
close;
|
||||
}else{
|
||||
mes "[Kaniki]";
|
||||
mes "I'm sorry, but I can";
|
||||
mes "only provide my hairstyling";
|
||||
mes "service if you bring a New";
|
||||
mes "Style Coupon. Please come";
|
||||
mes "back to me after you manage to";
|
||||
mes "get one of those coupons, okay?";
|
||||
close;
|
||||
}
|
||||
}
|
||||
mes "[Kaniki]";
|
||||
mes "Really? Oh, that's too bad.";
|
||||
mes "Well, if you ever change your";
|
||||
mes "mind about updating your";
|
||||
mes "hairstyle, come back";
|
||||
mes "and let me know, okay?";
|
||||
close;
|
||||
}
|
||||
@@ -14,7 +14,7 @@
|
||||
// nyd_dun01 - Yggdrasil Root Dungeon
|
||||
//==================================================
|
||||
nyd_dun01,0,0 monster Draco 2013,40
|
||||
nyd_dun01,0,0 monster Draco's Egg 2014,10,0,0,0
|
||||
nyd_dun01,0,0 monster Draco's Egg 2014,10
|
||||
nyd_dun01,0,0 monster Aqua Elemental 2016,20
|
||||
nyd_dun01,0,0 monster Dark Pinguicula 2015,10
|
||||
nyd_dun01,0,0 monster Rata 2017,2,900000
|
||||
|
||||
@@ -84,7 +84,7 @@ prt_maze03,50,150,70,70 monster Vagabond Wolf 1092,1,1920000,150000
|
||||
prt_maze03,170,170,70,70 monster Mantis 1139,30,60000,30000
|
||||
prt_maze03,170,170,70,70 monster Eclipse 1093,1,1920000,150000
|
||||
prt_maze03,23,23,70,70 monster Mastering 1090,1,1920000,150000
|
||||
prt_maze03,100,100,80,80 monster Baphomet Jr. 1101,25,0,0,0
|
||||
prt_maze03,100,100,80,80 monster Baphomet Jr. 1101,25
|
||||
prt_maze03,0,0,0,0 boss_monster Baphomet 1039,1,7200000,600000,1
|
||||
prt_maze03,61,98,10,10 monster Shining Plant 1083,1,1800000,900000
|
||||
prt_maze03,61,98,10,10 monster Blue Plant 1079,1,1800000,900000
|
||||
|
||||
@@ -391,3 +391,8 @@ que_thr mapflag nobranch
|
||||
// Sunken Tower
|
||||
//============================================================
|
||||
1@ch_u mapflag nobranch
|
||||
|
||||
//============================================================
|
||||
// Cash Mall
|
||||
//============================================================
|
||||
itemmall mapflag nobranch
|
||||
|
||||
@@ -486,3 +486,8 @@ wolfvill mapflag nomemo
|
||||
// Illusion of Twins
|
||||
//============================================================
|
||||
ant_d02_i mapflag nomemo
|
||||
|
||||
//============================================================
|
||||
// Cash Mall
|
||||
//============================================================
|
||||
itemmall mapflag nomemo
|
||||
|
||||
@@ -107,3 +107,8 @@ lasa_in01 mapflag nopenalty
|
||||
conch_in mapflag nopenalty
|
||||
|
||||
wolfvill mapflag nopenalty
|
||||
|
||||
//============================================================
|
||||
// Cash Mall
|
||||
//============================================================
|
||||
itemmall mapflag nopenalty
|
||||
|
||||
@@ -122,3 +122,8 @@ ecl_hub01 mapflag pvp off
|
||||
que_avan01 mapflag pvp off
|
||||
dali mapflag pvp off
|
||||
wolfvill mapflag pvp off
|
||||
|
||||
//============================================================
|
||||
// Cash Mall
|
||||
//============================================================
|
||||
itemmall mapflag pvp off
|
||||
|
||||
@@ -446,3 +446,9 @@ que_thr mapflag noteleport
|
||||
1@ch_u mapflag noteleport
|
||||
1@ch_u mapflag monster_noteleport
|
||||
1@ch_u mapflag monster_noteleport
|
||||
|
||||
//============================================================
|
||||
// Cash Mall
|
||||
//============================================================
|
||||
itemmall mapflag noteleport
|
||||
itemmall mapflag monster_noteleport
|
||||
|
||||
@@ -54,3 +54,4 @@ Footer:
|
||||
- Path: npc/re/merchants/barters/quests_17_1.yml
|
||||
- Path: npc/re/merchants/barters/refine.yml
|
||||
- Path: npc/re/merchants/barters/enchantgrade.yml
|
||||
- Path: npc/re/merchants/barters/cashmall.yml
|
||||
|
||||
1039
npc/re/merchants/barters/cashmall.yml
Normal file
1039
npc/re/merchants/barters/cashmall.yml
Normal file
File diff suppressed because it is too large
Load Diff
331
npc/re/merchants/cashmall.txt
Normal file
331
npc/re/merchants/cashmall.txt
Normal file
@@ -0,0 +1,331 @@
|
||||
//===== rAthena Script =======================================
|
||||
//= Cash Mall
|
||||
//===== Changelogs: ==========================================
|
||||
//= 1.0 Initial version from replays. [Lemongrass]
|
||||
//= 1.1 Cash Hair Stylist [Kisuka]
|
||||
//= 1.2 Updated Hair Stylist [Lemongrass]
|
||||
//============================================================
|
||||
|
||||
prontera,137,125,4 script Cash Sales Guide#prontera::cashmall_warper 4_M_HUMAN_02,{
|
||||
mes "[Guide]";
|
||||
mes "Hello~";
|
||||
mes "This guide wants to be the one to take you to a special place.";
|
||||
mes "What kind of place is that?";
|
||||
next;
|
||||
mes "[Guide]";
|
||||
mes "It's a place full of mysterious items to collect and sell.";
|
||||
mes "To buy stuff there you need special money.";
|
||||
next;
|
||||
mes "[Guide]";
|
||||
mes "So, are you ready to go there?";
|
||||
next;
|
||||
if (select( "Yes", "No" ) == 2) {
|
||||
mes "[Guide]";
|
||||
mes "Okay~";
|
||||
mes "But don't get frustrated.";
|
||||
mes "There's always more chances~";
|
||||
close;
|
||||
}
|
||||
mes "[Guide]";
|
||||
mes "Yeah~ You're really ready.";
|
||||
mes "Well then, get some good stuff~";
|
||||
mes "Oops, I forgot. When you come out be sure to come back here.";
|
||||
mes "Rember this~";
|
||||
close2;
|
||||
setarray .@maparray$[0], "prontera", "morocc", "moc_ruins", "geffen", "payon", "lighthalzen", "rachel";
|
||||
.@return = inarray(.@maparray$[0], strcharinfo(3));
|
||||
|
||||
if (.@return > 0)
|
||||
cashmall_return = .@return;
|
||||
else // Default to Prontera if not found
|
||||
cashmall_return = 0;
|
||||
|
||||
warp "itemmall",22,43;
|
||||
end;
|
||||
}
|
||||
morocc,164,39,4 duplicate(cashmall_warper) Cash Sales Guide#morocc 4_M_HUMAN_02
|
||||
moc_ruins,115,143,4 duplicate(cashmall_warper) Cash Sales Guide#moc_ruins 4_M_HUMAN_02
|
||||
geffen,115,168,4 duplicate(cashmall_warper) Cash Sales Guide#geffen 4_M_HUMAN_02
|
||||
payon,164,157,4 duplicate(cashmall_warper) Cash Sales Guide#payon 4_M_HUMAN_02
|
||||
lighthalzen,206,144,4 duplicate(cashmall_warper) Cash Sales Guide#lighthalzen 4_M_HUMAN_02
|
||||
rachel,128,144,4 duplicate(cashmall_warper) Cash Sales Guide#rachel 4_M_HUMAN_02
|
||||
|
||||
itemmall,21,45,4 script Exit Guide#cashmall_exit 4_M_HUMAN_02,{
|
||||
mes "[Guide]";
|
||||
mes "Have you had a good time?";
|
||||
mes "Thank you very much for using our item mall.";
|
||||
mes "We will continue to bring you valuable items.";
|
||||
next;
|
||||
mes "[Guide]";
|
||||
mes "Would you like to return from where you came from?";
|
||||
next;
|
||||
if (select( "Yes", "No" ) == 2) {
|
||||
mes "[Guide]";
|
||||
mes "There are still more things to see.";
|
||||
mes "Have a good time.";
|
||||
close;
|
||||
}
|
||||
mes "[Guide]";
|
||||
mes "Thank you for coming.";
|
||||
mes "I'll send you back from where you came from.";
|
||||
close2;
|
||||
switch(cashmall_return) {
|
||||
default:
|
||||
case 0:
|
||||
.@returnmap$ = "prontera";
|
||||
setarray .@xy[0],116,72;
|
||||
break;
|
||||
case 1:
|
||||
.@returnmap$ = "morocc";
|
||||
setarray .@xy[0],159,46;
|
||||
break;
|
||||
case 2:
|
||||
.@returnmap$ = "moc_ruins";
|
||||
setarray .@xy[0],109,137;
|
||||
break;
|
||||
case 3:
|
||||
.@returnmap$ = "geffen";
|
||||
setarray .@xy[0],120,38;
|
||||
break;
|
||||
case 4:
|
||||
.@returnmap$ = "payon";
|
||||
setarray .@xy[0],161,58;
|
||||
break;
|
||||
case 5:
|
||||
.@returnmap$ = "lighthalzen";
|
||||
setarray .@xy[0],159,95;
|
||||
break;
|
||||
case 6:
|
||||
.@returnmap$ = "rachel";
|
||||
setarray .@xy[0],115,125;
|
||||
break;
|
||||
}
|
||||
cashmall_return = 0;
|
||||
warp .@returnmap$,.@xy[0],.@xy[1];
|
||||
end;
|
||||
}
|
||||
|
||||
itemmall,41,53,3 script Cat Hand Salesman Macaroon#cashmall 4_M_MERCAT1,{
|
||||
mes "[Macaroon]";
|
||||
mes "Welcome!";
|
||||
mes "Today doesn't come every day!";
|
||||
mes "Things to see today~ Voila!";
|
||||
mes "You can only exchange with <ITEM>[[Kachua] Mileage Coupon]<INFO>1000274</INFO></ITEM>!";
|
||||
mes "Feel free to choose!";
|
||||
next;
|
||||
switch( select( "3-1st Job Group Skill Shadow", "3-2nd Job Group Skill Shadow", "Extended Job Group Skill Shadow", "General Shadow by Occupation", "Shadow Cube", "Smelting, Modification, Useful Items", "Drop Box", "Spellbook" ) ){
|
||||
case 1:
|
||||
mes "[Macaroon]";
|
||||
mes "^FF00663-1st Job Group Skill Shadow^000000 you say!";
|
||||
mes "Here they are!";
|
||||
close2;
|
||||
callshop "CachuaCoupon01";
|
||||
end;
|
||||
|
||||
case 2:
|
||||
mes "[Macaroon]";
|
||||
mes "^FF00663-2nd Job Group Skill Shadow^000000 you say!";
|
||||
mes "Here they are!";
|
||||
close2;
|
||||
callshop "CachuaCoupon02";
|
||||
end;
|
||||
|
||||
case 3:
|
||||
mes "[Macaroon]";
|
||||
mes "^FF0066Extended Job Group Skill Shadow^000000 you say!";
|
||||
mes "Here they are!";
|
||||
close2;
|
||||
callshop "CachuaCoupon03";
|
||||
end;
|
||||
|
||||
case 4:
|
||||
mes "[Macaroon]";
|
||||
mes "^FF0066General Shadow by Occupation^000000 you say!";
|
||||
mes "Here they are!";
|
||||
close2;
|
||||
callshop "CachuaCoupon04";
|
||||
end;
|
||||
|
||||
case 5:
|
||||
mes "[Macaroon]";
|
||||
mes "^FF0066Shadow Cube^000000 you say!";
|
||||
mes "Here they are!";
|
||||
close2;
|
||||
callshop "CachuaCoupon05";
|
||||
end;
|
||||
|
||||
case 6:
|
||||
mes "[Macaroon]";
|
||||
mes "^FF0066Smelting, Modification, Useful Items^000000 you say!";
|
||||
mes "Here they are!";
|
||||
close2;
|
||||
callshop "CachuaCoupon06";
|
||||
end;
|
||||
|
||||
case 7:
|
||||
mes "[Macaroon]";
|
||||
mes "^FF0066Drop Box^000000 you say!";
|
||||
mes "Here they are!";
|
||||
close2;
|
||||
callshop "CachuaCoupon07";
|
||||
end;
|
||||
|
||||
case 8:
|
||||
mes "[Macaroon]";
|
||||
mes "^FF0066Spellbook^000000 you say!";
|
||||
mes "Here they are!";
|
||||
close2;
|
||||
callshop "CachuaCoupon08";
|
||||
end;
|
||||
}
|
||||
}
|
||||
|
||||
itemmall,24,77,4 script Blacksmith Basta#pr 4_M_DWARF,{
|
||||
if( !getbattleflag( "feature.refineui" ) ){
|
||||
end;
|
||||
}
|
||||
|
||||
mes "[Blacksmith Basta]";
|
||||
mes "I have taken over the work of Mighty Hammer, Brock and the Shadow Blacksmith. I will be busy from now on.";
|
||||
close2;
|
||||
refineui();
|
||||
end;
|
||||
}
|
||||
|
||||
itemmall,27,77,4 script Mighty Hammer#im 4_M_DWARF,{
|
||||
mes "[Blacksmith Mighty Hammer]";
|
||||
mes "If it is about refining, ask Basta. I am retired.";
|
||||
close;
|
||||
}
|
||||
|
||||
itemmall,24,74,5 script Blacksmith Brock#im 4_M_HUMAN_01,{
|
||||
mes "[Blacksmith Brock]";
|
||||
mes "I am retired now. If it is about refining, make a request to Basta over there.";
|
||||
close;
|
||||
}
|
||||
|
||||
itemmall,19,74,5 script Stylist#cash 91,{
|
||||
if( getbattleflag( "feature.stylist" ) ){
|
||||
mes "[Jeremy]";
|
||||
mes "Hello cutie~";
|
||||
mes "I would like you to call me Head Stylist Jeremy.";
|
||||
next;
|
||||
if( select( "Change style:End conversation" ) == 2 ){
|
||||
mes "[Jeremy]";
|
||||
mes "My shop is always open, so please come back anytime.";
|
||||
close;
|
||||
}
|
||||
close2;
|
||||
openstylist();
|
||||
end;
|
||||
}
|
||||
|
||||
mes "[Stylist]";
|
||||
mes "Hey, I'm Kaniki.";
|
||||
mes "I'm here to start a new";
|
||||
mes "trend by introducing my";
|
||||
mes "special new hairstyles!";
|
||||
mes "Give me a ^FF0000New Style Coupon^000000,";
|
||||
mes "and I'll change your hair~";
|
||||
next;
|
||||
if (Sex == SEX_MALE) {
|
||||
mes "[Kaniki]";
|
||||
mes "I have two special";
|
||||
mes "hairstyles for men, the";
|
||||
mes "Emergency Heal Perm";
|
||||
mes "and the Aura Blade Cut.";
|
||||
mes "and aura blade cut.";
|
||||
next;
|
||||
cutin "hair_m_24.bmp",4;
|
||||
mes "[Kaniki]";
|
||||
mes "This is the Emergency";
|
||||
mes "Heal Perm. It's a brand";
|
||||
mes "new style I invented recently.";
|
||||
mes "What do you think? Cool, huh?";
|
||||
next;
|
||||
cutin "",255;
|
||||
cutin "hair_m_25.bmp",4;
|
||||
mes "[Kaniki]";
|
||||
mes "Now this is the Aura";
|
||||
mes "Blade Cut. You haven't";
|
||||
mes "seen anything like it";
|
||||
mes "before, haven't you?";
|
||||
next;
|
||||
cutin "",255;
|
||||
}else{
|
||||
mes "[Kaniki]";
|
||||
mes "I have two new hairstyles for";
|
||||
mes "women, the Assumptio Perm";
|
||||
mes "and the Soul Changer Cut.";
|
||||
mes "Do you want to see how";
|
||||
mes "these styles look?";
|
||||
next;
|
||||
cutin "hair_f_24.bmp",4;
|
||||
mes "[Kaniki]";
|
||||
mes "This is the Assumptio";
|
||||
mes "Perm. It'd really good";
|
||||
mes "on you, wouldn't it?";
|
||||
next;
|
||||
cutin "",255;
|
||||
cutin "hair_f_25.bmp",4;
|
||||
mes "[Kaniki]";
|
||||
mes "Next is the Soul";
|
||||
mes "Changer Cut. What do";
|
||||
mes "you think? Isn't it nice?";
|
||||
next;
|
||||
cutin "",255;
|
||||
}
|
||||
mes "[Kaniki]";
|
||||
mes "Have you decided";
|
||||
mes "if you'd like me to";
|
||||
mes "change your hairstyle?";
|
||||
next;
|
||||
if (select( "Change Hairstyle", "Don't Change" ) == 2) {
|
||||
mes "[Kaniki]";
|
||||
mes "Really? Oh, that's too bad.";
|
||||
mes "Well, if you ever change your";
|
||||
mes "mind about updating your";
|
||||
mes "hairstyle, come back";
|
||||
mes "and let me know, okay?";
|
||||
close;
|
||||
}
|
||||
if (countitem(7622) < 1) {
|
||||
mes "[Kaniki]";
|
||||
mes "I'm sorry, but I can";
|
||||
mes "only provide my hairstyling";
|
||||
mes "service if you bring a New";
|
||||
mes "Style Coupon. Please come";
|
||||
mes "back to me after you manage to";
|
||||
mes "get one of those coupons, okay?";
|
||||
close;
|
||||
}
|
||||
mes "[Kaniki]";
|
||||
mes "Great, you brought";
|
||||
mes "a New Style Coupon!";
|
||||
mes "Alright, which hairstyle";
|
||||
mes "did you want to have?";
|
||||
next;
|
||||
if (Sex == SEX_MALE) {
|
||||
if(select("Emergency Heal Perm", "Aura Blade Cut") == 1) {
|
||||
delitem 7622,1; // New_Style_Coupon
|
||||
setlook 1,24;
|
||||
}else{
|
||||
delitem 7622,1; // New_Style_Coupon
|
||||
setlook 1,25;
|
||||
}
|
||||
}else{
|
||||
if(select("Assumptio Perm", "Soul Changer Cut") == 1) {
|
||||
delitem 7622,1; // New_Style_Coupon
|
||||
setlook 1,24;
|
||||
}else{
|
||||
delitem 7622,1; // New_Style_Coupon
|
||||
setlook 1,25;
|
||||
}
|
||||
}
|
||||
mes "[Kaniki]";
|
||||
mes "There--! It's done!";
|
||||
mes "How do you like your";
|
||||
mes "new hair? Well, I hope";
|
||||
mes "to see you again. Take care!";
|
||||
close;
|
||||
}
|
||||
@@ -12,11 +12,12 @@
|
||||
//===== Additional Comments: =================================
|
||||
//= 1.0 First version.
|
||||
//= 1.1 Standardizing, grammar and bug fixes. [Euphy]
|
||||
//= 1.2 Moved to Cash Mall [Lemongrass]
|
||||
//============================================================
|
||||
|
||||
// Main NPC :: 201105_luk_enc
|
||||
//============================================================
|
||||
prt_in,28,73,3 script Devil Enchant Master#prq 63,{
|
||||
itemmall,29,71,3 script Devil Enchant Master#prq 63,{
|
||||
disable_items;
|
||||
if (checkweight(1201,1) == 0) {
|
||||
mes "You are carrying too many items, please reduce it and come back again!";
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
//= 1.1 Removed re-roll behavior and fetch materials from db
|
||||
//= [Secret]
|
||||
//= 1.2 Added Refine UI [Atemo, Lemongrass]
|
||||
//= 1.3 Moved to Cash Mall [Lemongrass]
|
||||
//============================================================
|
||||
- script ::ShadowBlacksmith -1,{
|
||||
if( getbattleflag( "feature.refineui" ) ){
|
||||
@@ -163,4 +164,5 @@
|
||||
}
|
||||
|
||||
//moc_paraup,45,185,5 duplicate(ShadowBlacksmith) Shadow Blacksmith#eden1 4_F_JOB_BLACKSMITH // Commented out until it's added to the map index
|
||||
prt_in,61,54,3 duplicate(ShadowBlacksmith) Shadow Blacksmith#itemmall 4_F_JOB_BLACKSMITH
|
||||
//prt_in,61,54,3 duplicate(ShadowBlacksmith) Shadow Blacksmith#itemmall 4_F_JOB_BLACKSMITH
|
||||
itemmall,31,76,3 duplicate(ShadowBlacksmith) Shadow Blacksmith#itemmall 4_F_JOB_BLACKSMITH
|
||||
|
||||
@@ -184,11 +184,11 @@ gl_step,0,0 monster Mimic 1191,6,5000
|
||||
//==================================================
|
||||
// gl_cas02_ - Nightmare Mode 2f
|
||||
//==================================================
|
||||
gl_cas02_,0,0 monster Evil Druid (Nightmare) 2480,4,0,0,0
|
||||
gl_cas02_,0,0 monster Chimera (Nightmare) 2485,1,0,0,0
|
||||
gl_cas02_,0,0 monster Mimic (Nightmare) 2479,19,0,0,0
|
||||
gl_cas02_,0,0 monster Rideword (Nightmare) 2478,10,0,0,0
|
||||
gl_cas02_,0,0 monster Wanderer (Nightmare) 2477,60,0,0,0
|
||||
gl_cas02_,0,0 monster Evil Druid (Nightmare) 2480,4,5000
|
||||
gl_cas02_,0,0 monster Chimera (Nightmare) 2485,1,5000
|
||||
gl_cas02_,0,0 monster Mimic (Nightmare) 2479,19,5000
|
||||
gl_cas02_,0,0 monster Rideword (Nightmare) 2478,10,5000
|
||||
gl_cas02_,0,0 monster Wanderer (Nightmare) 2477,60,5000
|
||||
gl_cas02_,0,0 monster Mysteltainn 1203,1,7200000,3600000
|
||||
gl_cas02_,0,0 monster Alice 1275,1,5000
|
||||
gl_cas02_,102,180 monster Whisper 1185,1,1800000,900000
|
||||
@@ -197,8 +197,8 @@ gl_cas02_,0,0 monster Baphomet (Nightmare) 2483,1,7200000,0,0
|
||||
//==================================================
|
||||
// gl_chyard_ - Nightmare Mode Churchyard
|
||||
//==================================================
|
||||
gl_chyard_,0,0 monster Wraith Dead (Nightmare) 2481,91,0,0,0
|
||||
gl_chyard_,0,0 monster Wraith Dead 1291,31,0,0,0
|
||||
gl_chyard_,0,0 monster Wraith Dead (Nightmare) 2481,91,5000
|
||||
gl_chyard_,0,0 monster Wraith Dead 1291,31,5000
|
||||
gl_chyard_,0,0 monster Evil Druid (Nightmare) 2480,22,60000,0,0
|
||||
gl_chyard_,0,0 monster Mimic (Nightmare) 2479,34,60000,0,0
|
||||
gl_chyard_,0,0,0,0 boss_monster Dark Lord 1272,1,3600000,600000,1
|
||||
|
||||
@@ -22,3 +22,10 @@ sp_rudus3,0,0 monster Mutant Dolor 20362,60,5000
|
||||
sp_rudus3,0,0 monster Mutant Plaga 20360,53,5000
|
||||
sp_rudus3,0,0 monster Mutant Venenum 20364,65,5000
|
||||
sp_rudus3,0,0 monster Mutant Twin Caput 20366,65,5000
|
||||
|
||||
sp_rudus4 monster Giant Caput GIANT_CAPUT,75
|
||||
sp_rudus4 monster Dolorian DOLORIAN,75
|
||||
sp_rudus4 monster Deadre DEADRE,75
|
||||
sp_rudus4 monster Venedi VENEDI,75
|
||||
sp_rudus4 monster Plagarion PLAGARION,75
|
||||
sp_rudus4 boss_monster R001-Bestia R001_BESTIA,1,21600000,600000,0
|
||||
|
||||
@@ -10,28 +10,28 @@
|
||||
//============================================================
|
||||
|
||||
// ver_eju
|
||||
ver_eju,0,0,0,0 monster Recon Robot 3154,50,0,0,0
|
||||
ver_eju,0,0,0,0 monster Excavator Robot 3153,10,0,0,0
|
||||
ver_eju,0,0,0,0 monster Recon Robot 3154,50,5000
|
||||
ver_eju,0,0,0,0 monster Excavator Robot 3153,10,5000
|
||||
// ver_tunn
|
||||
ver_tunn,0,0,0,0 monster Recon Robot 3154,5,0,0,0
|
||||
ver_tunn,0,0,0,0 monster Recon Robot 3154,5,30000
|
||||
// verus01
|
||||
verus01,0,0,0,0 monster Green Cenere 3247,50,0,0,0
|
||||
verus01,0,0,0,0 monster Explorer Robot Turbo 3249,25,0,0,0
|
||||
verus01,0,0,0,0 monster Repair Robot Turbo 3248,25,0,0,0
|
||||
verus01,0,0,0,0 monster Green Cenere 3247,50,5000
|
||||
verus01,0,0,0,0 monster Explorer Robot Turbo 3249,25,5000
|
||||
verus01,0,0,0,0 monster Repair Robot Turbo 3248,25,5000
|
||||
// verus02
|
||||
verus02,0,0,0,0 monster Repair Robot Turbo 3248,50,0,0,0
|
||||
verus02,0,0,0,0 monster Explorer Robot Turbo 3249,50,0,0,0
|
||||
verus02,0,0,0,0 monster Repair Robot Turbo 3248,50,5000
|
||||
verus02,0,0,0,0 monster Explorer Robot Turbo 3249,50,5000
|
||||
// verus03
|
||||
verus03,0,0,0,0 monster Illegal Promotion 3159,40,0,0,0
|
||||
verus03,0,0,0,0 monster Explorer Robot 3156,50,0,0,0
|
||||
verus03,0,0,0,0 monster Repair Robot 3155,50,0,0,0
|
||||
verus03,0,0,0,0 monster Ruin Grace Believer 3158,10,0,0,0
|
||||
verus03,0,0,0,0 monster Illegal Promotion 3159,40,5000
|
||||
verus03,0,0,0,0 monster Explorer Robot 3156,50,5000
|
||||
verus03,0,0,0,0 monster Repair Robot 3155,50,5000
|
||||
verus03,0,0,0,0 monster Ruin Grace Believer 3158,10,5000
|
||||
// un_bunker
|
||||
un_bunker,0,0,0,0 monster Thief Bug 1051,6,0,0,0
|
||||
un_bunker,0,0,0,0 monster Smelly Ghoul 3255,68,0,0,0
|
||||
un_bunker,0,0,0,0 monster Smelly Zombie 3256,80,0,0,0
|
||||
un_bunker,0,0,0,0 monster Machine Component 3250,28,0,0,0
|
||||
un_bunker,0,0,0,0 monster DR815 3252,14,0,0,0
|
||||
un_bunker,0,0,0,0 monster GC109 3251,10,0,0,0
|
||||
un_bunker,0,0,0,0 monster Black Mushroom 1084,1,0,0,0
|
||||
un_bunker,0,0,0,0 monster Chonchon 1011,2,0,0,0
|
||||
un_bunker,0,0,0,0 monster Thief Bug 1051,6,5000
|
||||
un_bunker,0,0,0,0 monster Smelly Ghoul 3255,68,5000
|
||||
un_bunker,0,0,0,0 monster Smelly Zombie 3256,80,5000
|
||||
un_bunker,0,0,0,0 monster Machine Component 3250,28,5000
|
||||
un_bunker,0,0,0,0 monster DR815 3252,14,5000
|
||||
un_bunker,0,0,0,0 monster GC109 3251,10,5000
|
||||
un_bunker,0,0,0,0 monster Black Mushroom 1084,1,5000
|
||||
un_bunker,0,0,0,0 monster Chonchon 1011,2,5000
|
||||
|
||||
@@ -13,9 +13,11 @@
|
||||
//===== Additional Comments: =================================
|
||||
//= 1.0 First version, currently useless/disabled.
|
||||
//= 1.1 Implemented the 'mergeitem' script command. [Cydh]
|
||||
//= 1.2 Updated and moved to Cash Mall [Lemongrass]
|
||||
//============================================================
|
||||
|
||||
prontera,146,95,3 script Mergician#pron 64,{
|
||||
//prontera,146,95,3 script Mergician#pron 1_M_WIZARD,{
|
||||
itemmall,35,75,3 script Mergician#mall 1_M_WIZARD,{
|
||||
if (checkweight(1301,1) == 0) {
|
||||
mes "- Wait a second !! -";
|
||||
mes "- You are carrying too many items -";
|
||||
@@ -28,8 +30,8 @@ prontera,146,95,3 script Mergician#pron 64,{
|
||||
mes "Do you believe in the miracle of Merge god?? If so, repeat my spell loudly as I pronounce it!!!";
|
||||
mes "Merge Merge, Merrrrge!!!";
|
||||
next;
|
||||
switch(select("What is the miracle of Merge?:Merrrrge!!!!:Abandon...")) {
|
||||
case 1:
|
||||
switch(select("Merrrrge!!!!:What is the miracle of Merge?:Abandon...")) {
|
||||
case 2:
|
||||
mes "[Mergician]";
|
||||
mes "There is an order which rules the world and keeps the world to go well.";
|
||||
next;
|
||||
@@ -47,7 +49,7 @@ prontera,146,95,3 script Mergician#pron 64,{
|
||||
mes "Believe in Mergism. That is the truth.";
|
||||
mes "Then I can help you be happy and content.";
|
||||
close;
|
||||
case 2:
|
||||
case 1:
|
||||
mes "[Mergician]";
|
||||
mes "This is the total holy ritual to pray to the Great God, Merge! and I am borrowing the power for a while!!";
|
||||
next;
|
||||
|
||||
480
npc/re/quests/quests_dungeons_200.txt
Normal file
480
npc/re/quests/quests_dungeons_200.txt
Normal file
@@ -0,0 +1,480 @@
|
||||
//===== rAthena Script =======================================
|
||||
//= New dungeons
|
||||
//===== Description: =========================================
|
||||
//= [Walkthrough Conversion]
|
||||
//===== Changelog: ===========================================
|
||||
//= 1.0 Added sp_rudus4 quests. [Capuche]
|
||||
//============================================================
|
||||
|
||||
// sp_rudus4
|
||||
pub_cat,94,43,5 script Yulma#rudus4 4_F_ANYA,{
|
||||
if (BaseLevel < 200) {
|
||||
mes "[Yulma]";
|
||||
mes "Uh... who are you?";
|
||||
mes "Sorry, I'm not good at remembering people's faces! But I think you are not good enough to ask about my work here.";
|
||||
next;
|
||||
mes " - This is a quest that can be performed at level 200 or higher - ";
|
||||
close;
|
||||
}
|
||||
switch( isbegin_quest(16521) ) {
|
||||
case 0:
|
||||
emotion ET_SMILE;
|
||||
mes "[Yulma]";
|
||||
mes "Oh, " + strcharinfo(0) + ". Are you here for a drink?";
|
||||
mes "I just had a business, and it went well.";
|
||||
next;
|
||||
select( "What is it for?" );
|
||||
mes "[Yulma]";
|
||||
mes "You know that Secret Wing and our rebellion have been tracking the traces of Illusion's illegal experiments, right?";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "In the meantime, I found a way to the 4th floor of Rudus.";
|
||||
next;
|
||||
switch( select( "Well, I know.", "Where was Rudus?" ) ) {
|
||||
case 1:
|
||||
emotion ET_DELIGHT;
|
||||
mes "[Yulma]";
|
||||
mes "Hehe, it's good to have a good conversation with " + strcharinfo(0) + ".";
|
||||
break;
|
||||
case 2:
|
||||
emotion ET_SURPRISE;
|
||||
mes "[Yulma]";
|
||||
mes "What, how many times did you forget?";
|
||||
mes "It was the place where Illusion abandoned the failed works that were created after the experiment.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Remember Morning? Where the little boy stays.";
|
||||
mes "He is on the first floor, and Rudus itself exists on the second and third floors.";
|
||||
break;
|
||||
}
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "By the way, the 4th floor of Rudus is quite amazing...";
|
||||
mes "Somehow, among the test subjects abandoned in Rudus, only particularly strong ones seem to be gathered.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Researchers of the Secret Wing say that after fierce competition among the subjects, the strongest subjects seem to have settled there.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Well, actually, I'm not sure how complicated it is!";
|
||||
mes "It seems that the Secret Wing researchers need to study the entities there.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "So I was looking for someone to help me.";
|
||||
mes "To be precise you, " + strcharinfo(0) + "!";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Do you need a job? I know everything~";
|
||||
mes "If you have an idea, go to the 3rd floor of Rudus.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "<NAVI>[Pion]<INFO>sp_rudus3,380,42,0,101,0</INFO></NAVI> is in control of the path leading down to the fourth floor.";
|
||||
mes "Go and tell him I sent you, and find out if it's worth it to come!";
|
||||
setquest 16521;
|
||||
close2;
|
||||
navigateto("sp_rudus3",380,42);
|
||||
end;
|
||||
case 1:
|
||||
mes "[Yulma]";
|
||||
mes "Do you need a job? I know everything~";
|
||||
mes "If you have an idea, go to the 3rd floor of Rudus.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "<NAVI>[Pion]<INFO>sp_rudus3,380,42,0,101,0</INFO></NAVI> is in control of the path leading down to the fourth floor.";
|
||||
mes "Go and tell him I sent you, and find out if it's worth it to come!";
|
||||
close;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
if (isbegin_quest(16522) == 1) {
|
||||
mes "[Yulma]";
|
||||
mes "Oh, you went down to the 4th floor of Rudus. How was it?";
|
||||
mes "Is Pian doing well? Did the subjects feel a bit worthy of a fight?";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Then help me study the people from the Secret Wing.";
|
||||
mes "I was looking for someone to hunt them, because I was not enough to catch and research monsters myself.";
|
||||
next;
|
||||
select( "Ask if I can just hunt" );
|
||||
emotion ET_KEK;
|
||||
mes "[Yulma]";
|
||||
mes "Oh, I almost forgot.";
|
||||
mes "If you attach this chip somewhere on your body and hunt them, researchers can receive data.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "New material, eco-friendly, non-toxic, safe material, so you don't have to worry about it.";
|
||||
mes "Where would you like to hang it?";
|
||||
next;
|
||||
select( "Earlobe", "Back neck", "Back of hand", "Forehead" );
|
||||
mes "[Yulma]";
|
||||
mes "Okay, I'll attach it well so it doesn't bother you.";
|
||||
mes "Okay, that's it then...";
|
||||
completequest 16522;
|
||||
next;
|
||||
}
|
||||
mes "[Yulma]";
|
||||
mes "Please take good care of me today!";
|
||||
mes "So, what kind of research would you like to help with today?";
|
||||
next;
|
||||
switch( select("Abyssal Solitude", "Transformation and Evolution", "Data Backup", "Don't help" ) ) {
|
||||
case 1:
|
||||
switch( checkquest(16523,PLAYTIME) ) {
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
mes "[Yulma]";
|
||||
mes "Secret Wing researchers are resting.";
|
||||
mes "So, " + strcharinfo(0) + ", how about coming back after a little rest?";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "The 4th floor of Rudus is not a comfortable place to go in and out easily.";
|
||||
mes "Let's get some rest and work fully prepared!";
|
||||
close;
|
||||
case 2:
|
||||
erasequest 16523;
|
||||
break;
|
||||
}
|
||||
switch( checkquest(16524,HUNTING) ) {
|
||||
case -1:
|
||||
mes "[Yulma]";
|
||||
mes "A place where only strong individuals survive and bite weaker ones...";
|
||||
mes "Like a deep, dark pit of solitude.";
|
||||
next;
|
||||
emotion ET_SWEAT;
|
||||
mes "[Yulma]";
|
||||
mes "Well, I don't know about that!";
|
||||
mes "My job is to deliver the requests of researchers.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Researchers want to know how the subjects of Rudus differ from those distributed on the 4th floor.";
|
||||
next;
|
||||
emotion ET_PROFUSELY_SWAT;
|
||||
mes "[Yulma]";
|
||||
mes "How much more has it lost it's original form, and whether it has changed itself after the experiment.";
|
||||
mes "<FONT SIZE = 9>Um... these researchers look a little dangerous too? I think that's how all researchers are, to a person like me.</FONT>";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Anyway, you want to collect <FONT COLOR = 0000CD>Dolorian, Plagarion, and Deadre</FONT> data.";
|
||||
mes "What if we hunt 10 individuals each?";
|
||||
next;
|
||||
if (select( "I'll come hunting", "I refuse" ) == 2) {
|
||||
mes "[Yulma]";
|
||||
mes "We're already comrades on the same boat~?";
|
||||
mes "Isn't that right, comrade? Think again!";
|
||||
close;
|
||||
}
|
||||
mes "[Yulma]";
|
||||
mes "Okay, if you go hunting and from hunting, data will be gathered.";
|
||||
mes "And my allowance will be accumulating!";
|
||||
setquest 16524;
|
||||
close;
|
||||
case 0:
|
||||
case 1:
|
||||
mes "[Yulma]";
|
||||
mes "Secret Wing researchers want to collect <FONT COLOR = 0000CD>Dolorian, Plagarion, and Deadre</FONT> data.";
|
||||
mes "What if we hunt 10 individuals each?";
|
||||
close;
|
||||
case 2:
|
||||
mes "[Yulma]";
|
||||
mes "Today's hunting seems to be successful!";
|
||||
mes "How did you know, " + strcharinfo(0) + ", the chip I put on you worked today.";
|
||||
next;
|
||||
emotion ET_DELIGHT;
|
||||
mes "[Yulma]";
|
||||
mes "I see it every time, but every time it's amazing, how the chip works.";
|
||||
mes "Well, I should pay you for the work you did today.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Here you are!";
|
||||
mes "Then since you've finished your work, take a good rest. Please take care of me tomorrow as well~";
|
||||
erasequest 16524;
|
||||
setquest 16523;
|
||||
getexp 15915940,11141160; // TODO: the amount has been changed with the monster update
|
||||
close;
|
||||
}
|
||||
end;
|
||||
case 2:
|
||||
switch( checkquest(16525,PLAYTIME) ) {
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
mes "[Yulma]";
|
||||
mes "Secret Wing researchers left work already.";
|
||||
mes "So, " + strcharinfo(0) + ", how about coming back after a little rest?";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "The 4th floor of Rudus is not a comfortable place to go in and out easily.";
|
||||
mes "You too, get a good rest, and let's work fully prepared!";
|
||||
close;
|
||||
case 2:
|
||||
erasequest 16525;
|
||||
break;
|
||||
}
|
||||
switch( checkquest(16526,HUNTING) ) {
|
||||
case -1:
|
||||
mes "[Yulma]";
|
||||
mes "The 4th-floor entities Giant Caput and Venedi are greatly altered from the other-floor entities";
|
||||
mes "to become gigantic, or to harbor more venom...";
|
||||
next;
|
||||
emotion ET_PROFUSELY_SWAT;
|
||||
mes "[Yulma]";
|
||||
mes "Researchers seem to be very interested in these guys.";
|
||||
mes "That's why I ask you to hunt them.";
|
||||
mes "<FONT SIZE = 9>Um...why don't we do it? There must be something complicated at the upper level. I don't know.</FONT>";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Can you hunt 15 <FONT COLOR = 0000CD>Giant Caput and Venedi</FONT> each?";
|
||||
mes "Data will be collected automatically, so you just need to focus on hunting.";
|
||||
next;
|
||||
if (select( "I'll hunt them", "I refuse" ) == 2) {
|
||||
mes "[Yulma]";
|
||||
mes "We're already comrades on the same boat~?";
|
||||
mes "Isn't that right, comrade? Think again!";
|
||||
close;
|
||||
}
|
||||
mes "[Yulma]";
|
||||
mes "Okay, go and hunt hard!";
|
||||
mes "My bonus depends on your performance!";
|
||||
setquest 16526;
|
||||
close;
|
||||
case 0:
|
||||
case 1:
|
||||
mes "[Yulma]";
|
||||
mes "Can you hunt 15 <FONT COLOR = 0000CD>Giant Caput and Venedi</FONT> each?";
|
||||
mes "Data will be collected automatically, so you just need to focus on hunting.";
|
||||
close;
|
||||
case 2:
|
||||
mes "[Yulma]";
|
||||
mes "Have you been well? You came back from hunting safely.";
|
||||
mes "Please tell me that the researchers worked hard today.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Looks like good data has been gathered.";
|
||||
mes "Then I should pay you for the work you did today.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Here you are!";
|
||||
mes "You worked hard today, so get a good rest and come back. Let's work hard tomorrow!";
|
||||
erasequest 16526;
|
||||
setquest 16525;
|
||||
getexp 15176970,11001900; // TODO: the amount has been changed with the monster update
|
||||
close;
|
||||
}
|
||||
end;
|
||||
case 3:
|
||||
switch( checkquest(16527,PLAYTIME) ) {
|
||||
case -1:
|
||||
break;
|
||||
case 0:
|
||||
case 1:
|
||||
mes "[Yulma]";
|
||||
mes "The researcher said he's withdrawn now. Chip maintenance is enough once a day!";
|
||||
mes "So, " + strcharinfo(0) + ", how about coming back after a little rest?";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "The 4th floor of Rudus is not a comfortable place to go in and out easily.";
|
||||
mes "Let's get some rest and work fully prepared!";
|
||||
close;
|
||||
case 2:
|
||||
erasequest 16527;
|
||||
break;
|
||||
}
|
||||
switch( isbegin_quest(16528) ) {
|
||||
case 0:
|
||||
mes "[Yulma]";
|
||||
mes "Oh, by the way, are the chips sticking well?";
|
||||
mes "It doesn't last that long...";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "And I have to back up and format the data I have collected so that I can receive new data, but I don't have the talent to do that...";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "I'll introduce you to a researcher who is currently in the field, would you like to go directly?";
|
||||
mes "He is probably disguised to observe monsters, but I'll give you the location, so go check it out!";
|
||||
next;
|
||||
if (select( "Look for him", "Don't look for him" ) == 2) {
|
||||
mes "[Yulma]";
|
||||
mes "Isn't it frustrating to only work with me?";
|
||||
mes "It wouldn't be a bad idea to meet the researchers working in the field...";
|
||||
close;
|
||||
}
|
||||
mes "[Yulma]";
|
||||
mes "Yeah! Isn't it frustrating to only meet with me to get work delivered?";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "I'm on my way to see him, so if you have any questions, you can ask him directly!";
|
||||
mes "I heard that <NAVI>[Researcher]<INFO>sp_rudus4,192,204,0,101,0</INFO></NAVI> mostly burrows around the center of the 4th floor of Rudus.";
|
||||
setquest 16528;
|
||||
close;
|
||||
case 1:
|
||||
mes "[Yulma]";
|
||||
mes "I'm on my way to meet the Secret Wing researcher, so if you have any questions, you can ask him directly!";
|
||||
mes "I heard that <NAVI>[Researcher]<INFO>sp_rudus4,192,204,0,101,0</INFO></NAVI> mostly burrows around the center of the 4th floor of Rudus.";
|
||||
close;
|
||||
case 2:
|
||||
mes "[Yulma]";
|
||||
mes "Have you been there? Did you talk a bit?";
|
||||
mes "Is the researcher hiding well?";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "He's known for hiding very well, even though he doesn't have the skills to hide.";
|
||||
mes "That's why you're out in the field.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Because this is also a job... Since I safely replaced him, the superiors asked me to take care of the allowance.";
|
||||
next;
|
||||
mes "[Yulma]";
|
||||
mes "Well, it's good that you came back to me too!";
|
||||
mes "Then have a good day and see you tomorrow!";
|
||||
erasequest 16528;
|
||||
erasequest 16540;
|
||||
setquest 16527;
|
||||
getexp 15000000,11000000;
|
||||
close;
|
||||
}
|
||||
end;
|
||||
case 4:
|
||||
mes "[Yulma]";
|
||||
mes "Eh, won't you?";
|
||||
mes "I was eagerly waiting for " + strcharinfo(0) + "!";
|
||||
close;
|
||||
}
|
||||
end;
|
||||
|
||||
OnInit:
|
||||
questinfo( QTYPE_QUEST2, QMARK_YELLOW, "checkquest(16524,HUNTING) == 2" );
|
||||
questinfo( QTYPE_QUEST2, QMARK_YELLOW, "checkquest(16526,HUNTING) == 2" );
|
||||
questinfo( QTYPE_QUEST2, QMARK_YELLOW, "isbegin_quest(16528) == 2" );
|
||||
|
||||
questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(16523,PLAYTIME) == 2" );
|
||||
questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(16525,PLAYTIME) == 2" );
|
||||
questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "checkquest(16527,PLAYTIME) == 2" );
|
||||
|
||||
questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "BaseLevel >= 200 && (checkquest(16524,HUNTING) == -1 && checkquest(16523,PLAYTIME) == -1)" );
|
||||
questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "BaseLevel >= 200 && (checkquest(16526,HUNTING) == -1 && checkquest(16525,PLAYTIME) == -1)" );
|
||||
questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "BaseLevel >= 200 && (isbegin_quest(16528) == 0 && checkquest(16527,PLAYTIME) == -1)" );
|
||||
end;
|
||||
}
|
||||
|
||||
sp_rudus3,380,42,3 script Pion#rudus4 4_M_REBELLION3,{
|
||||
switch( isbegin_quest(16521) ) {
|
||||
case 0:
|
||||
emotion ET_SLEEPY;
|
||||
mes "[Pion]";
|
||||
mes "Zzz... Whoa!";
|
||||
mes "Excuse me, sir! No more work!";
|
||||
next;
|
||||
mes "[Pion]";
|
||||
mes "Seup, Ha-am... Down this slope is an access control area.";
|
||||
mes "People are not allowed to enter.";
|
||||
next;
|
||||
select("I'm not an ordinary person." );
|
||||
mes "[Pion]";
|
||||
mes "Yes? Ah... ah no! " + strcharinfo(0) + " !";
|
||||
mes "That... Still, I can't let you in on my own.";
|
||||
close;
|
||||
case 1:
|
||||
emotion ET_SLEEPY;
|
||||
mes "[Pion]";
|
||||
mes "Zzz... Whoa!";
|
||||
mes "Excuse me! No more work!";
|
||||
next;
|
||||
mes "[Pion]";
|
||||
mes "Oops... ah, this is definitely not saliva";
|
||||
mes "It is a drop of sweat that shines with passion and effort.";
|
||||
next;
|
||||
mes "[Pion]";
|
||||
mes "Hmm, hmmm. The entrance down this slope is now restricted...";
|
||||
mes "What's going on?";
|
||||
next;
|
||||
if (select( "I want to go to the 4th floor of Rudus.", "Point out the working attitude." ) == 2) {
|
||||
mes "[Pion]";
|
||||
mes "Oh, there's a problem with your working attitude?";
|
||||
mes "Sa, some people might sleep!!";
|
||||
next;
|
||||
mes "[Pion]";
|
||||
mes "I only slept a little!";
|
||||
mes "Really!";
|
||||
close;
|
||||
}
|
||||
mes "[Pion]";
|
||||
mes "Fourth floor? I'm in control right there...";
|
||||
mes "Ah, did you come to see Yulma from Bullet Meow?";
|
||||
next;
|
||||
mes "[Pion]";
|
||||
mes "Then you should pass it.";
|
||||
mes "If you want to look at the specimens on the 4th floor and help with a research request, go back to <NAVI>[Yulma]<INFO>pub_cat,94,43,0,101,0</INFO></NAVI> and ask.";
|
||||
next;
|
||||
mes "[Pion]";
|
||||
mes "I'll move you to the 4th floor.";
|
||||
close2;
|
||||
completequest 16521;
|
||||
setquest 16522;
|
||||
warp "sp_rudus4",370,156;
|
||||
end;
|
||||
case 2:
|
||||
break;
|
||||
}
|
||||
emotion ET_SLEEPY;
|
||||
mes "[Pion]";
|
||||
mes "Zzz... Huh! Shi, excuse me!";
|
||||
mes "Are you sure you want to go down to the 4th floor of Rudus?";
|
||||
next;
|
||||
if (select( "Move", "Do not move" ) == 2) {
|
||||
mes "[Pion]";
|
||||
mes "I see. Ha-am....";
|
||||
close;
|
||||
}
|
||||
mes "[Pion]";
|
||||
mes "I'll move you. Take care!";
|
||||
close2;
|
||||
warp "sp_rudus4",370,156;
|
||||
end;
|
||||
|
||||
OnInit:
|
||||
questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(16521) == 1" );
|
||||
end;
|
||||
}
|
||||
|
||||
sp_rudus4,192,204,3 script Secret Wing Researcher#rudu 4_SOIL,{
|
||||
mes "[Secret Wing Researcher]";
|
||||
mes "Good. Field work.";
|
||||
mes "You have to watch a lot of monsters.";
|
||||
next;
|
||||
emotion ET_HUK;
|
||||
mes "[Secret Wing Researcher]";
|
||||
mes "...huh!";
|
||||
mes "How did you recognize me?";
|
||||
next;
|
||||
if (isbegin_quest(16528) == 1) {
|
||||
mes "[Secret Wing Researcher]";
|
||||
mes "Oh, look again, " + strcharinfo(0) + ".";
|
||||
mes "I got a call. Are you here to renew the chip?";
|
||||
next;
|
||||
mes "[Secret Wing Researcher]";
|
||||
mes "Let's see... Let's get some chips.";
|
||||
mes "Hmmmm... Connect with my machine... Empty data...";
|
||||
next;
|
||||
emotion ET_BEST;
|
||||
mes "[Secret Wing Researcher]";
|
||||
mes "Okay, that's it! The data is clean and very nice. I'll paste it again.";
|
||||
next;
|
||||
mes "[Secret Wing Researcher]";
|
||||
mes "Because this is also a job, <NAVI>[Yulma]<INFO>pub_cat,94,43,0,101,0</INFO></NAVI> will give you a small allowance when you return.";
|
||||
mes "I am always indebted to you. Good job!";
|
||||
completequest 16528;
|
||||
setquest 16540;
|
||||
close;
|
||||
}
|
||||
emotion ET_KEK;
|
||||
mes "[Secret Wing Researcher]";
|
||||
mes "Evil! If you pretend to know, monsters will come!";
|
||||
mes "Go away!";
|
||||
close;
|
||||
|
||||
OnInit:
|
||||
questinfo( QTYPE_DAILYQUEST, QMARK_YELLOW, "isbegin_quest(16528) == 1" );
|
||||
end;
|
||||
}
|
||||
@@ -115,6 +115,7 @@ npc: npc/re/merchants/bio4_reward.txt
|
||||
//npc: npc/re/merchants/blessed_refiner.txt
|
||||
//npc: npc/re/merchants/card_exchange.txt
|
||||
npc: npc/re/merchants/card_separation.txt
|
||||
npc: npc/re/merchants/cashmall.txt
|
||||
npc: npc/re/merchants/catalog.txt
|
||||
npc: npc/re/merchants/clothing_buff_removal.txt
|
||||
npc: npc/re/merchants/coin_exchange.txt
|
||||
@@ -154,7 +155,7 @@ npc: npc/re/merchants/shops.txt
|
||||
npc: npc/re/merchants/Slot_Move_Card_Sales.txt
|
||||
npc: npc/re/merchants/socket_enchant2.txt
|
||||
//npc: npc/re/merchants/ticket_refiner.txt
|
||||
//npc: npc/re/merchants/enchan_upg.txt
|
||||
npc: npc/re/merchants/enchan_upg.txt
|
||||
//npc: npc/re/merchants/cash_trader-idRO.txt
|
||||
npc: npc/re/merchants/te_merchant.txt
|
||||
npc: npc/re/merchants/shadow_refiner.txt
|
||||
@@ -227,6 +228,7 @@ npc: npc/re/quests/quests_aldebaran.txt
|
||||
npc: npc/re/quests/quests_brasilis.txt
|
||||
npc: npc/re/quests/quests_dewata.txt
|
||||
npc: npc/re/quests/quests_dicastes.txt
|
||||
npc: npc/re/quests/quests_dungeons_200.txt
|
||||
npc: npc/re/quests/quests_eclage.txt
|
||||
npc: npc/re/quests/quests_glastheim.txt
|
||||
npc: npc/re/quests/quests_izlude.txt
|
||||
|
||||
@@ -9,3 +9,5 @@ sp_rudus,180,258,0 warp rudus1_to_rudus2 1,1,sp_rudus2,185,258
|
||||
sp_rudus2,180,258,0 warp rudus2_to_rudus1 1,1,sp_rudus,185,258
|
||||
sp_rudus2,359,206,0 warp rudus2_to_rudus3 1,1,sp_rudus3,366,207
|
||||
sp_rudus3,371,207,0 warp rudus3_to_rudus2 1,1,sp_rudus2,355,206
|
||||
|
||||
sp_rudus4,380,156,0 warp2 #b_hw1 2,2,sp_rudus3,375,45
|
||||
|
||||
@@ -155,7 +155,6 @@ npc: npc/merchants/wander_pet_food.txt
|
||||
// - Cash Shop
|
||||
// See file before enabling, as you may wish to change the
|
||||
// point value of items to suit your own needs.
|
||||
//npc: npc/merchants/cash_hair.txt
|
||||
//npc: npc/merchants/cash_trader.txt
|
||||
npc: npc/merchants/cashheadgear_dye.txt
|
||||
|
||||
|
||||
@@ -6,23 +6,21 @@ The files in this directory are basic SQL table building scripts. The contained
|
||||
|
||||
### New Install
|
||||
---
|
||||
For a new install, the following needs to be imported into the 'ragnarok' schema:
|
||||
For a new install, the following needs to be imported into the main schema:
|
||||
Note: The schema name is defined in `conf/inter_athena.conf::map_server_db`.
|
||||
|
||||
* main.sql - Contains tables for normal server usage.
|
||||
* web.sql - Contains tables for the web service
|
||||
* roulette_default_data.sql - Contains data for the client's roulette game.
|
||||
|
||||
For a new install, the following needs to be imported into the 'log' schema:
|
||||
For a new install, the following can be imported into the main schema but is highly suggested to be imported into a separate schema for logs:
|
||||
Note: The schema name is defined in `conf/inter_athena.conf::log_db_db`.
|
||||
|
||||
* logs.sql - Contains tables for logging of server events.
|
||||
|
||||
If your server is setup to read SQL database data, import the following:
|
||||
If your server is setup to read SQL database data, import the following into the main schema:
|
||||
Note: If `conf/inter_athena.conf::use_sql_db` is set to yes continue with these imports else these can be skipped. Not all files have to be imported, only the ones that apply to the same mode as the server being ran.
|
||||
|
||||
* item_cash_db.sql - Used for client's cash shop.
|
||||
* item_cash_db2.sql - Used for client's cash shop (import).
|
||||
* item_db.sql - Contains __pre-renewal__ item data table structure.
|
||||
* item_db_equip.sql - Contains __pre-renewal__ equipment item data.
|
||||
* item_db_etc.sql - Contains __pre-renewal__ etcetera item data.
|
||||
@@ -44,8 +42,8 @@ Note: If `conf/inter_athena.conf::use_sql_db` is set to yes continue with these
|
||||
|
||||
### Updates
|
||||
---
|
||||
Over the course of time new features and optimizations will take place. This may require SQL changes to happen. In the `upgrades` folder will be upgrade files with an attached date.
|
||||
These imports only have to executed if an update has occurred after the initial installation. Many times a SQL error will be displayed on the server console stating the format differs from what is required.
|
||||
Over the course of time new features and optimizations will take place. This may require SQL changes to happen. In the `upgrades` folder will be SQL files with an attached date.
|
||||
These only have to executed one time if an update has occurred after the initial installation. It's possible to see when an update may be required when a SQL error will be displayed on the server console stating the format differs from what is required.
|
||||
|
||||
### Compatibility
|
||||
---
|
||||
@@ -76,4 +74,4 @@ To run these queries the user requires the [FILE](https://dev.mysql.com/doc/refm
|
||||
|
||||
### Notes
|
||||
---
|
||||
The web-server must be able to read the `login` and `guild` tables from the `login-server` and `char-server`, respectively.
|
||||
The `web-server` must be able to read the `login` and `guild` tables from the `login-server` and `char-server`, respectively.
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
DROP TABLE IF EXISTS `item_cash_db`;
|
||||
CREATE TABLE `item_cash_db` (
|
||||
`tab` smallint(6) NOT NULL,
|
||||
`item_id` int(10) unsigned NOT NULL,
|
||||
`price` mediumint(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`tab`,`item_id`)
|
||||
) ENGINE=MyISAM;
|
||||
@@ -1,7 +0,0 @@
|
||||
DROP TABLE IF EXISTS `item_cash_db2`;
|
||||
CREATE TABLE `item_cash_db2` (
|
||||
`tab` smallint(6) NOT NULL,
|
||||
`item_id` int(10) unsigned NOT NULL,
|
||||
`price` mediumint(10) unsigned NOT NULL DEFAULT '0',
|
||||
PRIMARY KEY (`tab`,`item_id`)
|
||||
) ENGINE=MyISAM;
|
||||
@@ -5641,11 +5641,11 @@ REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_sha
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24344,'S_Blitz_Armor','Blitz Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus bDef,25+5*(.@r/2);\nif (.@r >= 7) {\n bonus bAspd,1;\n if (.@r >= 9) {\n bonus bDelayrate,-1;\n }\n}');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_shield`,`equip_level_min`,`refineable`,`script`) VALUES (24345,'S_Tempest_Shield','Tempest Shadow Shield','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus2 bIgnoreMdefClassRate,Class_Normal,5+(.@r/2);');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_shoes`,`equip_level_min`,`refineable`,`script`) VALUES (24346,'S_Tempest_Shoes','Tempest Shadow Shoes','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus2 bIgnoreMdefClassRate,Class_Normal,5+(.@r/2);');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24347,'S_Magic_Executioner_Holy_Water_Armor','Magic Executioner Holy Water Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_DemiHuman,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Undead,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24348,'S_Magic_Exorcist_Corrupted_Armor','Magic Exorcist Corrupted Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_Demon,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Angel,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24349,'S_Magic_Vibration_Dragon_Killer_Armor','Magic Vibration Dragon Killer Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_Formless,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Dragon,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24350,'S_Magic_Scissor_Hunting_Armor','Magic Scissor Hunting Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_Plant,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Brute,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Player_Doram,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24351,'S_Magic_Fishing_Insect_Net_Armor','Magic Fishing Insect Net Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_Fish,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Insect,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24347,'S_M_ExeHoly_Armor','Magic Executioner Holy Water Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_DemiHuman,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Undead,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24348,'S_M_ExoCorrupt_Armor','Magic Exorcist Corrupted Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_Demon,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Angel,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24349,'S_M_DragonVib_Armor','Magic Vibration Dragon Killer Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_Formless,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Dragon,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24350,'S_M_SciHunting_Armor','Magic Scissor Hunting Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_Plant,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Brute,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Player_Doram,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24351,'S_M_FishInsect_Armor','Magic Fishing Insect Net Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreMdefRaceRate,RC_Fish,.@val;\nbonus2 bIgnoreMdefRaceRate,RC_Insect,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24352,'S_Plasterer\'s_Armor_II','Plasterer\'s Shadow Armor II','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus bDef,1;\nbonus2 bResEff,Eff_Stone,100*.@r;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_shoes`,`equip_level_min`,`refineable`,`script`) VALUES (24353,'S_Insomniac_Shoes_II','Insomniac Shadow Shoes II','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus bDef,1;\nbonus2 bResEff,Eff_Sleep,100*.@r;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24354,'S_Peerless_Armor_II','Peerless Shadow Armor II','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus bDef,1;\nbonus2 bResEff,Eff_Silence,100*.@r;');
|
||||
@@ -5669,11 +5669,11 @@ REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_sha
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_left_accessory`,`equip_level_min`,`refineable`,`script`) VALUES (24372,'S_Mortal_Blow_Pendant','Mortal Blow Shadow Pendant','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nif (.@r >= 9) {\n .@val = 3;\n} else if (.@r >= 7) {\n .@val = 2;\n}\nelse {\n .@val = 1;\n}\nbonus bCritAtkRate,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_shoes`,`equip_level_min`,`refineable`,`script`) VALUES (24373,'S_Penetration_Shoes','Penetration Shadow Shoes','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus2 bIgnoreDefClassRate,Class_Normal,5+(.@r/2);');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_shield`,`equip_level_min`,`refineable`,`script`) VALUES (24374,'S_Penetration_Shield','Penetration Shadow Shield','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus2 bIgnoreDefClassRate,Class_Normal,5+(.@r/2);');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24375,'S_Executioner_Holy_Water_Armor','Executioner Holy Water Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_DemiHuman,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Undead,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24376,'S_Exorcist_Corrupted_Armor','Exorcist Corrupted Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_Demon,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Angel,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24377,'S_Vibration_Dragon_Killer_Armor','Vibration Dragon Killer Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_Formless,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Dragon,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24378,'S_Scissor_Hunting_Armor','Scissor Hunting Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_Plant,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Brute,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24379,'S_Fishing_Insect_Net_Armor','Fishing Insect Net Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_Fish,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Insect,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24375,'S_ExeHoly_Armor','Executioner Holy Water Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_DemiHuman,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Undead,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24376,'S_ExoCorrupt_Armor','Exorcist Corrupted Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_Demon,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Angel,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24377,'S_DragonVib_Armor','Vibration Dragon Killer Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_Formless,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Dragon,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24378,'S_SciHunting_Armor','Scissor Hunting Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_Plant,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Brute,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_armor`,`equip_level_min`,`refineable`,`script`) VALUES (24379,'S_FishInsect_Armor','Fishing Insect Net Shadow Armor','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\n.@val = 5 + (.@r/2);\nbonus2 bIgnoreDefRaceRate,RC_Fish,.@val;\nbonus2 bIgnoreDefRaceRate,RC_Insect,.@val;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_weapon`,`equip_level_min`,`refineable`,`script`) VALUES (24380,'Sentimental_Weapone_S','Sentimental Shadow Weapon','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bBaseAtk,.@r;\nbonus bMatk,.@r;\nbonus bMaxSP,10+((.@r/2)*15);');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_right_accessory`,`equip_level_min`,`refineable`,`script`) VALUES (24381,'Sentimental_Earring_S','Sentimental Shadow Earring','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus bMaxSP,(.@r/2)*5;\nbonus bMaxSPrate,1;\nbonus bBaseAtk,5;');
|
||||
REPLACE INTO `item_db_re` (`id`,`name_aegis`,`name_english`,`type`,`location_shadow_left_accessory`,`equip_level_min`,`refineable`,`script`) VALUES (24382,'Sentimental_Pendant_S','Sentimental Shadow Pendant','Shadowgear',true,1,true,'.@r = getrefine();\nbonus bMaxHP,.@r*10;\nbonus bSPrecovRate,2+.@r/3;\nbonus bBaseAtk,5;');
|
||||
|
||||
@@ -940,6 +940,8 @@ CREATE TABLE IF NOT EXISTS `sc_data` (
|
||||
`char_id` int(11) unsigned NOT NULL,
|
||||
`type` smallint(11) unsigned NOT NULL,
|
||||
`tick` bigint(20) NOT NULL,
|
||||
`tick_total` bigint(20) NOT NULL,
|
||||
`tick_time` bigint(20) NOT NULL,
|
||||
`val1` int(11) NOT NULL default '0',
|
||||
`val2` int(11) NOT NULL default '0',
|
||||
`val3` int(11) NOT NULL default '0',
|
||||
@@ -973,6 +975,27 @@ CREATE TABLE IF NOT EXISTS `party` (
|
||||
PRIMARY KEY (`party_id`)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
--
|
||||
-- Table structure for table `party_bookings`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `party_bookings` (
|
||||
`world_name` varchar(32) NOT NULL,
|
||||
`account_id` int(11) unsigned NOT NULL,
|
||||
`char_id` int(11) unsigned NOT NULL,
|
||||
`char_name` varchar(23) NOT NULL,
|
||||
`purpose` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`assist` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`damagedealer` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`healer` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`tanker` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`minimum_level` smallint(5) unsigned NOT NULL,
|
||||
`maximum_level` smallint(5) unsigned NOT NULL,
|
||||
`comment` varchar(255) NOT NULL DEFAULT '',
|
||||
`created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`world_name`, `account_id`, `char_id`)
|
||||
) ENGINE=MyISAM;
|
||||
|
||||
--
|
||||
-- Table structure for table `pet`
|
||||
--
|
||||
|
||||
5
sql-files/upgrades/upgrade_20200803.sql
Normal file
5
sql-files/upgrades/upgrade_20200803.sql
Normal file
@@ -0,0 +1,5 @@
|
||||
ALTER TABLE `sc_data` ADD COLUMN `tick_total` BIGINT(20) NOT NULL AFTER `tick`;
|
||||
UPDATE `sc_data` SET `tick_total` = `tick`;
|
||||
|
||||
ALTER TABLE `sc_data` ADD COLUMN `tick_time` BIGINT(20) NOT NULL AFTER `tick_total`;
|
||||
UPDATE `sc_data` SET `tick_time` = `tick`;
|
||||
823
sql-files/upgrades/upgrade_20221218.sql
Normal file
823
sql-files/upgrades/upgrade_20221218.sql
Normal file
@@ -0,0 +1,823 @@
|
||||
/**
|
||||
ATTENTION!!!
|
||||
Please make sure to create a backup of your live data before running this update.
|
||||
This update is rather complicated and although I have tried my best I cannot guarantee that I did not make any mistake. [Lemongrass]
|
||||
We would also advise you to check the data in the temporary table after the insert statement and before the update statements.
|
||||
You could do so by running
|
||||
select * from `tmp_randomoptionfix` where `new_index` <> `old_index`;
|
||||
to see where changes happen and options will be moved.
|
||||
For executing this update your user needs create table and drop table permissions. Either run the update with another user [admin or root for example] or give your database user these permissions temporarily.
|
||||
Do not forget to remove these permissions again, as they are usually not necessary and it is rather dangerous, if someone gets access to your database user.
|
||||
Additionally if you have more than one storage table (see conf/inter_server.yml) make sure to also update those tables (see instructions at the bottom of this script).
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
Comment the line below to really run the script, this is a safeguard that you confirm you have read and understood what was written above.
|
||||
**/
|
||||
cancel;
|
||||
|
||||
-- Create a temporary table to store the data for the update
|
||||
create table `tmp_randomoptionfix` (
|
||||
`id` int(11) unsigned NOT NULL,
|
||||
`new_index` smallint(5) NOT NULL,
|
||||
`old_index` smallint(5) NOT NULL,
|
||||
`option_id` smallint(5) NOT NULL,
|
||||
`option_val` smallint(5) NOT NULL,
|
||||
`option_parm` tinyint(3) NOT NULL,
|
||||
PRIMARY KEY ( `id`, `old_index` )
|
||||
);
|
||||
|
||||
-- Create auction data
|
||||
insert into `tmp_randomoptionfix` ( `id`, `new_index`, `old_index`, `option_id`, `option_val`, `option_parm` )
|
||||
select
|
||||
`id`,
|
||||
row_number() over( partition by `id` order by `old_index` asc ) - 1 as `new_index`,
|
||||
`old_index`,
|
||||
`option_id`,
|
||||
`option_val`,
|
||||
`option_parm`
|
||||
from (
|
||||
select * from (
|
||||
select
|
||||
`auction_id` as `id`,
|
||||
0 as `old_index`,
|
||||
`option_id0` as `option_id`,
|
||||
`option_val0` as `option_val`,
|
||||
`option_parm0` as `option_parm`
|
||||
from `auction`
|
||||
where `option_id0` <> 0
|
||||
union
|
||||
select
|
||||
`auction_id` as `id`,
|
||||
1 as `old_index`,
|
||||
`option_id1` as `option_id`,
|
||||
`option_val1` as `option_val`,
|
||||
`option_parm1` as `option_parm`
|
||||
from `auction`
|
||||
where `option_id1` <> 0
|
||||
union
|
||||
select
|
||||
`auction_id` as `id`,
|
||||
2 as `old_index`,
|
||||
`option_id2` as `option_id`,
|
||||
`option_val2` as `option_val`,
|
||||
`option_parm2` as `option_parm`
|
||||
from `auction`
|
||||
where `option_id2` <> 0
|
||||
union
|
||||
select
|
||||
`auction_id` as `id`,
|
||||
3 as `old_index`,
|
||||
`option_id3` as `option_id`,
|
||||
`option_val3` as `option_val`,
|
||||
`option_parm3` as `option_parm`
|
||||
from `auction`
|
||||
where `option_id3` <> 0
|
||||
union
|
||||
select
|
||||
`auction_id` as `id`,
|
||||
4 as `old_index`,
|
||||
`option_id4` as `option_id`,
|
||||
`option_val4` as `option_val`,
|
||||
`option_parm4` as `option_parm`
|
||||
from `auction`
|
||||
where `option_id4` <> 0
|
||||
) t2
|
||||
order by `id`, `old_index`
|
||||
) t ;
|
||||
|
||||
-- Fix option 0
|
||||
update `auction`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `auction`.`auction_id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 0
|
||||
set
|
||||
`option_id0` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val0` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm0` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 1
|
||||
update `auction`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `auction`.`auction_id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 1
|
||||
set
|
||||
`option_id1` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val1` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm1` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 2
|
||||
update `auction`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `auction`.`auction_id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 2
|
||||
set
|
||||
`option_id2` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val2` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm2` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 3
|
||||
update `auction`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `auction`.`auction_id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 3
|
||||
set
|
||||
`option_id3` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val3` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm3` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 4
|
||||
update `auction`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `auction`.`auction_id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 4
|
||||
set
|
||||
`option_id4` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val4` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm4` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Delete the data to have a clean table for the next run
|
||||
delete from `tmp_randomoptionfix`;
|
||||
|
||||
-- Create cart_inventory data
|
||||
insert into `tmp_randomoptionfix` ( `id`, `new_index`, `old_index`, `option_id`, `option_val`, `option_parm` )
|
||||
select
|
||||
`id`,
|
||||
row_number() over( partition by `id` order by `old_index` asc ) - 1 as `new_index`,
|
||||
`old_index`,
|
||||
`option_id`,
|
||||
`option_val`,
|
||||
`option_parm`
|
||||
from (
|
||||
select * from (
|
||||
select
|
||||
`id`,
|
||||
0 as `old_index`,
|
||||
`option_id0` as `option_id`,
|
||||
`option_val0` as `option_val`,
|
||||
`option_parm0` as `option_parm`
|
||||
from `cart_inventory`
|
||||
where `option_id0` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
1 as `old_index`,
|
||||
`option_id1` as `option_id`,
|
||||
`option_val1` as `option_val`,
|
||||
`option_parm1` as `option_parm`
|
||||
from `cart_inventory`
|
||||
where `option_id1` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
2 as `old_index`,
|
||||
`option_id2` as `option_id`,
|
||||
`option_val2` as `option_val`,
|
||||
`option_parm2` as `option_parm`
|
||||
from `cart_inventory`
|
||||
where `option_id2` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
3 as `old_index`,
|
||||
`option_id3` as `option_id`,
|
||||
`option_val3` as `option_val`,
|
||||
`option_parm3` as `option_parm`
|
||||
from `cart_inventory`
|
||||
where `option_id3` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
4 as `old_index`,
|
||||
`option_id4` as `option_id`,
|
||||
`option_val4` as `option_val`,
|
||||
`option_parm4` as `option_parm`
|
||||
from `cart_inventory`
|
||||
where `option_id4` <> 0
|
||||
) t2
|
||||
order by `id`, `old_index`
|
||||
) t ;
|
||||
|
||||
-- Fix option 0
|
||||
update `cart_inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `cart_inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 0
|
||||
set
|
||||
`option_id0` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val0` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm0` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 1
|
||||
update `cart_inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `cart_inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 1
|
||||
set
|
||||
`option_id1` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val1` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm1` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 2
|
||||
update `cart_inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `cart_inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 2
|
||||
set
|
||||
`option_id2` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val2` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm2` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 3
|
||||
update `cart_inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `cart_inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 3
|
||||
set
|
||||
`option_id3` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val3` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm3` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 4
|
||||
update `cart_inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `cart_inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 4
|
||||
set
|
||||
`option_id4` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val4` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm4` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Delete the data to have a clean table for the next run
|
||||
delete from `tmp_randomoptionfix`;
|
||||
|
||||
-- Create guild_storage data
|
||||
insert into `tmp_randomoptionfix` ( `id`, `new_index`, `old_index`, `option_id`, `option_val`, `option_parm` )
|
||||
select
|
||||
`id`,
|
||||
row_number() over( partition by `id` order by `old_index` asc ) - 1 as `new_index`,
|
||||
`old_index`,
|
||||
`option_id`,
|
||||
`option_val`,
|
||||
`option_parm`
|
||||
from (
|
||||
select * from (
|
||||
select
|
||||
`id`,
|
||||
0 as `old_index`,
|
||||
`option_id0` as `option_id`,
|
||||
`option_val0` as `option_val`,
|
||||
`option_parm0` as `option_parm`
|
||||
from `guild_storage`
|
||||
where `option_id0` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
1 as `old_index`,
|
||||
`option_id1` as `option_id`,
|
||||
`option_val1` as `option_val`,
|
||||
`option_parm1` as `option_parm`
|
||||
from `guild_storage`
|
||||
where `option_id1` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
2 as `old_index`,
|
||||
`option_id2` as `option_id`,
|
||||
`option_val2` as `option_val`,
|
||||
`option_parm2` as `option_parm`
|
||||
from `guild_storage`
|
||||
where `option_id2` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
3 as `old_index`,
|
||||
`option_id3` as `option_id`,
|
||||
`option_val3` as `option_val`,
|
||||
`option_parm3` as `option_parm`
|
||||
from `guild_storage`
|
||||
where `option_id3` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
4 as `old_index`,
|
||||
`option_id4` as `option_id`,
|
||||
`option_val4` as `option_val`,
|
||||
`option_parm4` as `option_parm`
|
||||
from `guild_storage`
|
||||
where `option_id4` <> 0
|
||||
) t2
|
||||
order by `id`, `old_index`
|
||||
) t ;
|
||||
|
||||
-- Fix option 0
|
||||
update `guild_storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `guild_storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 0
|
||||
set
|
||||
`option_id0` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val0` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm0` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 1
|
||||
update `guild_storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `guild_storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 1
|
||||
set
|
||||
`option_id1` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val1` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm1` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 2
|
||||
update `guild_storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `guild_storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 2
|
||||
set
|
||||
`option_id2` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val2` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm2` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 3
|
||||
update `guild_storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `guild_storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 3
|
||||
set
|
||||
`option_id3` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val3` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm3` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 4
|
||||
update `guild_storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `guild_storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 4
|
||||
set
|
||||
`option_id4` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val4` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm4` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Delete the data to have a clean table for the next run
|
||||
delete from `tmp_randomoptionfix`;
|
||||
|
||||
-- Create inventory data
|
||||
insert into `tmp_randomoptionfix` ( `id`, `new_index`, `old_index`, `option_id`, `option_val`, `option_parm` )
|
||||
select
|
||||
`id`,
|
||||
row_number() over( partition by `id` order by `old_index` asc ) - 1 as `new_index`,
|
||||
`old_index`,
|
||||
`option_id`,
|
||||
`option_val`,
|
||||
`option_parm`
|
||||
from (
|
||||
select * from (
|
||||
select
|
||||
`id`,
|
||||
0 as `old_index`,
|
||||
`option_id0` as `option_id`,
|
||||
`option_val0` as `option_val`,
|
||||
`option_parm0` as `option_parm`
|
||||
from `inventory`
|
||||
where `option_id0` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
1 as `old_index`,
|
||||
`option_id1` as `option_id`,
|
||||
`option_val1` as `option_val`,
|
||||
`option_parm1` as `option_parm`
|
||||
from `inventory`
|
||||
where `option_id1` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
2 as `old_index`,
|
||||
`option_id2` as `option_id`,
|
||||
`option_val2` as `option_val`,
|
||||
`option_parm2` as `option_parm`
|
||||
from `inventory`
|
||||
where `option_id2` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
3 as `old_index`,
|
||||
`option_id3` as `option_id`,
|
||||
`option_val3` as `option_val`,
|
||||
`option_parm3` as `option_parm`
|
||||
from `inventory`
|
||||
where `option_id3` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
4 as `old_index`,
|
||||
`option_id4` as `option_id`,
|
||||
`option_val4` as `option_val`,
|
||||
`option_parm4` as `option_parm`
|
||||
from `inventory`
|
||||
where `option_id4` <> 0
|
||||
) t2
|
||||
order by `id`, `old_index`
|
||||
) t ;
|
||||
|
||||
-- Fix option 0
|
||||
update `inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 0
|
||||
set
|
||||
`option_id0` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val0` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm0` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 1
|
||||
update `inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 1
|
||||
set
|
||||
`option_id1` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val1` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm1` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 2
|
||||
update `inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 2
|
||||
set
|
||||
`option_id2` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val2` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm2` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 3
|
||||
update `inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 3
|
||||
set
|
||||
`option_id3` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val3` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm3` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 4
|
||||
update `inventory`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `inventory`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 4
|
||||
set
|
||||
`option_id4` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val4` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm4` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Delete the data to have a clean table for the next run
|
||||
delete from `tmp_randomoptionfix`;
|
||||
|
||||
-- Create mail_attachments data
|
||||
insert into `tmp_randomoptionfix` ( `id`, `new_index`, `old_index`, `option_id`, `option_val`, `option_parm` )
|
||||
select
|
||||
`id`,
|
||||
row_number() over( partition by `id` order by `old_index` asc ) - 1 as `new_index`,
|
||||
`old_index`,
|
||||
`option_id`,
|
||||
`option_val`,
|
||||
`option_parm`
|
||||
from (
|
||||
select * from (
|
||||
select
|
||||
`id`,
|
||||
0 as `old_index`,
|
||||
`option_id0` as `option_id`,
|
||||
`option_val0` as `option_val`,
|
||||
`option_parm0` as `option_parm`
|
||||
from `mail_attachments`
|
||||
where `option_id0` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
1 as `old_index`,
|
||||
`option_id1` as `option_id`,
|
||||
`option_val1` as `option_val`,
|
||||
`option_parm1` as `option_parm`
|
||||
from `mail_attachments`
|
||||
where `option_id1` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
2 as `old_index`,
|
||||
`option_id2` as `option_id`,
|
||||
`option_val2` as `option_val`,
|
||||
`option_parm2` as `option_parm`
|
||||
from `mail_attachments`
|
||||
where `option_id2` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
3 as `old_index`,
|
||||
`option_id3` as `option_id`,
|
||||
`option_val3` as `option_val`,
|
||||
`option_parm3` as `option_parm`
|
||||
from `mail_attachments`
|
||||
where `option_id3` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
4 as `old_index`,
|
||||
`option_id4` as `option_id`,
|
||||
`option_val4` as `option_val`,
|
||||
`option_parm4` as `option_parm`
|
||||
from `mail_attachments`
|
||||
where `option_id4` <> 0
|
||||
) t2
|
||||
order by `id`, `old_index`
|
||||
) t ;
|
||||
|
||||
-- Fix option 0
|
||||
update `mail_attachments`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `mail_attachments`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 0
|
||||
set
|
||||
`option_id0` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val0` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm0` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 1
|
||||
update `mail_attachments`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `mail_attachments`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 1
|
||||
set
|
||||
`option_id1` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val1` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm1` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 2
|
||||
update `mail_attachments`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `mail_attachments`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 2
|
||||
set
|
||||
`option_id2` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val2` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm2` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 3
|
||||
update `mail_attachments`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `mail_attachments`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 3
|
||||
set
|
||||
`option_id3` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val3` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm3` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 4
|
||||
update `mail_attachments`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `mail_attachments`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 4
|
||||
set
|
||||
`option_id4` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val4` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm4` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Delete the data to have a clean table for the next run
|
||||
delete from `tmp_randomoptionfix`;
|
||||
|
||||
-- Create storage data
|
||||
insert into `tmp_randomoptionfix` ( `id`, `new_index`, `old_index`, `option_id`, `option_val`, `option_parm` )
|
||||
select
|
||||
`id`,
|
||||
row_number() over( partition by `id` order by `old_index` asc ) - 1 as `new_index`,
|
||||
`old_index`,
|
||||
`option_id`,
|
||||
`option_val`,
|
||||
`option_parm`
|
||||
from (
|
||||
select * from (
|
||||
select
|
||||
`id`,
|
||||
0 as `old_index`,
|
||||
`option_id0` as `option_id`,
|
||||
`option_val0` as `option_val`,
|
||||
`option_parm0` as `option_parm`
|
||||
from `storage`
|
||||
where `option_id0` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
1 as `old_index`,
|
||||
`option_id1` as `option_id`,
|
||||
`option_val1` as `option_val`,
|
||||
`option_parm1` as `option_parm`
|
||||
from `storage`
|
||||
where `option_id1` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
2 as `old_index`,
|
||||
`option_id2` as `option_id`,
|
||||
`option_val2` as `option_val`,
|
||||
`option_parm2` as `option_parm`
|
||||
from `storage`
|
||||
where `option_id2` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
3 as `old_index`,
|
||||
`option_id3` as `option_id`,
|
||||
`option_val3` as `option_val`,
|
||||
`option_parm3` as `option_parm`
|
||||
from `storage`
|
||||
where `option_id3` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
4 as `old_index`,
|
||||
`option_id4` as `option_id`,
|
||||
`option_val4` as `option_val`,
|
||||
`option_parm4` as `option_parm`
|
||||
from `storage`
|
||||
where `option_id4` <> 0
|
||||
) t2
|
||||
order by `id`, `old_index`
|
||||
) t ;
|
||||
|
||||
-- Fix option 0
|
||||
update `storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 0
|
||||
set
|
||||
`option_id0` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val0` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm0` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 1
|
||||
update `storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 1
|
||||
set
|
||||
`option_id1` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val1` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm1` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 2
|
||||
update `storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 2
|
||||
set
|
||||
`option_id2` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val2` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm2` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 3
|
||||
update `storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 3
|
||||
set
|
||||
`option_id3` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val3` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm3` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 4
|
||||
update `storage`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `storage`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 4
|
||||
set
|
||||
`option_id4` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val4` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm4` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Delete the data to have a clean table for the next run
|
||||
delete from `tmp_randomoptionfix`;
|
||||
|
||||
-- Repeat this for any other storage tables that you have created (for example VIP)
|
||||
-- To do this copy paste the code below and replace ${other_storage} with the name of your table
|
||||
/**
|
||||
-- Create ${other_storage} data
|
||||
insert into `tmp_randomoptionfix` ( `id`, `new_index`, `old_index`, `option_id`, `option_val`, `option_parm` )
|
||||
select
|
||||
`id`,
|
||||
row_number() over( partition by `id` order by `old_index` asc ) - 1 as `new_index`,
|
||||
`old_index`,
|
||||
`option_id`,
|
||||
`option_val`,
|
||||
`option_parm`
|
||||
from (
|
||||
select * from (
|
||||
select
|
||||
`id`,
|
||||
0 as `old_index`,
|
||||
`option_id0` as `option_id`,
|
||||
`option_val0` as `option_val`,
|
||||
`option_parm0` as `option_parm`
|
||||
from `${other_storage}`
|
||||
where `option_id0` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
1 as `old_index`,
|
||||
`option_id1` as `option_id`,
|
||||
`option_val1` as `option_val`,
|
||||
`option_parm1` as `option_parm`
|
||||
from `${other_storage}`
|
||||
where `option_id1` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
2 as `old_index`,
|
||||
`option_id2` as `option_id`,
|
||||
`option_val2` as `option_val`,
|
||||
`option_parm2` as `option_parm`
|
||||
from `${other_storage}`
|
||||
where `option_id2` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
3 as `old_index`,
|
||||
`option_id3` as `option_id`,
|
||||
`option_val3` as `option_val`,
|
||||
`option_parm3` as `option_parm`
|
||||
from `${other_storage}`
|
||||
where `option_id3` <> 0
|
||||
union
|
||||
select
|
||||
`id`,
|
||||
4 as `old_index`,
|
||||
`option_id4` as `option_id`,
|
||||
`option_val4` as `option_val`,
|
||||
`option_parm4` as `option_parm`
|
||||
from `${other_storage}`
|
||||
where `option_id4` <> 0
|
||||
) t2
|
||||
order by `id`, `old_index`
|
||||
) t ;
|
||||
|
||||
-- Fix option 0
|
||||
update `${other_storage}`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `${other_storage}`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 0
|
||||
set
|
||||
`option_id0` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val0` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm0` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 1
|
||||
update `${other_storage}`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `${other_storage}`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 1
|
||||
set
|
||||
`option_id1` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val1` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm1` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 2
|
||||
update `${other_storage}`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `${other_storage}`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 2
|
||||
set
|
||||
`option_id2` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val2` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm2` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 3
|
||||
update `${other_storage}`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `${other_storage}`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 3
|
||||
set
|
||||
`option_id3` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val3` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm3` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Fix option 4
|
||||
update `${other_storage}`
|
||||
left join `tmp_randomoptionfix`
|
||||
on `${other_storage}`.`id` = `tmp_randomoptionfix`.`id` and `tmp_randomoptionfix`.`new_index` = 4
|
||||
set
|
||||
`option_id4` = coalesce( `tmp_randomoptionfix`.`option_id`, 0 ),
|
||||
`option_val4` = coalesce( `tmp_randomoptionfix`.`option_val`, 0 ),
|
||||
`option_parm4` = coalesce( `tmp_randomoptionfix`.`option_parm`, 0 )
|
||||
;
|
||||
|
||||
-- Delete the data to have a clean table for the next run
|
||||
delete from `tmp_randomoptionfix`;
|
||||
**/
|
||||
|
||||
drop table `tmp_randomoptionfix`;
|
||||
20
sql-files/upgrades/upgrade_20221220.sql
Normal file
20
sql-files/upgrades/upgrade_20221220.sql
Normal file
@@ -0,0 +1,20 @@
|
||||
--
|
||||
-- Table structure for table `party_bookings`
|
||||
--
|
||||
|
||||
CREATE TABLE IF NOT EXISTS `party_bookings` (
|
||||
`world_name` varchar(32) NOT NULL,
|
||||
`account_id` int(11) unsigned NOT NULL,
|
||||
`char_id` int(11) unsigned NOT NULL,
|
||||
`char_name` varchar(23) NOT NULL,
|
||||
`purpose` smallint(5) unsigned NOT NULL DEFAULT '0',
|
||||
`assist` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`damagedealer` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`healer` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`tanker` tinyint(3) unsigned NOT NULL DEFAULT '0',
|
||||
`minimum_level` smallint(5) unsigned NOT NULL,
|
||||
`maximum_level` smallint(5) unsigned NOT NULL,
|
||||
`comment` varchar(255) NOT NULL DEFAULT '',
|
||||
`created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||
PRIMARY KEY (`world_name`, `account_id`, `char_id`)
|
||||
) ENGINE=MyISAM;
|
||||
@@ -110,6 +110,7 @@
|
||||
<PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\rapidyaml\src;$(SolutionDir)3rdparty\rapidyaml\ext\c4core\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
@@ -229,4 +230,4 @@
|
||||
<Copy SourceFiles="$(SolutionDir)tools\charserv.bat" DestinationFolder="$(SolutionDir)" ContinueOnError="true" Condition="!Exists('$(SolutionDir)charserv.bat')" />
|
||||
<Copy SourceFiles="$(SolutionDir)tools\runserver.bat" DestinationFolder="$(SolutionDir)" ContinueOnError="true" Condition="!Exists('$(SolutionDir)runserver.bat')" />
|
||||
</Target>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -4,6 +4,9 @@
|
||||
#pragma warning(disable:4800)
|
||||
#include "char.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@@ -22,6 +25,7 @@
|
||||
#include "../common/socket.hpp"
|
||||
#include "../common/strlib.hpp"
|
||||
#include "../common/timer.hpp"
|
||||
#include "../common/utilities.hpp"
|
||||
|
||||
#include "char_clif.hpp"
|
||||
#include "char_cnslif.hpp"
|
||||
@@ -37,6 +41,9 @@
|
||||
#include "int_storage.hpp"
|
||||
#include "packets.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
using namespace rathena::server_character;
|
||||
|
||||
//definition of exported var declared in header
|
||||
int login_fd=-1; //login file descriptor
|
||||
int char_fd=-1; //char file descriptor
|
||||
@@ -68,31 +75,31 @@ struct s_subnet {
|
||||
} subnet[16];
|
||||
int subnet_count = 0;
|
||||
|
||||
DBMap* auth_db; // uint32 account_id -> struct auth_node*
|
||||
DBMap* online_char_db; // uint32 account_id -> struct online_char_data*
|
||||
DBMap* char_db_; // uint32 char_id -> struct mmo_charstatus*
|
||||
DBMap* char_get_authdb() { return auth_db; }
|
||||
DBMap* char_get_onlinedb() { return online_char_db; }
|
||||
DBMap* char_get_chardb() { return char_db_; }
|
||||
// uint32 account_id -> struct auth_node*
|
||||
std::unordered_map<uint32, std::shared_ptr<struct auth_node>> auth_db;
|
||||
// uint32 account_id -> struct online_char_data*
|
||||
std::unordered_map<uint32, std::shared_ptr<struct online_char_data>> online_char_db;
|
||||
// uint32 char_id -> struct mmo_charstatus*
|
||||
std::unordered_map<uint32, std::shared_ptr<struct mmo_charstatus>> char_db;
|
||||
std::unordered_map<uint32, std::shared_ptr<struct auth_node>>& char_get_authdb() { return auth_db; }
|
||||
std::unordered_map<uint32, std::shared_ptr<struct online_char_data>>& char_get_onlinedb() { return online_char_db; }
|
||||
std::unordered_map<uint32, std::shared_ptr<struct mmo_charstatus>>& char_get_chardb() { return char_db; }
|
||||
|
||||
/**
|
||||
* @see DBCreateData
|
||||
*/
|
||||
DBData char_create_online_data(DBKey key, va_list args){
|
||||
struct online_char_data* character;
|
||||
CREATE(character, struct online_char_data, 1);
|
||||
character->account_id = key.i;
|
||||
character->char_id = -1;
|
||||
character->server = -1;
|
||||
character->fd = -1;
|
||||
character->waiting_disconnect = INVALID_TIMER;
|
||||
return db_ptr2data(character);
|
||||
online_char_data::online_char_data( uint32 account_id ){
|
||||
this->account_id = account_id;
|
||||
this->char_id = -1;
|
||||
this->server = -1;
|
||||
this->fd = -1;
|
||||
this->waiting_disconnect = INVALID_TIMER;
|
||||
}
|
||||
|
||||
void char_set_charselect(uint32 account_id) {
|
||||
struct online_char_data* character;
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), account_id );
|
||||
|
||||
character = (struct online_char_data*)idb_ensure(online_char_db, account_id, char_create_online_data);
|
||||
if( character == nullptr ){
|
||||
character = std::make_shared<struct online_char_data>( account_id );
|
||||
char_get_onlinedb()[account_id] = character;
|
||||
}
|
||||
|
||||
if( character->server > -1 )
|
||||
if( map_server[character->server].users > 0 ) // Prevent this value from going negative.
|
||||
@@ -111,20 +118,27 @@ void char_set_charselect(uint32 account_id) {
|
||||
}
|
||||
|
||||
void char_set_char_online(int map_id, uint32 char_id, uint32 account_id) {
|
||||
struct online_char_data* character;
|
||||
struct mmo_charstatus *cp;
|
||||
|
||||
//Update DB
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='1', `last_login`=NOW() WHERE `char_id`='%d' LIMIT 1", schema_config.char_db, char_id) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
|
||||
//Check to see for online conflicts
|
||||
character = (struct online_char_data*)idb_ensure(online_char_db, account_id, char_create_online_data);
|
||||
if( character->char_id != -1 && character->server > -1 && character->server != map_id )
|
||||
{
|
||||
ShowNotice("set_char_online: Character %d:%d marked in map server %d, but map server %d claims to have (%d:%d) online!\n",
|
||||
character->account_id, character->char_id, character->server, map_id, account_id, char_id);
|
||||
mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), account_id );
|
||||
|
||||
if( character != nullptr ){
|
||||
if( character->char_id != -1 && character->server > -1 && character->server != map_id ){
|
||||
ShowNotice("set_char_online: Character %d:%d marked in map server %d, but map server %d claims to have (%d:%d) online!\n",
|
||||
character->account_id, character->char_id, character->server, map_id, account_id, char_id);
|
||||
mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
|
||||
}
|
||||
|
||||
// Get rid of disconnect timer
|
||||
if( character->waiting_disconnect != INVALID_TIMER ){
|
||||
delete_timer( character->waiting_disconnect, char_chardb_waiting_disconnect );
|
||||
character->waiting_disconnect = INVALID_TIMER;
|
||||
}
|
||||
}else{
|
||||
character = std::make_shared<struct online_char_data>( account_id );
|
||||
}
|
||||
|
||||
//Update state data
|
||||
@@ -134,14 +148,9 @@ void char_set_char_online(int map_id, uint32 char_id, uint32 account_id) {
|
||||
if( character->server > -1 )
|
||||
map_server[character->server].users++;
|
||||
|
||||
//Get rid of disconnect timer
|
||||
if(character->waiting_disconnect != INVALID_TIMER) {
|
||||
delete_timer(character->waiting_disconnect, char_chardb_waiting_disconnect);
|
||||
character->waiting_disconnect = INVALID_TIMER;
|
||||
}
|
||||
|
||||
//Set char online in guild cache. If char is in memory, use the guild id on it, otherwise seek it.
|
||||
cp = (struct mmo_charstatus*)idb_get(char_db_,char_id);
|
||||
std::shared_ptr<struct mmo_charstatus> cp = util::umap_find( char_get_chardb(), char_id );
|
||||
|
||||
inter_guild_CharOnline(char_id, cp?cp->guild_id:-1);
|
||||
|
||||
//Notify login server
|
||||
@@ -149,8 +158,6 @@ void char_set_char_online(int map_id, uint32 char_id, uint32 account_id) {
|
||||
}
|
||||
|
||||
void char_set_char_offline(uint32 char_id, uint32 account_id){
|
||||
struct online_char_data* character;
|
||||
|
||||
if ( char_id == -1 )
|
||||
{
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `account_id`='%d'", schema_config.char_db, account_id) )
|
||||
@@ -158,17 +165,20 @@ void char_set_char_offline(uint32 char_id, uint32 account_id){
|
||||
}
|
||||
else
|
||||
{
|
||||
struct mmo_charstatus* cp = (struct mmo_charstatus*)idb_get(char_db_,char_id);
|
||||
std::shared_ptr<struct mmo_charstatus> cp = util::umap_find( char_get_chardb(), char_id );
|
||||
|
||||
inter_guild_CharOffline(char_id, cp?cp->guild_id:-1);
|
||||
if (cp)
|
||||
idb_remove(char_db_,char_id);
|
||||
char_get_chardb().erase( char_id );
|
||||
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `online`='0' WHERE `char_id`='%d' LIMIT 1", schema_config.char_db, char_id) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
}
|
||||
|
||||
if ((character = (struct online_char_data*)idb_get(online_char_db, account_id)) != NULL)
|
||||
{ //We don't free yet to avoid aCalloc/aFree spamming during char change. [Skotlex]
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), account_id );
|
||||
|
||||
// We don't free yet to avoid aCalloc/aFree spamming during char change. [Skotlex]
|
||||
if( character != nullptr ){
|
||||
if( character->server > -1 )
|
||||
if( map_server[character->server].users > 0 ) // Prevent this value from going negative.
|
||||
map_server[character->server].users--;
|
||||
@@ -195,12 +205,7 @@ void char_set_char_offline(uint32 char_id, uint32 account_id){
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBApply
|
||||
*/
|
||||
int char_db_setoffline(DBKey key, DBData *data, va_list ap) {
|
||||
struct online_char_data* character = (struct online_char_data*)db_data2ptr(data);
|
||||
int server = va_arg(ap, int);
|
||||
void char_db_setoffline( std::shared_ptr<struct online_char_data> character, int server ){
|
||||
if (server == -1) {
|
||||
character->char_id = -1;
|
||||
character->server = -1;
|
||||
@@ -210,28 +215,17 @@ int char_db_setoffline(DBKey key, DBData *data, va_list ap) {
|
||||
}
|
||||
} else if (character->server == server)
|
||||
character->server = -2; //In some map server that we aren't connected to.
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBApply
|
||||
*/
|
||||
int char_db_kickoffline(DBKey key, DBData *data, va_list ap){
|
||||
struct online_char_data* character = (struct online_char_data*)db_data2ptr(data);
|
||||
int server_id = va_arg(ap, int);
|
||||
|
||||
void char_db_kickoffline( std::shared_ptr<struct online_char_data> character, int server_id ){
|
||||
if (server_id > -1 && character->server != server_id)
|
||||
return 0;
|
||||
return;
|
||||
|
||||
//Kick out any connected characters, and set them offline as appropriate.
|
||||
if (character->server > -1)
|
||||
mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 1);
|
||||
else if (character->waiting_disconnect == INVALID_TIMER)
|
||||
char_set_char_offline(character->char_id, character->account_id);
|
||||
else
|
||||
return 0; // fail
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void char_set_all_offline(int id){
|
||||
@@ -239,7 +233,10 @@ void char_set_all_offline(int id){
|
||||
ShowNotice("Sending all users offline.\n");
|
||||
else
|
||||
ShowNotice("Sending users of map-server %d offline.\n",id);
|
||||
online_char_db->foreach(online_char_db,char_db_kickoffline,id);
|
||||
|
||||
for( const auto& pair : char_get_onlinedb() ){
|
||||
char_db_kickoffline( pair.second, id );
|
||||
}
|
||||
|
||||
if (id >= 0 || !chlogif_isconnected())
|
||||
return;
|
||||
@@ -255,28 +252,23 @@ void char_set_all_offline_sql(void){
|
||||
Sql_ShowDebug(sql_handle);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBCreateData
|
||||
*/
|
||||
DBData char_create_charstatus(DBKey key, va_list args) {
|
||||
struct mmo_charstatus *cp;
|
||||
cp = (struct mmo_charstatus *) aCalloc(1,sizeof(struct mmo_charstatus));
|
||||
cp->char_id = key.i;
|
||||
return db_ptr2data(cp);
|
||||
}
|
||||
|
||||
int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
|
||||
int i = 0;
|
||||
int count = 0;
|
||||
int diff = 0;
|
||||
char save_status[128]; //For displaying save information. [Skotlex]
|
||||
struct mmo_charstatus *cp;
|
||||
int errors = 0; //If there are any errors while saving, "cp" will not be updated at the end.
|
||||
StringBuf buf;
|
||||
|
||||
if (char_id!=p->char_id) return 0;
|
||||
|
||||
cp = (struct mmo_charstatus *)idb_ensure(char_db_, char_id, char_create_charstatus);
|
||||
std::shared_ptr<struct mmo_charstatus> cp = util::umap_find( char_get_chardb(), char_id );
|
||||
|
||||
if( cp == nullptr ){
|
||||
cp = std::make_shared<struct mmo_charstatus>();
|
||||
cp->char_id = char_id;
|
||||
char_get_chardb()[cp->char_id] = cp;
|
||||
}
|
||||
|
||||
StringBuf_Init(&buf);
|
||||
memset(save_status, 0, sizeof(save_status));
|
||||
@@ -524,8 +516,11 @@ int char_mmo_char_tosql(uint32 char_id, struct mmo_charstatus* p){
|
||||
StringBuf_Destroy(&buf);
|
||||
if (save_status[0]!='\0' && charserv_config.save_log)
|
||||
ShowInfo("Saved char %d - %s:%s.\n", char_id, p->name, save_status);
|
||||
if (!errors)
|
||||
memcpy(cp, p, sizeof(struct mmo_charstatus));
|
||||
|
||||
if( !errors ){
|
||||
memcpy( cp.get(), p, sizeof( struct mmo_charstatus ) );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1033,7 +1028,6 @@ int char_mmo_chars_fromsql(struct char_session_data* sd, uint8* buf, uint8* coun
|
||||
//=====================================================================================================
|
||||
int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_everything) {
|
||||
int i;
|
||||
struct mmo_charstatus* cp;
|
||||
SqlStmt* stmt;
|
||||
char last_map[MAP_NAME_LENGTH_EXT];
|
||||
char save_map[MAP_NAME_LENGTH_EXT];
|
||||
@@ -1271,16 +1265,22 @@ int char_mmo_char_fromsql(uint32 char_id, struct mmo_charstatus* p, bool load_ev
|
||||
ShowInfo("Loaded char (%d - %s): %s\n", char_id, p->name, StringBuf_Value(&msg_buf)); //ok. all data load successfully!
|
||||
SqlStmt_Free(stmt);
|
||||
|
||||
cp = (struct mmo_charstatus *)idb_ensure(char_db_, char_id, char_create_charstatus);
|
||||
memcpy(cp, p, sizeof(struct mmo_charstatus));
|
||||
std::shared_ptr<struct mmo_charstatus> cp = util::umap_find( char_get_chardb(), char_id );
|
||||
|
||||
if( cp == nullptr ){
|
||||
cp = std::make_shared<struct mmo_charstatus>();
|
||||
cp->char_id = char_id;
|
||||
char_get_chardb()[cp->char_id] = cp;
|
||||
}
|
||||
|
||||
memcpy( cp.get(), p, sizeof( struct mmo_charstatus ) );
|
||||
|
||||
StringBuf_Destroy(&msg_buf);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//==========================================================================================================
|
||||
int char_mmo_sql_init(void) {
|
||||
char_db_= idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
|
||||
ShowStatus("Characters per Account: '%d'.\n", charserv_config.char_config.char_per_account);
|
||||
|
||||
//the 'set offline' part is now in check_login_conn ...
|
||||
@@ -1998,10 +1998,10 @@ void char_set_session_flag_(int account_id, int val, bool set) {
|
||||
}
|
||||
|
||||
void char_auth_ok(int fd, struct char_session_data *sd) {
|
||||
struct online_char_data* character;
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), sd->account_id );
|
||||
|
||||
if( (character = (struct online_char_data*)idb_get(online_char_db, sd->account_id)) != NULL )
|
||||
{ // check if character is not online already. [Skotlex]
|
||||
// Check if character is not online already. [Skotlex]
|
||||
if( character != nullptr ){
|
||||
if (character->server > -1)
|
||||
{ //Character already online. KICK KICK KICK
|
||||
mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
|
||||
@@ -2206,33 +2206,38 @@ void char_pincode_decrypt( uint32 userSeed, char* pin ){
|
||||
//replies/disconnect the player we tried to kick. [Skotlex]
|
||||
//------------------------------------------------
|
||||
TIMER_FUNC(char_chardb_waiting_disconnect){
|
||||
struct online_char_data* character;
|
||||
if ((character = (struct online_char_data*)idb_get(online_char_db, id)) != NULL && character->waiting_disconnect == tid)
|
||||
{ //Mark it offline due to timeout.
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), static_cast<uint32>( id ) );
|
||||
|
||||
// Mark it offline due to timeout.
|
||||
if( character != nullptr && character->waiting_disconnect == tid ){
|
||||
character->waiting_disconnect = INVALID_TIMER;
|
||||
char_set_char_offline(character->char_id, character->account_id);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBApply
|
||||
*/
|
||||
int char_online_data_cleanup_sub(DBKey key, DBData *data, va_list ap)
|
||||
{
|
||||
struct online_char_data *character= (struct online_char_data *)db_data2ptr(data);
|
||||
if (character->fd != -1)
|
||||
return 0; //Character still connected
|
||||
if (character->server == -2) //Unknown server.. set them offline
|
||||
char_set_char_offline(character->char_id, character->account_id);
|
||||
if (character->server < 0)
|
||||
//Free data from players that have not been online for a while.
|
||||
db_remove(online_char_db, key);
|
||||
return 0;
|
||||
}
|
||||
|
||||
TIMER_FUNC(char_online_data_cleanup){
|
||||
online_char_db->foreach(online_char_db, char_online_data_cleanup_sub);
|
||||
for( auto it = char_get_onlinedb().begin(); it != char_get_onlinedb().end(); ){
|
||||
std::shared_ptr<struct online_char_data> character = it->second;
|
||||
|
||||
// Character still connected
|
||||
if( character->fd != -1 ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Unknown server - set them offline
|
||||
if( character->server == -2 ){
|
||||
char_set_char_offline( character->char_id, character->account_id );
|
||||
}
|
||||
|
||||
// Free data from players that have not been online for a while.
|
||||
if( character->server < 0 ){
|
||||
it = char_get_onlinedb().erase( it );
|
||||
}else{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2380,7 +2385,7 @@ bool char_checkdb(void){
|
||||
return false;
|
||||
}
|
||||
//checking scdata_db
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`type`,`tick`,`val1`,`val2`,`val3`,`val4`"
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`char_id`,`type`,`tick`,`tick_total`,`tick_time`,`val1`,`val2`,`val3`,`val4`"
|
||||
" FROM `%s` LIMIT 1;", schema_config.scdata_db) ){
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return false;
|
||||
@@ -2820,6 +2825,8 @@ void char_set_defaults(){
|
||||
#else
|
||||
charserv_config.allowed_job_flag = 1;
|
||||
#endif
|
||||
|
||||
charserv_config.clear_parties = 0;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -3107,6 +3114,8 @@ bool char_config_read(const char* cfgName, bool normal){
|
||||
charserv_config.mail_return_empty = config_switch(w2);
|
||||
} else if (strcmpi(w1, "allowed_job_flag") == 0) {
|
||||
charserv_config.allowed_job_flag = atoi(w2);
|
||||
} else if (strcmpi(w1, "clear_parties") == 0) {
|
||||
charserv_config.clear_parties = config_switch(w2);
|
||||
} else if (strcmpi(w1, "import") == 0) {
|
||||
char_config_read(w2, normal);
|
||||
}
|
||||
@@ -3142,9 +3151,7 @@ void char_do_final_msg(void){
|
||||
_do_final_msg(CHAR_MAX_MSG,msg_table);
|
||||
}
|
||||
|
||||
|
||||
void do_final(void)
|
||||
{
|
||||
void CharacterServer::finalize(){
|
||||
ShowStatus("Terminating...\n");
|
||||
|
||||
char_set_all_offline(-1);
|
||||
@@ -3158,9 +3165,9 @@ void do_final(void)
|
||||
do_final_chmapif();
|
||||
do_final_chlogif();
|
||||
|
||||
char_db_->destroy(char_db_, NULL);
|
||||
online_char_db->destroy(online_char_db, NULL);
|
||||
auth_db->destroy(auth_db, NULL);
|
||||
char_get_chardb().clear();
|
||||
char_get_onlinedb().clear();
|
||||
char_get_authdb().clear();
|
||||
|
||||
if( char_fd != -1 )
|
||||
{
|
||||
@@ -3174,40 +3181,17 @@ void do_final(void)
|
||||
ShowStatus("Finished.\n");
|
||||
}
|
||||
|
||||
|
||||
void set_server_type(void){
|
||||
SERVER_TYPE = ATHENA_SERVER_CHAR;
|
||||
}
|
||||
|
||||
//------------------------------
|
||||
// Function called when the server
|
||||
// has received a crash signal.
|
||||
//------------------------------
|
||||
void do_abort(void)
|
||||
{
|
||||
}
|
||||
|
||||
/// Called when a terminate signal is received.
|
||||
void do_shutdown(void) {
|
||||
if( runflag != CHARSERVER_ST_SHUTDOWN )
|
||||
{
|
||||
int id;
|
||||
runflag = CHARSERVER_ST_SHUTDOWN;
|
||||
ShowStatus("Shutting down...\n");
|
||||
// TODO proper shutdown procedure; wait for acks?, kick all characters, ... [FlavoJS]
|
||||
for( id = 0; id < ARRAYLENGTH(map_server); ++id )
|
||||
chmapif_server_reset(id);
|
||||
chlogif_check_shutdown();
|
||||
flush_fifos();
|
||||
runflag = CORE_ST_STOP;
|
||||
}
|
||||
void CharacterServer::handle_shutdown(){
|
||||
ShowStatus("Shutting down...\n");
|
||||
// TODO proper shutdown procedure; wait for acks?, kick all characters, ... [FlavoJS]
|
||||
for( int id = 0; id < ARRAYLENGTH(map_server); ++id )
|
||||
chmapif_server_reset(id);
|
||||
flush_fifos();
|
||||
}
|
||||
|
||||
|
||||
int do_init(int argc, char **argv)
|
||||
{
|
||||
bool CharacterServer::initialize( int argc, char *argv[] ){
|
||||
//Read map indexes
|
||||
runflag = CHARSERVER_ST_STARTING;
|
||||
mapindex_init();
|
||||
|
||||
// Init default value
|
||||
@@ -3227,17 +3211,16 @@ int do_init(int argc, char **argv)
|
||||
char_sql_config_read(SQL_CONF_NAME);
|
||||
msg_config_read(MSG_CONF_NAME_EN);
|
||||
|
||||
// Skip this check if the server is run with run-once flag
|
||||
if (runflag!=CORE_ST_STOP && strcmp(charserv_config.userid, "s1")==0 && strcmp(charserv_config.passwd, "p1")==0) {
|
||||
#if !defined(BUILDBOT)
|
||||
if (strcmp(charserv_config.userid, "s1")==0 && strcmp(charserv_config.passwd, "p1")==0) {
|
||||
ShowWarning("Using the default user/password s1/p1 is NOT RECOMMENDED.\n");
|
||||
ShowNotice("Please edit your 'login' table to create a proper inter-server user/password (gender 'S')\n");
|
||||
ShowNotice("And then change the user/password to use in conf/char_athena.conf (or conf/import/char_conf.txt)\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
inter_init_sql((argc > 2) ? argv[2] : SQL_CONF_NAME); // inter server configuration
|
||||
|
||||
auth_db = idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
online_char_db = idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
char_mmo_sql_init();
|
||||
char_read_fame_list(); //Read fame lists.
|
||||
|
||||
@@ -3289,7 +3272,7 @@ int do_init(int argc, char **argv)
|
||||
//check db tables
|
||||
if(charserv_config.char_check_db && char_checkdb() == 0){
|
||||
ShowFatalError("char : A tables is missing in sql-server, please fix it, see (sql-files main.sql for structure) \n");
|
||||
exit(EXIT_FAILURE);
|
||||
return false;
|
||||
}
|
||||
//Cleaning the tables for NULL entrys @ startup [Sirius]
|
||||
//Chardb clean
|
||||
@@ -3308,13 +3291,7 @@ int do_init(int argc, char **argv)
|
||||
|
||||
if( (char_fd = make_listen_bind(charserv_config.bind_ip,charserv_config.char_port)) == -1 ) {
|
||||
ShowFatalError("Failed to bind to port '" CL_WHITE "%d" CL_RESET "'\n",charserv_config.char_port);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if( runflag != CORE_ST_STOP )
|
||||
{
|
||||
shutdown_callback = do_shutdown;
|
||||
runflag = CHARSERVER_ST_RUNNING;
|
||||
return false;
|
||||
}
|
||||
|
||||
do_init_chcnslif();
|
||||
@@ -3323,5 +3300,9 @@ int do_init(int argc, char **argv)
|
||||
|
||||
ShowStatus("The char-server is " CL_GREEN "ready" CL_RESET " (Server is listening on the port %d).\n\n", charserv_config.char_port);
|
||||
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] ){
|
||||
return main_core<CharacterServer>( argc, argv );
|
||||
}
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#ifndef CHAR_HPP
|
||||
#define CHAR_HPP
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include "../common/core.hpp" // CORE_ST_LAST
|
||||
@@ -14,19 +16,31 @@
|
||||
|
||||
#include "packets.hpp"
|
||||
|
||||
using rathena::server_core::Core;
|
||||
using rathena::server_core::e_core_type;
|
||||
|
||||
namespace rathena{
|
||||
namespace server_character{
|
||||
class CharacterServer : public Core{
|
||||
protected:
|
||||
bool initialize( int argc, char* argv[] ) override;
|
||||
void finalize() override;
|
||||
void handle_shutdown() override;
|
||||
|
||||
public:
|
||||
CharacterServer() : Core( e_core_type::CHARACTER ){
|
||||
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
extern int login_fd; //login file descriptor
|
||||
extern int char_fd; //char file descriptor
|
||||
|
||||
#define MAX_STARTPOINT 5
|
||||
#define MAX_STARTITEM 32
|
||||
|
||||
enum E_CHARSERVER_ST {
|
||||
CHARSERVER_ST_RUNNING = CORE_ST_LAST,
|
||||
CHARSERVER_ST_STARTING,
|
||||
CHARSERVER_ST_SHUTDOWN,
|
||||
CHARSERVER_ST_LAST
|
||||
};
|
||||
|
||||
enum e_char_delete {
|
||||
CHAR_DEL_EMAIL = 1,
|
||||
CHAR_DEL_BIRTHDATE
|
||||
@@ -194,6 +208,7 @@ struct CharServ_Config {
|
||||
int mail_return_empty;
|
||||
|
||||
int allowed_job_flag;
|
||||
int clear_parties;
|
||||
};
|
||||
extern struct CharServ_Config charserv_config;
|
||||
|
||||
@@ -220,7 +235,8 @@ struct auth_node {
|
||||
unsigned changing_mapservers : 1;
|
||||
uint8 version;
|
||||
};
|
||||
DBMap* char_get_authdb(); // uint32 account_id -> struct auth_node*
|
||||
|
||||
std::unordered_map<uint32, std::shared_ptr<struct auth_node>>& char_get_authdb();
|
||||
|
||||
struct online_char_data {
|
||||
uint32 account_id;
|
||||
@@ -229,8 +245,12 @@ struct online_char_data {
|
||||
int waiting_disconnect;
|
||||
short server; // -2: unknown server, -1: not connected, 0+: id of server
|
||||
bool pincode_success;
|
||||
|
||||
public:
|
||||
online_char_data( uint32 account_id );
|
||||
};
|
||||
DBMap* char_get_onlinedb(); // uint32 account_id -> struct online_char_data*
|
||||
|
||||
std::unordered_map<uint32, std::shared_ptr<struct online_char_data>>& char_get_onlinedb();
|
||||
|
||||
struct char_session_data {
|
||||
bool auth; // whether the session is authed or not
|
||||
@@ -258,9 +278,7 @@ struct char_session_data {
|
||||
uint8 flag; // &1 - Retrieving guild bound items
|
||||
};
|
||||
|
||||
|
||||
struct mmo_charstatus;
|
||||
DBMap* char_get_chardb(); // uint32 char_id -> struct mmo_charstatus*
|
||||
std::unordered_map<uint32, std::shared_ptr<struct mmo_charstatus>>& char_get_chardb();
|
||||
|
||||
//Custom limits for the fame lists. [Skotlex]
|
||||
extern int fame_list_size_chemist;
|
||||
@@ -278,8 +296,7 @@ int char_search_mapserver(unsigned short map, uint32 ip, uint16 port);
|
||||
int char_lan_subnetcheck(uint32 ip);
|
||||
|
||||
int char_count_users(void);
|
||||
DBData char_create_online_data(DBKey key, va_list args);
|
||||
int char_db_setoffline(DBKey key, DBData *data, va_list ap);
|
||||
void char_db_setoffline( std::shared_ptr<struct online_char_data> character, int server );
|
||||
void char_set_char_online(int map_id, uint32 char_id, uint32 account_id);
|
||||
void char_set_char_offline(uint32 char_id, uint32 account_id);
|
||||
void char_set_all_offline(int id);
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "char_clif.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -15,6 +18,7 @@
|
||||
#include "../common/sql.hpp"
|
||||
#include "../common/strlib.hpp"
|
||||
#include "../common/timer.hpp"
|
||||
#include "../common/utilities.hpp"
|
||||
#include "../common/utils.hpp"
|
||||
|
||||
#include "char.hpp"
|
||||
@@ -23,6 +27,8 @@
|
||||
#include "inter.hpp"
|
||||
#include "packets.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
#if PACKETVER_SUPPORTS_PINCODE
|
||||
bool pincode_allowed( char* pincode );
|
||||
#endif
|
||||
@@ -674,7 +680,7 @@ int chclif_parse_maplogin(int fd){
|
||||
l_user[23] = '\0';
|
||||
l_pass[23] = '\0';
|
||||
ARR_FIND( 0, ARRAYLENGTH(map_server), i, map_server[i].fd <= 0 );
|
||||
if( runflag != CHARSERVER_ST_RUNNING ||
|
||||
if( !global_core->is_running() ||
|
||||
i == ARRAYLENGTH(map_server) ||
|
||||
strcmp(l_user, charserv_config.userid) != 0 ||
|
||||
strcmp(l_pass, charserv_config.passwd) != 0 )
|
||||
@@ -703,9 +709,6 @@ int chclif_parse_reqtoconnect(int fd, struct char_session_data* sd,uint32 ipl){
|
||||
if( RFIFOREST(fd) < 17 ) // request to connect
|
||||
return 0;
|
||||
else {
|
||||
struct auth_node* node;
|
||||
DBMap *auth_db = char_get_authdb();
|
||||
|
||||
uint32 account_id = RFIFOL(fd,2);
|
||||
uint32 login_id1 = RFIFOL(fd,6);
|
||||
uint32 login_id2 = RFIFOL(fd,10);
|
||||
@@ -735,20 +738,21 @@ int chclif_parse_reqtoconnect(int fd, struct char_session_data* sd,uint32 ipl){
|
||||
WFIFOL(fd,0) = account_id;
|
||||
WFIFOSET(fd,4);
|
||||
|
||||
if( runflag != CHARSERVER_ST_RUNNING ) {
|
||||
if( !global_core->is_running() ){
|
||||
chclif_reject(fd, 0); // rejected from server
|
||||
return 1;
|
||||
}
|
||||
|
||||
// search authentification
|
||||
node = (struct auth_node*)idb_get(auth_db, account_id);
|
||||
if( node != NULL &&
|
||||
std::shared_ptr<struct auth_node> node = util::umap_find( char_get_authdb(), account_id);
|
||||
|
||||
if( node != nullptr &&
|
||||
node->account_id == account_id &&
|
||||
node->login_id1 == login_id1 &&
|
||||
node->login_id2 == login_id2 /*&&
|
||||
node->ip == ipl*/ )
|
||||
{// authentication found (coming from map server)
|
||||
idb_remove(auth_db, account_id);
|
||||
char_get_authdb().erase(account_id);
|
||||
char_auth_ok(fd, sd);
|
||||
}
|
||||
else
|
||||
@@ -780,7 +784,7 @@ int chclif_parse_req_charlist(int fd, struct char_session_data* sd){
|
||||
}
|
||||
|
||||
//Send player to map
|
||||
void chclif_send_map_data( int fd, struct mmo_charstatus *cd, uint32 ipl, int map_server_index ){
|
||||
void chclif_send_map_data( int fd, std::shared_ptr<struct mmo_charstatus> cd, uint32 ipl, int map_server_index ){
|
||||
#if PACKETVER >= 20170315
|
||||
int cmd = 0xAC5;
|
||||
int size = 156;
|
||||
@@ -806,13 +810,9 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){
|
||||
FIFOSD_CHECK(3)
|
||||
{
|
||||
struct mmo_charstatus char_dat;
|
||||
struct mmo_charstatus *cd;
|
||||
char* data;
|
||||
uint32 char_id;
|
||||
struct auth_node* node;
|
||||
int i, map_fd, server_id;
|
||||
DBMap *auth_db = char_get_authdb();
|
||||
DBMap *char_db_ = char_get_chardb();
|
||||
|
||||
int slot = RFIFOB(fd,2);
|
||||
RFIFOSKIP(fd,3);
|
||||
@@ -864,7 +864,7 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){
|
||||
}
|
||||
|
||||
//Have to switch over to the DB instance otherwise data won't propagate [Kevin]
|
||||
cd = (struct mmo_charstatus *)idb_get(char_db_, char_id);
|
||||
std::shared_ptr<struct mmo_charstatus> cd = util::umap_find( char_get_chardb(), char_id );
|
||||
|
||||
if (charserv_config.log_char) {
|
||||
char esc_name[NAME_LENGTH*2+1];
|
||||
@@ -930,7 +930,8 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){
|
||||
chclif_send_map_data( fd, cd, ipl, i );
|
||||
|
||||
// create temporary auth entry
|
||||
CREATE(node, struct auth_node, 1);
|
||||
std::shared_ptr<struct auth_node> node = std::make_shared<struct auth_node>();
|
||||
|
||||
node->account_id = sd->account_id;
|
||||
node->char_id = cd->char_id;
|
||||
node->login_id1 = sd->login_id1;
|
||||
@@ -939,8 +940,8 @@ int chclif_parse_charselect(int fd, struct char_session_data* sd,uint32 ipl){
|
||||
node->expiration_time = sd->expiration_time;
|
||||
node->group_id = sd->group_id;
|
||||
node->ip = ipl;
|
||||
idb_put(auth_db, sd->account_id, node);
|
||||
|
||||
char_get_authdb()[node->account_id] = node;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1363,12 +1364,16 @@ int chclif_parse(int fd) {
|
||||
|
||||
if(session[fd]->flag.eof) {
|
||||
if( sd != NULL && sd->auth ) { // already authed client
|
||||
DBMap *online_char_db = char_get_onlinedb();
|
||||
struct online_char_data* data = (struct online_char_data*)idb_get(online_char_db, sd->account_id);
|
||||
if( data != NULL && data->fd == fd)
|
||||
std::shared_ptr<struct online_char_data> data = util::umap_find( char_get_onlinedb(), sd->account_id );
|
||||
|
||||
if( data != nullptr && data->fd == fd ){
|
||||
data->fd = -1;
|
||||
if( data == NULL || data->server == -1) //If it is not in any server, send it offline. [Skotlex]
|
||||
}
|
||||
|
||||
// If it is not in any server, send it offline. [Skotlex]
|
||||
if( data == nullptr || data->server == -1 ){
|
||||
char_set_char_offline(-1,sd->account_id);
|
||||
}
|
||||
}
|
||||
do_close(fd);
|
||||
return 0;
|
||||
|
||||
@@ -74,7 +74,7 @@ int cnslif_parse(const char* buf)
|
||||
|
||||
if( n == 2 && strcmpi("server", type) == 0 ){
|
||||
if( strcmpi("shutdown", command) == 0 || strcmpi("exit", command) == 0 || strcmpi("quit", command) == 0 ){
|
||||
runflag = 0;
|
||||
global_core->signal_shutdown();
|
||||
}
|
||||
else if( strcmpi("alive", command) == 0 || strcmpi("status", command) == 0 )
|
||||
ShowInfo(CL_CYAN "Console: " CL_BOLD "I'm Alive." CL_RESET "\n");
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "char_logif.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -11,6 +13,7 @@
|
||||
#include "../common/sql.hpp"
|
||||
#include "../common/strlib.hpp"
|
||||
#include "../common/timer.hpp"
|
||||
#include "../common/utilities.hpp"
|
||||
#include "../common/utils.hpp"
|
||||
|
||||
#include "char.hpp"
|
||||
@@ -19,6 +22,8 @@
|
||||
#include "inter.hpp"
|
||||
#include "int_guild.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
//early declaration
|
||||
void chlogif_on_ready(void);
|
||||
void chlogif_on_disconnect(void);
|
||||
@@ -59,10 +64,9 @@ void chlogif_pincode_start(int fd, struct char_session_data* sd){
|
||||
}else{
|
||||
if( !(charserv_config.pincode_config.pincode_changetime)
|
||||
|| ( sd->pincode_change + charserv_config.pincode_config.pincode_changetime ) > time(NULL) ){
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
struct online_char_data* node = (struct online_char_data*)idb_get( online_char_db, sd->account_id );
|
||||
std::shared_ptr<struct online_char_data> node = util::umap_find( char_get_onlinedb(), sd->account_id );
|
||||
|
||||
if( node != NULL && node->pincode_success ){
|
||||
if( node != nullptr && node->pincode_success ){
|
||||
// User has already passed the check
|
||||
chclif_pincode_sendstate( fd, sd, PINCODE_PASSED );
|
||||
}else{
|
||||
@@ -82,21 +86,6 @@ void chlogif_pincode_start(int fd, struct char_session_data* sd){
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Load this character's account id into the 'online accounts' packet
|
||||
* @see DBApply
|
||||
*/
|
||||
int chlogif_send_acc_tologin_sub(DBKey key, DBData *data, va_list ap) {
|
||||
struct online_char_data* character = (struct online_char_data*)db_data2ptr(data);
|
||||
int* i = va_arg(ap, int*);
|
||||
if(character->server > -1) {
|
||||
WFIFOL(login_fd,8+(*i)*4) = character->account_id;
|
||||
(*i)++;
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Timered function to send all account_id connected to login-serv
|
||||
* @param tid : Timer id
|
||||
@@ -107,14 +96,20 @@ int chlogif_send_acc_tologin_sub(DBKey key, DBData *data, va_list ap) {
|
||||
*/
|
||||
TIMER_FUNC(chlogif_send_acc_tologin){
|
||||
if ( chlogif_isconnected() ){
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
// send account list to login server
|
||||
int users = online_char_db->size(online_char_db);
|
||||
int users = char_get_onlinedb().size();
|
||||
int i = 0;
|
||||
|
||||
WFIFOHEAD(login_fd,8+users*4);
|
||||
WFIFOW(login_fd,0) = 0x272d;
|
||||
online_char_db->foreach(online_char_db, chlogif_send_acc_tologin_sub, &i, users);
|
||||
for( const auto& pair : char_get_onlinedb() ){
|
||||
std::shared_ptr<struct online_char_data> character = pair.second;
|
||||
|
||||
if( character->server > -1 ){
|
||||
WFIFOL( login_fd, 8 + i * 4 ) = character->account_id;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
WFIFOW(login_fd,2) = 8+ i*4;
|
||||
WFIFOL(login_fd,4) = i;
|
||||
WFIFOSET(login_fd,WFIFOW(login_fd,2));
|
||||
@@ -434,18 +429,17 @@ int chlogif_parse_ackchangesex(int fd)
|
||||
return 0;
|
||||
else {
|
||||
unsigned char buf[7];
|
||||
int acc = RFIFOL(fd,2);
|
||||
uint32 acc = RFIFOL(fd,2);
|
||||
int sex = RFIFOB(fd,6);
|
||||
RFIFOSKIP(fd,7);
|
||||
|
||||
if (acc > 0) { // TODO: Is this even possible?
|
||||
unsigned char i;
|
||||
int char_id = 0, class_ = 0, guild_id = 0;
|
||||
DBMap* auth_db = char_get_authdb();
|
||||
struct auth_node* node = (struct auth_node*)idb_get(auth_db, acc);
|
||||
std::shared_ptr<struct auth_node> node = util::umap_find( char_get_authdb(), acc );
|
||||
SqlStmt *stmt;
|
||||
|
||||
if (node != NULL)
|
||||
if (node != nullptr)
|
||||
node->sex = sex;
|
||||
|
||||
// get characters
|
||||
@@ -550,13 +544,13 @@ int chlogif_parse_askkick(int fd){
|
||||
if (RFIFOREST(fd) < 6)
|
||||
return 0;
|
||||
else {
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
DBMap* auth_db = char_get_authdb();
|
||||
int aid = RFIFOL(fd,2);
|
||||
struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, aid);
|
||||
uint32 aid = RFIFOL(fd,2);
|
||||
RFIFOSKIP(fd,6);
|
||||
if( character != NULL )
|
||||
{// account is already marked as online!
|
||||
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), aid );
|
||||
|
||||
// account is already marked as online!
|
||||
if( character != nullptr ){
|
||||
if( character->server > -1 )
|
||||
{ //Kick it from the map server it is on.
|
||||
mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
|
||||
@@ -577,7 +571,9 @@ int chlogif_parse_askkick(int fd){
|
||||
char_set_char_offline(-1, aid);
|
||||
}
|
||||
}
|
||||
idb_remove(auth_db, aid);// reject auth attempts from map-server
|
||||
|
||||
// reject auth attempts from map-server
|
||||
char_get_authdb().erase( aid );
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -813,16 +809,6 @@ void chlogif_reset(void){
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
/// Checks the conditions for the server to stop.
|
||||
/// Releases the cookie when all characters are saved.
|
||||
/// If all the conditions are met, it stops the core loop.
|
||||
void chlogif_check_shutdown(void)
|
||||
{
|
||||
if( runflag != CHARSERVER_ST_SHUTDOWN )
|
||||
return;
|
||||
runflag = CORE_ST_STOP;
|
||||
}
|
||||
|
||||
/// Called when the connection to Login Server is disconnected.
|
||||
void chlogif_on_disconnect(void){
|
||||
ShowWarning("Connection to Login Server lost.\n\n");
|
||||
@@ -833,8 +819,6 @@ void chlogif_on_ready(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
chlogif_check_shutdown();
|
||||
|
||||
//Send online accounts to login server.
|
||||
chlogif_send_acc_tologin(INVALID_TIMER, gettick(), 0, 0);
|
||||
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "char_mapif.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h> //memcpy
|
||||
|
||||
@@ -12,11 +14,14 @@
|
||||
#include "../common/sql.hpp"
|
||||
#include "../common/strlib.hpp"
|
||||
#include "../common/timer.hpp"
|
||||
#include "../common/utilities.hpp"
|
||||
|
||||
#include "char.hpp"
|
||||
#include "char_logif.hpp"
|
||||
#include "inter.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
/**
|
||||
* Packet send to all map-servers, attach to ourself
|
||||
* @param buf: packet to send in form of an array buffer
|
||||
@@ -279,7 +284,7 @@ int chmapif_parse_askscdata(int fd){
|
||||
int aid, cid;
|
||||
aid = RFIFOL(fd,2);
|
||||
cid = RFIFOL(fd,6);
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4 from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT type, tick, val1, val2, val3, val4, tick_total, tick_time from `%s` WHERE `account_id` = '%d' AND `char_id`='%d'",
|
||||
schema_config.scdata_db, aid, cid) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
@@ -303,6 +308,8 @@ int chmapif_parse_askscdata(int fd){
|
||||
Sql_GetData(sql_handle, 3, &data, NULL); scdata.val2 = atoi(data);
|
||||
Sql_GetData(sql_handle, 4, &data, NULL); scdata.val3 = atoi(data);
|
||||
Sql_GetData(sql_handle, 5, &data, NULL); scdata.val4 = atoi(data);
|
||||
Sql_GetData(sql_handle, 6, &data, NULL); scdata.tick_total = strtoll(data, nullptr, 10);
|
||||
Sql_GetData(sql_handle, 7, &data, NULL); scdata.tick_time = strtoll(data, nullptr, 10);
|
||||
memcpy(WFIFOP(fd, 14+count*sizeof(struct status_change_data)), &scdata, sizeof(struct status_change_data));
|
||||
}
|
||||
if (count >= 50)
|
||||
@@ -357,21 +364,29 @@ int chmapif_parse_regmapuser(int fd, int id){
|
||||
return 0;
|
||||
else {
|
||||
//TODO: When data mismatches memory, update guild/party online/offline states.
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
int i;
|
||||
|
||||
map_server[id].users = RFIFOW(fd,4);
|
||||
online_char_db->foreach(online_char_db,char_db_setoffline,id); //Set all chars from this server as 'unknown'
|
||||
for(i = 0; i < map_server[id].users; i++) {
|
||||
int aid = RFIFOL(fd,6+i*8);
|
||||
int cid = RFIFOL(fd,6+i*8+4);
|
||||
struct online_char_data* character = (struct online_char_data*)idb_ensure(online_char_db, aid, char_create_online_data);
|
||||
if( character->server > -1 && character->server != id )
|
||||
{
|
||||
ShowNotice("Set map user: Character (%d:%d) marked on map server %d, but map server %d claims to have (%d:%d) online!\n",
|
||||
character->account_id, character->char_id, character->server, id, aid, cid);
|
||||
mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
|
||||
|
||||
// Set all chars from this server as 'unknown'
|
||||
for( const auto& pair : char_get_onlinedb() ){
|
||||
char_db_setoffline( pair.second, id );
|
||||
}
|
||||
|
||||
for( int i = 0; i < map_server[id].users; i++ ){
|
||||
uint32 aid = RFIFOL(fd,6+i*8);
|
||||
uint32 cid = RFIFOL(fd,6+i*8+4);
|
||||
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), aid );
|
||||
|
||||
if( character != nullptr ){
|
||||
if( character->server > -1 && character->server != id ){
|
||||
ShowNotice("Set map user: Character (%d:%d) marked on map server %d, but map server %d claims to have (%d:%d) online!\n",
|
||||
character->account_id, character->char_id, character->server, id, aid, cid);
|
||||
mapif_disconnectplayer(map_server[character->server].fd, character->account_id, character->char_id, 2);
|
||||
}
|
||||
}else{
|
||||
character = std::make_shared<struct online_char_data>( aid );
|
||||
}
|
||||
|
||||
character->server = id;
|
||||
character->char_id = cid;
|
||||
}
|
||||
@@ -392,9 +407,8 @@ int chmapif_parse_reqsavechar(int fd, int id){
|
||||
if (RFIFOREST(fd) < 4 || RFIFOREST(fd) < RFIFOW(fd,2))
|
||||
return 0;
|
||||
else {
|
||||
int aid = RFIFOL(fd,4), cid = RFIFOL(fd,8), size = RFIFOW(fd,2);
|
||||
struct online_char_data* character;
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
uint32 aid = RFIFOL( fd, 4 ), cid = RFIFOL( fd, 8 );
|
||||
uint16 size = RFIFOW( fd, 2 );
|
||||
|
||||
if (size - 13 != sizeof(struct mmo_charstatus))
|
||||
{
|
||||
@@ -402,11 +416,11 @@ int chmapif_parse_reqsavechar(int fd, int id){
|
||||
RFIFOSKIP(fd,size);
|
||||
return 1;
|
||||
}
|
||||
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), aid );
|
||||
|
||||
//Check account only if this ain't final save. Final-save goes through because of the char-map reconnect
|
||||
if (RFIFOB(fd,12) || RFIFOB(fd,13) || (
|
||||
(character = (struct online_char_data*)idb_get(online_char_db, aid)) != NULL &&
|
||||
character->char_id == cid))
|
||||
{
|
||||
if( RFIFOB( fd, 12 ) || RFIFOB( fd, 13 ) || ( character != nullptr && character->char_id == cid ) ){
|
||||
struct mmo_charstatus char_dat;
|
||||
memcpy(&char_dat, RFIFOP(fd,13), sizeof(struct mmo_charstatus));
|
||||
char_mmo_char_tosql(cid, &char_dat);
|
||||
@@ -458,15 +472,12 @@ int chmapif_parse_authok(int fd){
|
||||
uint32 ip = RFIFOL(fd,14);
|
||||
RFIFOSKIP(fd,18);
|
||||
|
||||
if( runflag != CHARSERVER_ST_RUNNING ){
|
||||
if( !global_core->is_running() ){
|
||||
chmapif_charselres(fd,account_id,0);
|
||||
}else{
|
||||
struct auth_node* node;
|
||||
DBMap* auth_db = char_get_authdb();
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
|
||||
// create temporary auth entry
|
||||
CREATE(node, struct auth_node, 1);
|
||||
std::shared_ptr<struct auth_node> node = std::make_shared<struct auth_node>();
|
||||
|
||||
node->account_id = account_id;
|
||||
node->char_id = 0;
|
||||
node->login_id1 = login_id1;
|
||||
@@ -475,16 +486,18 @@ int chmapif_parse_authok(int fd){
|
||||
node->ip = ntohl(ip);
|
||||
//node->expiration_time = 0; // unlimited/unknown time by default (not display in map-server)
|
||||
//node->gmlevel = 0;
|
||||
idb_put(auth_db, account_id, node);
|
||||
|
||||
char_get_authdb()[node->account_id] = node;
|
||||
|
||||
//Set char to "@ char select" in online db [Kevin]
|
||||
char_set_charselect(account_id);
|
||||
{
|
||||
struct online_char_data* character = (struct online_char_data*)idb_get(online_char_db, account_id);
|
||||
if( character != NULL ){
|
||||
character->pincode_success = true;
|
||||
}
|
||||
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), account_id );
|
||||
|
||||
if( character != nullptr ){
|
||||
character->pincode_success = true;
|
||||
}
|
||||
|
||||
chmapif_charselres(fd,account_id,1);
|
||||
}
|
||||
}
|
||||
@@ -596,30 +609,28 @@ int chmapif_parse_reqchangemapserv(int fd){
|
||||
return 0;
|
||||
else {
|
||||
int map_id, map_fd = -1;
|
||||
struct mmo_charstatus* char_data;
|
||||
struct mmo_charstatus char_dat;
|
||||
DBMap* char_db_ = char_get_chardb();
|
||||
|
||||
map_id = char_search_mapserver(RFIFOW(fd,18), ntohl(RFIFOL(fd,24)), ntohs(RFIFOW(fd,28))); //Locate mapserver by ip and port.
|
||||
if (map_id >= 0)
|
||||
map_fd = map_server[map_id].fd;
|
||||
//Char should just had been saved before this packet, so this should be safe. [Skotlex]
|
||||
char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
|
||||
if (char_data == NULL) { //Really shouldn't happen.
|
||||
char_mmo_char_fromsql(RFIFOL(fd,14), &char_dat, true);
|
||||
char_data = (struct mmo_charstatus*)uidb_get(char_db_,RFIFOL(fd,14));
|
||||
|
||||
uint32 char_id = RFIFOL( fd, 14 );
|
||||
|
||||
// Char should just had been saved before this packet, so this should be safe. [Skotlex]
|
||||
std::shared_ptr<struct mmo_charstatus> char_data = util::umap_find( char_get_chardb(), char_id );
|
||||
|
||||
// Really shouldn't happen.
|
||||
if( char_data == nullptr ){
|
||||
char_mmo_char_fromsql( char_id, &char_dat, true );
|
||||
char_data = util::umap_find( char_get_chardb(), char_id );
|
||||
}
|
||||
|
||||
if( runflag == CHARSERVER_ST_RUNNING &&
|
||||
if( global_core->is_running() &&
|
||||
session_isActive(map_fd) &&
|
||||
char_data )
|
||||
{ //Send the map server the auth of this player.
|
||||
struct online_char_data* data;
|
||||
struct auth_node* node;
|
||||
DBMap* auth_db = char_get_authdb();
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
|
||||
int aid = RFIFOL(fd,2);
|
||||
uint32 aid = RFIFOL( fd, 2 );
|
||||
|
||||
//Update the "last map" as this is where the player must be spawned on the new map server.
|
||||
char_data->last_point.map = RFIFOW(fd,18);
|
||||
@@ -628,9 +639,10 @@ int chmapif_parse_reqchangemapserv(int fd){
|
||||
char_data->sex = RFIFOB(fd,30);
|
||||
|
||||
// create temporary auth entry
|
||||
CREATE(node, struct auth_node, 1);
|
||||
std::shared_ptr<struct auth_node> node = std::make_shared<struct auth_node>();
|
||||
|
||||
node->account_id = aid;
|
||||
node->char_id = RFIFOL(fd,14);
|
||||
node->char_id = char_id;
|
||||
node->login_id1 = RFIFOL(fd,6);
|
||||
node->login_id2 = RFIFOL(fd,10);
|
||||
node->sex = RFIFOB(fd,30);
|
||||
@@ -638,9 +650,15 @@ int chmapif_parse_reqchangemapserv(int fd){
|
||||
node->ip = ntohl(RFIFOL(fd,31));
|
||||
node->group_id = RFIFOL(fd,35);
|
||||
node->changing_mapservers = 1;
|
||||
idb_put(auth_db, aid, node);
|
||||
|
||||
data = (struct online_char_data*)idb_ensure(online_char_db, aid, char_create_online_data);
|
||||
char_get_authdb()[node->account_id] = node;
|
||||
|
||||
std::shared_ptr<struct online_char_data> data = util::umap_find( char_get_onlinedb(), aid );
|
||||
|
||||
if( data == nullptr ){
|
||||
data = std::make_shared<struct online_char_data>( aid );
|
||||
}
|
||||
|
||||
data->char_id = char_data->char_id;
|
||||
data->server = map_id; //Update server where char is.
|
||||
|
||||
@@ -942,14 +960,14 @@ int chmapif_parse_save_scdata(int fd){
|
||||
int i;
|
||||
|
||||
StringBuf_Init(&buf);
|
||||
StringBuf_Printf(&buf, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `val1`, `val2`, `val3`, `val4`) VALUES ", schema_config.scdata_db);
|
||||
StringBuf_Printf(&buf, "INSERT INTO `%s` (`account_id`, `char_id`, `type`, `tick`, `tick_total`, `tick_time`, `val1`, `val2`, `val3`, `val4`) VALUES ", schema_config.scdata_db);
|
||||
for( i = 0; i < count; ++i )
|
||||
{
|
||||
memcpy (&data, RFIFOP(fd, 14+i*sizeof(struct status_change_data)), sizeof(struct status_change_data));
|
||||
if( i > 0 )
|
||||
StringBuf_AppendStr(&buf, ", ");
|
||||
StringBuf_Printf(&buf, "('%d','%d','%hu','%" PRtf "','%ld','%ld','%ld','%ld')", aid, cid,
|
||||
data.type, data.tick, data.val1, data.val2, data.val3, data.val4);
|
||||
StringBuf_Printf(&buf, "('%d','%d','%hu','%" PRtf "','%" PRtf "','%" PRtf "','%ld','%ld','%ld','%ld')", aid, cid,
|
||||
data.type, data.tick, data.tick_total, data.tick_time, data.val1, data.val2, data.val3, data.val4);
|
||||
}
|
||||
if( SQL_ERROR == Sql_QueryStr(sql_handle, StringBuf_Value(&buf)) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
@@ -988,14 +1006,9 @@ int chmapif_parse_reqauth(int fd, int id){
|
||||
uint32 login_id1;
|
||||
unsigned char sex;
|
||||
uint32 ip;
|
||||
struct auth_node* node;
|
||||
struct mmo_charstatus* cd;
|
||||
struct mmo_charstatus char_dat;
|
||||
bool autotrade;
|
||||
|
||||
DBMap* auth_db = char_get_authdb();
|
||||
DBMap* char_db_ = char_get_chardb();
|
||||
|
||||
account_id = RFIFOL(fd,2);
|
||||
char_id = RFIFOL(fd,6);
|
||||
login_id1 = RFIFOL(fd,10);
|
||||
@@ -1004,14 +1017,16 @@ int chmapif_parse_reqauth(int fd, int id){
|
||||
autotrade = RFIFOB(fd,19) != 0;
|
||||
RFIFOSKIP(fd,20);
|
||||
|
||||
node = (struct auth_node*)idb_get(auth_db, account_id);
|
||||
cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
|
||||
if( cd == NULL )
|
||||
{ //Really shouldn't happen. (or autotrade)
|
||||
char_mmo_char_fromsql(char_id, &char_dat, true);
|
||||
cd = (struct mmo_charstatus*)uidb_get(char_db_,char_id);
|
||||
std::shared_ptr<struct auth_node> node = util::umap_find( char_get_authdb(), account_id );
|
||||
std::shared_ptr<struct mmo_charstatus> cd = util::umap_find( char_get_chardb(), char_id );
|
||||
|
||||
if( cd == nullptr ){
|
||||
// Really shouldn't happen. (or autotrade)
|
||||
char_mmo_char_fromsql( char_id, &char_dat, true );
|
||||
cd = util::umap_find( char_get_chardb(), char_id );
|
||||
}
|
||||
if( runflag == CHARSERVER_ST_RUNNING && autotrade && cd ){
|
||||
|
||||
if( global_core->is_running() && autotrade && cd ){
|
||||
uint16 mmo_charstatus_len = sizeof(struct mmo_charstatus) + 25;
|
||||
|
||||
WFIFOHEAD(fd,mmo_charstatus_len);
|
||||
@@ -1023,11 +1038,11 @@ int chmapif_parse_reqauth(int fd, int id){
|
||||
WFIFOL(fd,16) = 0;
|
||||
WFIFOL(fd,20) = 0;
|
||||
WFIFOB(fd,24) = 0;
|
||||
memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus));
|
||||
memcpy( WFIFOP( fd, 25 ), cd.get(), sizeof(struct mmo_charstatus));
|
||||
WFIFOSET(fd, WFIFOW(fd,2));
|
||||
|
||||
char_set_char_online(id, char_id, account_id);
|
||||
} else if( runflag == CHARSERVER_ST_RUNNING &&
|
||||
} else if( global_core->is_running() &&
|
||||
cd != NULL &&
|
||||
node != NULL &&
|
||||
node->account_id == account_id &&
|
||||
@@ -1050,11 +1065,11 @@ int chmapif_parse_reqauth(int fd, int id){
|
||||
WFIFOL(fd,16) = (uint32)node->expiration_time; // FIXME: will wrap to negative after "19-Jan-2038, 03:14:07 AM GMT"
|
||||
WFIFOL(fd,20) = node->group_id;
|
||||
WFIFOB(fd,24) = node->changing_mapservers;
|
||||
memcpy(WFIFOP(fd,25), cd, sizeof(struct mmo_charstatus));
|
||||
memcpy( WFIFOP( fd, 25 ), cd.get(), sizeof( struct mmo_charstatus ) );
|
||||
WFIFOSET(fd, WFIFOW(fd,2));
|
||||
|
||||
// only use the auth once and mark user online
|
||||
idb_remove(auth_db, account_id);
|
||||
char_get_authdb().erase( account_id );
|
||||
char_set_char_online(id, char_id, account_id);
|
||||
} else {// auth failed
|
||||
WFIFOHEAD(fd,19);
|
||||
@@ -1492,7 +1507,6 @@ void chmapif_server_reset(int id){
|
||||
int j = 0;
|
||||
unsigned char buf[16384];
|
||||
int fd = map_server[id].fd;
|
||||
DBMap* online_char_db = char_get_onlinedb();
|
||||
|
||||
//Notify other map servers that this one is gone. [Skotlex]
|
||||
WBUFW(buf,0) = 0x2b20;
|
||||
@@ -1505,7 +1519,12 @@ void chmapif_server_reset(int id){
|
||||
WBUFW(buf,2) = j * 4 + 10;
|
||||
chmapif_sendallwos(fd, buf, WBUFW(buf,2));
|
||||
}
|
||||
online_char_db->foreach(online_char_db,char_db_setoffline,id); //Tag relevant chars as 'in disconnected' server.
|
||||
|
||||
// Tag relevant chars as 'in disconnected' server.
|
||||
for( const auto& pair : char_get_onlinedb() ){
|
||||
char_db_setoffline( pair.second, id );
|
||||
}
|
||||
|
||||
chmapif_server_destroy(id);
|
||||
chmapif_server_init(id);
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "int_auction.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -14,35 +17,37 @@
|
||||
#include "../common/sql.hpp"
|
||||
#include "../common/strlib.hpp"
|
||||
#include "../common/timer.hpp"
|
||||
#include "../common/utilities.hpp"
|
||||
|
||||
#include "char.hpp"
|
||||
#include "char_mapif.hpp"
|
||||
#include "inter.hpp"
|
||||
#include "int_mail.hpp"
|
||||
|
||||
static DBMap* auction_db_ = NULL; // int auction_id -> struct auction_data*
|
||||
using namespace rathena;
|
||||
|
||||
void auction_delete(struct auction_data *auction);
|
||||
// int auction_id -> struct auction_data*
|
||||
static std::unordered_map<uint32, std::shared_ptr<struct auction_data>> auction_db;
|
||||
|
||||
void auction_delete( std::shared_ptr<struct auction_data> auction );
|
||||
TIMER_FUNC(auction_end_timer);
|
||||
|
||||
int auction_count(uint32 char_id, bool buy)
|
||||
{
|
||||
int i = 0;
|
||||
struct auction_data *auction;
|
||||
DBIterator *iter = db_iterator(auction_db_);
|
||||
|
||||
for( auction = (struct auction_data *)dbi_first(iter); dbi_exists(iter); auction = (struct auction_data *)dbi_next(iter) )
|
||||
{
|
||||
if( (buy && auction->buyer_id == char_id) || (!buy && auction->seller_id == char_id) )
|
||||
for( const auto& pair : auction_db ){
|
||||
std::shared_ptr<struct auction_data> auction = pair.second;
|
||||
|
||||
if( ( buy && auction->buyer_id == char_id ) || ( !buy && auction->seller_id == char_id ) ){
|
||||
i++;
|
||||
}
|
||||
}
|
||||
dbi_destroy(iter);
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
void auction_save(struct auction_data *auction)
|
||||
{
|
||||
void auction_save( std::shared_ptr<struct auction_data> auction ){
|
||||
int j;
|
||||
StringBuf buf;
|
||||
SqlStmt* stmt;
|
||||
@@ -76,8 +81,7 @@ void auction_save(struct auction_data *auction)
|
||||
StringBuf_Destroy(&buf);
|
||||
}
|
||||
|
||||
unsigned int auction_create(struct auction_data *auction)
|
||||
{
|
||||
uint32 auction_create( std::shared_ptr<struct auction_data> auction ){
|
||||
int j;
|
||||
StringBuf buf;
|
||||
SqlStmt* stmt;
|
||||
@@ -119,7 +123,6 @@ unsigned int auction_create(struct auction_data *auction)
|
||||
}
|
||||
else
|
||||
{
|
||||
struct auction_data *auction_;
|
||||
t_tick tick = auction->hours * 3600000;
|
||||
|
||||
auction->item.amount = 1;
|
||||
@@ -130,9 +133,7 @@ unsigned int auction_create(struct auction_data *auction)
|
||||
auction->auction_end_timer = add_timer( gettick() + tick , auction_end_timer, auction->auction_id, 0);
|
||||
ShowInfo("New Auction %u | time left %" PRtf " ms | By %s.\n", auction->auction_id, tick, auction->seller_name);
|
||||
|
||||
CREATE(auction_, struct auction_data, 1);
|
||||
memcpy(auction_, auction, sizeof(struct auction_data));
|
||||
idb_put(auction_db_, auction_->auction_id, auction_);
|
||||
auction_db[auction->auction_id] = auction;
|
||||
}
|
||||
|
||||
SqlStmt_Free(stmt);
|
||||
@@ -152,9 +153,9 @@ void mapif_Auction_message(uint32 char_id, unsigned char result)
|
||||
}
|
||||
|
||||
TIMER_FUNC(auction_end_timer){
|
||||
struct auction_data *auction;
|
||||
if( (auction = (struct auction_data *)idb_get(auction_db_, id)) != NULL )
|
||||
{
|
||||
std::shared_ptr<struct auction_data> auction = util::umap_find( auction_db, static_cast<uint32>( id ) );
|
||||
|
||||
if( auction != nullptr ){
|
||||
if( auction->buyer_id )
|
||||
{
|
||||
mail_sendmail(0, msg_txt(200), auction->buyer_id, auction->buyer_name, msg_txt(201), msg_txt(202), 0, &auction->item, 1);
|
||||
@@ -173,8 +174,7 @@ TIMER_FUNC(auction_end_timer){
|
||||
return 0;
|
||||
}
|
||||
|
||||
void auction_delete(struct auction_data *auction)
|
||||
{
|
||||
void auction_delete( std::shared_ptr<struct auction_data> auction ){
|
||||
unsigned int auction_id = auction->auction_id;
|
||||
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `auction_id` = '%d'", schema_config.auction_db, auction_id) )
|
||||
@@ -183,7 +183,7 @@ void auction_delete(struct auction_data *auction)
|
||||
if( auction->auction_end_timer != INVALID_TIMER )
|
||||
delete_timer(auction->auction_end_timer, auction_end_timer);
|
||||
|
||||
idb_remove(auction_db_, auction_id);
|
||||
auction_db.erase( auction_id );
|
||||
}
|
||||
|
||||
void inter_auctions_fromsql(void)
|
||||
@@ -214,8 +214,8 @@ void inter_auctions_fromsql(void)
|
||||
while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
|
||||
{
|
||||
struct item *item;
|
||||
struct auction_data *auction;
|
||||
CREATE(auction, struct auction_data, 1);
|
||||
std::shared_ptr<struct auction_data> auction = std::make_shared<struct auction_data>();
|
||||
|
||||
Sql_GetData(sql_handle, 0, &data, NULL); auction->auction_id = atoi(data);
|
||||
Sql_GetData(sql_handle, 1, &data, NULL); auction->seller_id = atoi(data);
|
||||
Sql_GetData(sql_handle, 2, &data, NULL); safestrncpy(auction->seller_name, data, NAME_LENGTH);
|
||||
@@ -261,7 +261,8 @@ void inter_auctions_fromsql(void)
|
||||
endtick = tick + 10000; // 10 Second's to process ended auctions
|
||||
|
||||
auction->auction_end_timer = add_timer(endtick, auction_end_timer, auction->auction_id, 0);
|
||||
idb_put(auction_db_, auction->auction_id, auction);
|
||||
|
||||
auction_db[auction->auction_id] = auction;
|
||||
}
|
||||
|
||||
Sql_FreeResult(sql_handle);
|
||||
@@ -288,14 +289,13 @@ void mapif_parse_Auction_requestlist(int fd)
|
||||
int price = RFIFOL(fd,10);
|
||||
short type = RFIFOW(fd,8), page = max(1,RFIFOW(fd,14));
|
||||
unsigned char buf[5 * sizeof(struct auction_data)];
|
||||
DBIterator *iter = db_iterator(auction_db_);
|
||||
struct auction_data *auction;
|
||||
short i = 0, j = 0, pages = 1;
|
||||
|
||||
memcpy(searchtext, RFIFOP(fd,16), NAME_LENGTH);
|
||||
|
||||
for( auction = static_cast<auction_data *>(dbi_first(iter)); dbi_exists(iter); auction = static_cast<auction_data *>(dbi_next(iter)) )
|
||||
{
|
||||
for( const auto& pair : auction_db ){
|
||||
std::shared_ptr<struct auction_data> auction = pair.second;
|
||||
|
||||
if( (type == 0 && auction->type != IT_ARMOR && auction->type != IT_PETARMOR) ||
|
||||
(type == 1 && auction->type != IT_WEAPON) ||
|
||||
(type == 2 && auction->type != IT_CARD) ||
|
||||
@@ -316,10 +316,9 @@ void mapif_parse_Auction_requestlist(int fd)
|
||||
if( page != pages )
|
||||
continue; // This is not the requested Page
|
||||
|
||||
memcpy(WBUFP(buf, j * len), auction, len);
|
||||
memcpy( WBUFP( buf, j * len ), auction.get(), len );
|
||||
j++; // Found Results
|
||||
}
|
||||
dbi_destroy(iter);
|
||||
|
||||
mapif_Auction_sendlist(fd, char_id, j, pages, buf);
|
||||
}
|
||||
@@ -337,15 +336,22 @@ void mapif_Auction_register(int fd, struct auction_data *auction)
|
||||
|
||||
void mapif_parse_Auction_register(int fd)
|
||||
{
|
||||
struct auction_data auction;
|
||||
if( RFIFOW(fd,2) != sizeof(struct auction_data) + 4 )
|
||||
return;
|
||||
|
||||
memcpy(&auction, RFIFOP(fd,4), sizeof(struct auction_data));
|
||||
if( auction_count(auction.seller_id, false) < 5 )
|
||||
auction.auction_id = auction_create(&auction);
|
||||
struct auction_data* auction = reinterpret_cast<struct auction_data*>( RFIFOP( fd, 4 ) );
|
||||
|
||||
mapif_Auction_register(fd, &auction);
|
||||
if( auction_count( auction->seller_id, false ) < 5 ){
|
||||
std::shared_ptr<struct auction_data> auction2 = std::make_shared<struct auction_data>();
|
||||
|
||||
memcpy( auction2.get(), auction, sizeof( struct auction_data ) );
|
||||
|
||||
auction2->auction_id = auction_create( auction2 );
|
||||
|
||||
auction = auction2.get();
|
||||
}
|
||||
|
||||
mapif_Auction_register( fd, auction );
|
||||
}
|
||||
|
||||
void mapif_Auction_cancel(int fd, uint32 char_id, unsigned char result)
|
||||
@@ -360,10 +366,10 @@ void mapif_Auction_cancel(int fd, uint32 char_id, unsigned char result)
|
||||
void mapif_parse_Auction_cancel(int fd)
|
||||
{
|
||||
uint32 char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6);
|
||||
struct auction_data *auction;
|
||||
|
||||
if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL )
|
||||
{
|
||||
std::shared_ptr<struct auction_data> auction = util::umap_find( auction_db, auction_id );
|
||||
|
||||
if( auction == nullptr ){
|
||||
mapif_Auction_cancel(fd, char_id, 1); // Bid Number is Incorrect
|
||||
return;
|
||||
}
|
||||
@@ -398,10 +404,9 @@ void mapif_Auction_close(int fd, uint32 char_id, unsigned char result)
|
||||
void mapif_parse_Auction_close(int fd)
|
||||
{
|
||||
uint32 char_id = RFIFOL(fd,2), auction_id = RFIFOL(fd,6);
|
||||
struct auction_data *auction;
|
||||
std::shared_ptr<struct auction_data> auction = util::umap_find( auction_db, auction_id );
|
||||
|
||||
if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL )
|
||||
{
|
||||
if( auction == nullptr ){
|
||||
mapif_Auction_close(fd, char_id, 2); // Bid Number is Incorrect
|
||||
return;
|
||||
}
|
||||
@@ -442,10 +447,9 @@ void mapif_parse_Auction_bid(int fd)
|
||||
{
|
||||
uint32 char_id = RFIFOL(fd,4), auction_id = RFIFOL(fd,8);
|
||||
int bid = RFIFOL(fd,12);
|
||||
struct auction_data *auction;
|
||||
std::shared_ptr<struct auction_data> auction = util::umap_find( auction_db, auction_id );
|
||||
|
||||
if( (auction = (struct auction_data *)idb_get(auction_db_, auction_id)) == NULL || auction->price >= bid || auction->seller_id == char_id )
|
||||
{
|
||||
if( auction == nullptr || auction->price >= bid || auction->seller_id == char_id ){
|
||||
mapif_Auction_bid(fd, char_id, bid, 0); // You have failed to bid in the auction
|
||||
return;
|
||||
}
|
||||
@@ -508,7 +512,6 @@ int inter_auction_parse_frommap(int fd)
|
||||
|
||||
int inter_auction_sql_init(void)
|
||||
{
|
||||
auction_db_ = idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
inter_auctions_fromsql();
|
||||
|
||||
return 0;
|
||||
@@ -516,7 +519,7 @@ int inter_auction_sql_init(void)
|
||||
|
||||
void inter_auction_sql_final(void)
|
||||
{
|
||||
auction_db_->destroy(auction_db_,NULL);
|
||||
auction_db.clear();
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3,6 +3,10 @@
|
||||
|
||||
#include "int_clan.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h> //memset
|
||||
|
||||
@@ -17,8 +21,10 @@
|
||||
#include "char_mapif.hpp"
|
||||
#include "inter.hpp"
|
||||
|
||||
//clan cache
|
||||
static DBMap* clan_db; // int clan_id -> struct clan*
|
||||
// int clan_id -> struct clan*
|
||||
static std::unordered_map<int32, std::shared_ptr<struct clan>> clan_db;
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
int inter_clan_removemember_tosql(uint32 account_id, uint32 char_id){
|
||||
if( SQL_ERROR == Sql_Query( sql_handle, "UPDATE `%s` SET `clan_id` = '0' WHERE `char_id` = '%d'", schema_config.char_db, char_id ) ){
|
||||
@@ -29,16 +35,15 @@ int inter_clan_removemember_tosql(uint32 account_id, uint32 char_id){
|
||||
}
|
||||
}
|
||||
|
||||
struct clan* inter_clan_fromsql(int clan_id){
|
||||
struct clan* clan;
|
||||
std::shared_ptr<struct clan> inter_clan_fromsql(int clan_id){
|
||||
char* data;
|
||||
size_t len;
|
||||
int i;
|
||||
|
||||
if( clan_id <= 0 )
|
||||
return NULL;
|
||||
return nullptr;
|
||||
|
||||
clan = (struct clan*)idb_get(clan_db, clan_id);
|
||||
std::shared_ptr<struct clan> clan = util::umap_find( clan_db, clan_id );
|
||||
|
||||
if( clan ){
|
||||
return clan;
|
||||
@@ -46,15 +51,14 @@ struct clan* inter_clan_fromsql(int clan_id){
|
||||
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `name`, `master`, `mapname`, `max_member` FROM `%s` WHERE `clan_id`='%d'", schema_config.clan_table, clan_id) ){
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if( SQL_SUCCESS != Sql_NextRow(sql_handle) ){
|
||||
return NULL;// Clan does not exists.
|
||||
return nullptr; // Clan does not exists.
|
||||
}
|
||||
|
||||
CREATE(clan, struct clan, 1);
|
||||
memset(clan, 0, sizeof(struct clan));
|
||||
clan = std::make_shared<struct clan>();
|
||||
|
||||
clan->id = clan_id;
|
||||
Sql_GetData(sql_handle, 0, &data, &len); memcpy(clan->name, data, min(len, NAME_LENGTH));
|
||||
@@ -73,8 +77,7 @@ struct clan* inter_clan_fromsql(int clan_id){
|
||||
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `opposition`,`alliance_id`,`name` FROM `%s` WHERE `clan_id`='%d'", schema_config.clan_alliance_table, clan_id) ){
|
||||
Sql_ShowDebug(sql_handle);
|
||||
aFree(clan);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for( i = 0; i < MAX_CLANALLIANCE && SQL_SUCCESS == Sql_NextRow(sql_handle); i++ ){
|
||||
@@ -85,7 +88,7 @@ struct clan* inter_clan_fromsql(int clan_id){
|
||||
Sql_GetData(sql_handle, 2, &data, &len); memcpy(a->name, data, zmin(len, NAME_LENGTH));
|
||||
}
|
||||
|
||||
idb_put( clan_db, clan_id, clan);
|
||||
clan_db[clan->id] = clan;
|
||||
|
||||
if (charserv_config.save_log)
|
||||
ShowInfo("Clan loaded (%d - %s)\n", clan_id, clan->name);
|
||||
@@ -94,24 +97,22 @@ struct clan* inter_clan_fromsql(int clan_id){
|
||||
}
|
||||
|
||||
int mapif_clan_info( int fd ){
|
||||
DBIterator *iter;
|
||||
int offset;
|
||||
struct clan* clan;
|
||||
int length;
|
||||
|
||||
length = 4 + db_size(clan_db) * sizeof( struct clan );
|
||||
length = 4 + clan_db.size() * sizeof( struct clan );
|
||||
|
||||
WFIFOHEAD( fd, length );
|
||||
WFIFOW( fd, 0 ) = 0x38A0;
|
||||
WFIFOW( fd, 2 ) = length;
|
||||
|
||||
offset = 4;
|
||||
iter = db_iterator(clan_db);
|
||||
for( clan = (struct clan*)dbi_first(iter); dbi_exists(iter); clan = (struct clan*)dbi_next(iter) ){
|
||||
memcpy( WFIFOP( fd, offset ), clan, sizeof( struct clan ) );
|
||||
for( const auto& pair : clan_db ){
|
||||
std::shared_ptr<struct clan> clan = pair.second;
|
||||
|
||||
memcpy( WFIFOP( fd, offset ), clan.get(), sizeof( struct clan ) );
|
||||
offset += sizeof( struct clan );
|
||||
}
|
||||
dbi_destroy(iter);
|
||||
|
||||
WFIFOSET( fd, length );
|
||||
|
||||
@@ -138,7 +139,7 @@ static int mapif_parse_clan_message( int fd ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void mapif_clan_refresh_onlinecount( int fd, struct clan* clan ){
|
||||
static void mapif_clan_refresh_onlinecount( int fd, std::shared_ptr<struct clan> clan ){
|
||||
unsigned char buf[8];
|
||||
|
||||
WBUFW(buf,0) = 0x38A2;
|
||||
@@ -149,9 +150,10 @@ static void mapif_clan_refresh_onlinecount( int fd, struct clan* clan ){
|
||||
}
|
||||
|
||||
static void mapif_parse_clan_member_left( int fd ){
|
||||
struct clan* clan = (struct clan*)idb_get(clan_db, RFIFOL(fd,2) );
|
||||
std::shared_ptr<struct clan> clan = util::umap_find( clan_db, static_cast<int32>( RFIFOL( fd, 2 ) ) );
|
||||
|
||||
if( clan == NULL ){ // Unknown clan
|
||||
// Unknown clan
|
||||
if( clan == nullptr ){
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -163,9 +165,10 @@ static void mapif_parse_clan_member_left( int fd ){
|
||||
}
|
||||
|
||||
static void mapif_parse_clan_member_joined( int fd ){
|
||||
struct clan* clan = (struct clan*)idb_get(clan_db, RFIFOL(fd,2) );
|
||||
std::shared_ptr<struct clan> clan = util::umap_find( clan_db, static_cast<int32>( RFIFOL( fd, 2 ) ) );
|
||||
|
||||
if( clan == NULL ){ // Unknown clan
|
||||
// Unknown clan
|
||||
if( clan == nullptr ){
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -203,45 +206,28 @@ int inter_clan_parse_frommap( int fd ){
|
||||
|
||||
// Initialize clan sql
|
||||
int inter_clan_init(void){
|
||||
char* data;
|
||||
int* clan_ids;
|
||||
int amount;
|
||||
|
||||
clan_db = idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
|
||||
if( SQL_ERROR == Sql_Query( sql_handle, "SELECT `clan_id` FROM `%s`", schema_config.clan_table ) ){
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return 1;
|
||||
}
|
||||
|
||||
amount = (int)Sql_NumRows( sql_handle );
|
||||
std::vector<int32> clan_ids;
|
||||
|
||||
if( amount > 0 ){
|
||||
int i;
|
||||
while( SQL_SUCCESS == Sql_NextRow( sql_handle ) ){
|
||||
char* data;
|
||||
Sql_GetData( sql_handle, 0, &data, nullptr );
|
||||
clan_ids.push_back( atoi( data ) );
|
||||
}
|
||||
|
||||
CREATE( clan_ids, int, amount );
|
||||
i = 0;
|
||||
Sql_FreeResult( sql_handle );
|
||||
|
||||
while( SQL_SUCCESS == Sql_NextRow(sql_handle) ){
|
||||
Sql_GetData(sql_handle, 0, &data, NULL);
|
||||
clan_ids[i++] = atoi(data);
|
||||
}
|
||||
|
||||
Sql_FreeResult( sql_handle );
|
||||
|
||||
// If we didnt load a row as expected
|
||||
amount = i;
|
||||
|
||||
for( i = 0; i < amount; i++ ){
|
||||
inter_clan_fromsql( clan_ids[i] );
|
||||
}
|
||||
|
||||
aFree(clan_ids);
|
||||
for( int32 clan_id : clan_ids ){
|
||||
inter_clan_fromsql( clan_id );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inter_clan_final(){
|
||||
db_destroy(clan_db);
|
||||
clan_db.clear();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "int_guild.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <stdlib.h>
|
||||
#define __STDC_WANT_LIB_EXT1__ 1
|
||||
#include <string.h>
|
||||
@@ -34,32 +37,29 @@ using namespace rathena;
|
||||
|
||||
static const char dataToHex[] = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'};
|
||||
|
||||
//Guild cache
|
||||
static DBMap* guild_db_; // int guild_id -> struct guild*
|
||||
static DBMap *castle_db;
|
||||
// int guild_id -> struct guild*
|
||||
static std::unordered_map<int32, std::shared_ptr<struct guild>> guild_db;
|
||||
static std::unordered_map<int32, std::shared_ptr<struct guild_castle>> castle_db;
|
||||
|
||||
int mapif_parse_GuildLeave(int fd,int guild_id,uint32 account_id,uint32 char_id,int flag,const char *mes);
|
||||
int mapif_guild_broken(int guild_id,int flag);
|
||||
bool guild_check_empty(struct guild *g);
|
||||
int guild_calcinfo(struct guild *g);
|
||||
bool guild_check_empty( std::shared_ptr<struct guild> g );
|
||||
int guild_calcinfo( std::shared_ptr<struct guild> g );
|
||||
int mapif_guild_basicinfochanged(int guild_id,int type,const void *data,int len);
|
||||
int mapif_guild_info(int fd,struct guild *g);
|
||||
int guild_break_sub(int key,void *data,va_list ap);
|
||||
int inter_guild_tosql(struct guild *g,int flag);
|
||||
int guild_checkskill(struct guild *g, int id);
|
||||
int mapif_guild_info( int fd, std::shared_ptr<struct guild> g );
|
||||
int inter_guild_tosql( std::shared_ptr<struct guild> g, int flag );
|
||||
int guild_checkskill( std::shared_ptr<struct guild> g, int id );
|
||||
|
||||
TIMER_FUNC(guild_save_timer){
|
||||
static int last_id = 0; //To know in which guild we were.
|
||||
int state = 0; //0: Have not reached last guild. 1: Reached last guild, ready for save. 2: Some guild saved, don't do further saving.
|
||||
DBIterator *iter = db_iterator(guild_db_);
|
||||
DBKey key;
|
||||
struct guild* g;
|
||||
|
||||
if( last_id == 0 ) //Save the first guild in the list.
|
||||
state = 1;
|
||||
|
||||
for( g = (struct guild*)db_data2ptr(iter->first(iter, &key)); dbi_exists(iter); g = (struct guild*)db_data2ptr(iter->next(iter, &key)) )
|
||||
{
|
||||
for( auto it = guild_db.begin(); it != guild_db.end(); ){
|
||||
std::shared_ptr<struct guild> g = it->second;
|
||||
|
||||
if( state == 0 && g->guild_id == last_id )
|
||||
state++; //Save next guild in the list.
|
||||
else if( state == 1 && g->save_flag&GS_MASK )
|
||||
@@ -72,19 +72,20 @@ TIMER_FUNC(guild_save_timer){
|
||||
state++;
|
||||
}
|
||||
|
||||
if( g->save_flag == GS_REMOVE )
|
||||
{// Nothing to save, guild is ready for removal.
|
||||
// Nothing to save, guild is ready for removal.
|
||||
if( g->save_flag == GS_REMOVE ){
|
||||
if (charserv_config.save_log)
|
||||
ShowInfo("Guild Unloaded (%d - %s)\n", g->guild_id, g->name);
|
||||
db_remove(guild_db_, key);
|
||||
it = guild_db.erase( it );
|
||||
}else{
|
||||
it++;
|
||||
}
|
||||
}
|
||||
dbi_destroy(iter);
|
||||
|
||||
if( state != 2 ) //Reached the end of the guild db without saving.
|
||||
last_id = 0; //Reset guild saved, return to beginning.
|
||||
|
||||
state = guild_db_->size(guild_db_);
|
||||
state = guild_db.size();
|
||||
if( state < 1 ) state = 1; //Calculate the time slot for the next save.
|
||||
add_timer(tick + (charserv_config.autosave_interval)/state, guild_save_timer, 0, 0);
|
||||
return 0;
|
||||
@@ -100,8 +101,7 @@ int inter_guild_removemember_tosql(uint32 char_id)
|
||||
}
|
||||
|
||||
// Save guild into sql
|
||||
int inter_guild_tosql(struct guild *g,int flag)
|
||||
{
|
||||
int inter_guild_tosql( std::shared_ptr<struct guild> g, int flag ){
|
||||
// Table guild (GS_BASIC_MASK)
|
||||
// GS_EMBLEM `emblem_len`,`emblem_id`,`emblem_data`
|
||||
// GS_CONNECT `connect_member`,`average_lv`
|
||||
@@ -333,20 +333,21 @@ int inter_guild_tosql(struct guild *g,int flag)
|
||||
}
|
||||
|
||||
// Read guild from sql
|
||||
struct guild * inter_guild_fromsql(int guild_id)
|
||||
{
|
||||
struct guild *g;
|
||||
std::shared_ptr<struct guild> inter_guild_fromsql( int32 guild_id ){
|
||||
char* data;
|
||||
size_t len;
|
||||
char* p;
|
||||
int i;
|
||||
|
||||
if( guild_id <= 0 )
|
||||
return NULL;
|
||||
if( guild_id <= 0 ){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
g = (struct guild*)idb_get(guild_db_, guild_id);
|
||||
if( g )
|
||||
std::shared_ptr<struct guild> g = util::umap_find( guild_db, guild_id );
|
||||
|
||||
if( g != nullptr ){
|
||||
return g;
|
||||
}
|
||||
|
||||
#ifdef NOISY
|
||||
ShowInfo("Guild load request (%d)...\n", guild_id);
|
||||
@@ -356,13 +357,15 @@ struct guild * inter_guild_fromsql(int guild_id)
|
||||
"FROM `%s` g LEFT JOIN `%s` c ON c.`char_id` = g.`char_id` WHERE g.`guild_id`='%d'", schema_config.guild_db, schema_config.char_db, guild_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
|
||||
return NULL;// Guild does not exists.
|
||||
// Guild does not exists.
|
||||
if( SQL_SUCCESS != Sql_NextRow( sql_handle ) ){
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
CREATE(g, struct guild, 1);
|
||||
g = std::make_shared<struct guild>();
|
||||
|
||||
g->guild_id = guild_id;
|
||||
Sql_GetData(sql_handle, 0, &data, &len); memcpy(g->name, data, zmin(len, NAME_LENGTH));
|
||||
@@ -412,8 +415,7 @@ struct guild * inter_guild_fromsql(int guild_id)
|
||||
"FROM `%s` `m` INNER JOIN `%s` `c` on `c`.`char_id`=`m`.`char_id` WHERE `m`.`guild_id`='%d' ORDER BY `position`", schema_config.guild_member_db, schema_config.char_db, guild_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
aFree(g);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
for( i = 0; i < g->max_member && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
|
||||
{
|
||||
@@ -452,8 +454,7 @@ struct guild * inter_guild_fromsql(int guild_id)
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `position`,`name`,`mode`,`exp_mode` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_position_db, guild_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
aFree(g);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
while( SQL_SUCCESS == Sql_NextRow(sql_handle) )
|
||||
{
|
||||
@@ -474,8 +475,7 @@ struct guild * inter_guild_fromsql(int guild_id)
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `opposition`,`alliance_id`,`name` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_alliance_db, guild_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
aFree(g);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
for( i = 0; i < MAX_GUILDALLIANCE && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
|
||||
{
|
||||
@@ -490,8 +490,7 @@ struct guild * inter_guild_fromsql(int guild_id)
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `account_id`,`name`,`mes` FROM `%s` WHERE `guild_id`='%d'", schema_config.guild_expulsion_db, guild_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
aFree(g);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
for( i = 0; i < MAX_GUILDEXPULSION && SQL_SUCCESS == Sql_NextRow(sql_handle); ++i )
|
||||
{
|
||||
@@ -506,8 +505,7 @@ struct guild * inter_guild_fromsql(int guild_id)
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `id`,`lv` FROM `%s` WHERE `guild_id`='%d' ORDER BY `id`", schema_config.guild_skill_db, guild_id) )
|
||||
{
|
||||
Sql_ShowDebug(sql_handle);
|
||||
aFree(g);
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
for(i = 0; i < MAX_GUILDSKILL; i++)
|
||||
@@ -525,8 +523,11 @@ struct guild * inter_guild_fromsql(int guild_id)
|
||||
}
|
||||
Sql_FreeResult(sql_handle);
|
||||
|
||||
idb_put(guild_db_, guild_id, g); //Add to cache
|
||||
g->save_flag |= GS_REMOVE; //But set it to be removed, in case it is not needed for long.
|
||||
// Add to cache
|
||||
guild_db[g->guild_id] = g;
|
||||
|
||||
// But set it to be removed, in case it is not needed for long.
|
||||
g->save_flag |= GS_REMOVE;
|
||||
|
||||
if (charserv_config.save_log)
|
||||
ShowInfo("Guild loaded (%d - %s)\n", guild_id, g->name);
|
||||
@@ -542,10 +543,10 @@ struct guild * inter_guild_fromsql(int guild_id)
|
||||
uint16 inter_guild_storagemax(int guild_id)
|
||||
{
|
||||
#ifdef OFFICIAL_GUILD_STORAGE
|
||||
struct guild *g = inter_guild_fromsql(guild_id);
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
uint16 max = 0;
|
||||
|
||||
if (!g) {
|
||||
if( g == nullptr ){
|
||||
ShowError("Guild %d not found!\n", guild_id);
|
||||
return 0;
|
||||
}
|
||||
@@ -561,8 +562,7 @@ uint16 inter_guild_storagemax(int guild_id)
|
||||
}
|
||||
|
||||
// `guild_castle` (`castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, `triggerD`, `nextTime`, `payTime`, `createTime`, `visibleC`, `visibleG0`, `visibleG1`, `visibleG2`, `visibleG3`, `visibleG4`, `visibleG5`, `visibleG6`, `visibleG7`)
|
||||
int inter_guildcastle_tosql(struct guild_castle *gc)
|
||||
{
|
||||
int inter_guildcastle_tosql( std::shared_ptr<struct guild_castle> gc ){
|
||||
StringBuf buf;
|
||||
int i;
|
||||
|
||||
@@ -584,15 +584,16 @@ int inter_guildcastle_tosql(struct guild_castle *gc)
|
||||
}
|
||||
|
||||
// Read guild_castle from SQL
|
||||
struct guild_castle* inter_guildcastle_fromsql(int castle_id)
|
||||
{
|
||||
std::shared_ptr<struct guild_castle> inter_guildcastle_fromsql( int castle_id ){
|
||||
char *data;
|
||||
int i;
|
||||
StringBuf buf;
|
||||
struct guild_castle *gc = (struct guild_castle *)idb_get(castle_db, castle_id);
|
||||
|
||||
if (gc != NULL)
|
||||
std::shared_ptr<struct guild_castle> gc = util::umap_find( castle_db, castle_id );
|
||||
|
||||
if( gc != nullptr ){
|
||||
return gc;
|
||||
}
|
||||
|
||||
StringBuf_Init(&buf);
|
||||
StringBuf_AppendStr(&buf, "SELECT `castle_id`, `guild_id`, `economy`, `defense`, `triggerE`, "
|
||||
@@ -607,7 +608,8 @@ struct guild_castle* inter_guildcastle_fromsql(int castle_id)
|
||||
}
|
||||
StringBuf_Destroy(&buf);
|
||||
|
||||
CREATE(gc, struct guild_castle, 1);
|
||||
gc = std::make_shared<struct guild_castle>();
|
||||
|
||||
gc->castle_id = castle_id;
|
||||
|
||||
if (SQL_SUCCESS == Sql_NextRow(sql_handle)) {
|
||||
@@ -626,7 +628,7 @@ struct guild_castle* inter_guildcastle_fromsql(int castle_id)
|
||||
}
|
||||
Sql_FreeResult(sql_handle);
|
||||
|
||||
idb_put(castle_db, castle_id, gc);
|
||||
castle_db[gc->castle_id] = gc;
|
||||
|
||||
if (charserv_config.save_log)
|
||||
ShowInfo("Loaded guild castle (%d - guild %d)\n", castle_id, gc->guild_id);
|
||||
@@ -637,7 +639,6 @@ struct guild_castle* inter_guildcastle_fromsql(int castle_id)
|
||||
|
||||
int inter_guild_CharOnline(uint32 char_id, int guild_id)
|
||||
{
|
||||
struct guild *g;
|
||||
int i;
|
||||
|
||||
if (guild_id == -1) {
|
||||
@@ -664,8 +665,9 @@ int inter_guild_CharOnline(uint32 char_id, int guild_id)
|
||||
if (guild_id == 0)
|
||||
return 0; //No guild...
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(!g) {
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if( g == nullptr ){
|
||||
ShowError("Character %d's guild %d not found!\n", char_id, guild_id);
|
||||
return 0;
|
||||
}
|
||||
@@ -687,7 +689,6 @@ int inter_guild_CharOnline(uint32 char_id, int guild_id)
|
||||
|
||||
int inter_guild_CharOffline(uint32 char_id, int guild_id)
|
||||
{
|
||||
struct guild *g=NULL;
|
||||
int online_count, i;
|
||||
|
||||
if (guild_id == -1)
|
||||
@@ -716,9 +717,12 @@ int inter_guild_CharOffline(uint32 char_id, int guild_id)
|
||||
return 0; //No guild...
|
||||
|
||||
//Character has a guild, set character offline and check if they were the only member online
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if (g == NULL) //Guild not found?
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
// Guild not found?
|
||||
if( g == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Set member offline
|
||||
ARR_FIND( 0, g->max_member, i, g->member[i].char_id == char_id );
|
||||
@@ -800,33 +804,22 @@ void GuildExpDatabase::loadingFinished() {
|
||||
|
||||
// Initialize guild sql and read exp_guild.yml
|
||||
void inter_guild_sql_init(void) {
|
||||
//Initialize the guild cache
|
||||
guild_db_= idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
castle_db = idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
|
||||
guild_exp_db.load();
|
||||
add_timer_func_list(guild_save_timer, "guild_save_timer");
|
||||
add_timer(gettick() + 10000, guild_save_timer, 0, 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see DBApply
|
||||
*/
|
||||
int guild_db_final(DBKey key, DBData *data, va_list ap)
|
||||
{
|
||||
struct guild *g = (struct guild*)db_data2ptr(data);
|
||||
if (g->save_flag&GS_MASK) {
|
||||
inter_guild_tosql(g, g->save_flag&GS_MASK);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inter_guild_sql_final(void)
|
||||
{
|
||||
guild_db_->destroy(guild_db_, guild_db_final);
|
||||
db_destroy(castle_db);
|
||||
return;
|
||||
for( const auto& pair : guild_db ){
|
||||
std::shared_ptr<struct guild> guild = pair.second;
|
||||
|
||||
if( guild->save_flag&GS_MASK ){
|
||||
inter_guild_tosql( guild, guild->save_flag&GS_MASK );
|
||||
}
|
||||
}
|
||||
guild_db.clear();
|
||||
castle_db.clear();
|
||||
}
|
||||
|
||||
// Get guild_id by its name. Returns 0 if not found, -1 on error.
|
||||
@@ -859,8 +852,7 @@ int search_guildname(char *str)
|
||||
}
|
||||
|
||||
// Check if guild is empty
|
||||
bool guild_check_empty(struct guild *g)
|
||||
{
|
||||
bool guild_check_empty( std::shared_ptr<struct guild> g ){
|
||||
int i;
|
||||
ARR_FIND( 0, g->max_member, i, g->member[i].account_id > 0 );
|
||||
//Let the calling function handle the guild removal in case they need
|
||||
@@ -874,14 +866,12 @@ t_exp GuildExpDatabase::get_nextexp(uint16 level) {
|
||||
return ((guild_exp == nullptr) ? 0 : guild_exp->exp);
|
||||
}
|
||||
|
||||
int guild_checkskill(struct guild *g,int id)
|
||||
{
|
||||
int guild_checkskill( std::shared_ptr<struct guild> g, int id ){
|
||||
int idx = id - GD_SKILLBASE;
|
||||
return idx < 0 || idx >= MAX_GUILDSKILL ? 0 : g->skill[idx].lv;
|
||||
}
|
||||
|
||||
int guild_calcinfo(struct guild *g)
|
||||
{
|
||||
int guild_calcinfo( std::shared_ptr<struct guild> g ){
|
||||
int i,c;
|
||||
struct guild before = *g; // Save guild current values
|
||||
|
||||
@@ -943,8 +933,7 @@ int guild_calcinfo(struct guild *g)
|
||||
//-------------------------------------------------------------------
|
||||
// Packet sent to map server
|
||||
|
||||
int mapif_guild_created(int fd,uint32 account_id,struct guild *g)
|
||||
{
|
||||
int mapif_guild_created( int fd, uint32 account_id, std::shared_ptr<struct guild> g ){
|
||||
WFIFOHEAD(fd, 10);
|
||||
WFIFOW(fd,0)=0x3830;
|
||||
WFIFOL(fd,2)=account_id;
|
||||
@@ -975,12 +964,11 @@ int mapif_guild_noinfo(int fd,int guild_id)
|
||||
}
|
||||
|
||||
// Send guild info
|
||||
int mapif_guild_info(int fd,struct guild *g)
|
||||
{
|
||||
int mapif_guild_info( int fd, std::shared_ptr<struct guild> g ){
|
||||
unsigned char buf[8+sizeof(struct guild)];
|
||||
WBUFW(buf,0)=0x3831;
|
||||
WBUFW(buf,2)=4+sizeof(struct guild);
|
||||
memcpy(buf+4,g,sizeof(struct guild));
|
||||
memcpy( buf + 4, g.get(), sizeof( struct guild ) );
|
||||
if(fd<0)
|
||||
chmapif_sendall(buf,WBUFW(buf,2));
|
||||
else
|
||||
@@ -1018,8 +1006,7 @@ int mapif_guild_withdraw(int guild_id,uint32 account_id,uint32 char_id,int flag,
|
||||
}
|
||||
|
||||
// Send short member's info
|
||||
int mapif_guild_memberinfoshort(struct guild *g,int idx)
|
||||
{
|
||||
int mapif_guild_memberinfoshort( std::shared_ptr<struct guild> g, int idx ){
|
||||
unsigned char buf[19];
|
||||
WBUFW(buf, 0)=0x3835;
|
||||
WBUFL(buf, 2)=g->guild_id;
|
||||
@@ -1120,8 +1107,7 @@ int mapif_guild_alliance(int guild_id1,int guild_id2,uint32 account_id1,uint32 a
|
||||
}
|
||||
|
||||
// Send a guild position desc
|
||||
int mapif_guild_position(struct guild *g,int idx)
|
||||
{
|
||||
int mapif_guild_position( std::shared_ptr<struct guild> g, int idx ){
|
||||
unsigned char buf[12 + sizeof(struct guild_position)];
|
||||
WBUFW(buf,0)=0x383b;
|
||||
WBUFW(buf,2)=sizeof(struct guild_position)+12;
|
||||
@@ -1133,8 +1119,7 @@ int mapif_guild_position(struct guild *g,int idx)
|
||||
}
|
||||
|
||||
// Send the guild notice
|
||||
int mapif_guild_notice(struct guild *g)
|
||||
{
|
||||
int mapif_guild_notice( std::shared_ptr<struct guild> g ){
|
||||
unsigned char buf[256];
|
||||
WBUFW(buf,0)=0x383e;
|
||||
WBUFL(buf,2)=g->guild_id;
|
||||
@@ -1145,8 +1130,7 @@ int mapif_guild_notice(struct guild *g)
|
||||
}
|
||||
|
||||
// Send emblem data
|
||||
int mapif_guild_emblem(struct guild *g)
|
||||
{
|
||||
int mapif_guild_emblem( std::shared_ptr<struct guild> g ){
|
||||
unsigned char buf[12 + sizeof(g->emblem_data)];
|
||||
WBUFW(buf,0)=0x383f;
|
||||
WBUFW(buf,2)=g->emblem_len+12;
|
||||
@@ -1158,8 +1142,7 @@ int mapif_guild_emblem(struct guild *g)
|
||||
}
|
||||
|
||||
// Send the guild emblem_id (version)
|
||||
int mapif_guild_emblem_version(guild* g)
|
||||
{
|
||||
int mapif_guild_emblem_version( std::shared_ptr<struct guild> g ){
|
||||
unsigned char buf[10];
|
||||
WBUFW(buf, 0) = 0x3841;
|
||||
WBUFL(buf, 2) = g->guild_id;
|
||||
@@ -1169,8 +1152,7 @@ int mapif_guild_emblem_version(guild* g)
|
||||
return 0;
|
||||
}
|
||||
|
||||
int mapif_guild_master_changed(struct guild *g, int aid, int cid, time_t time)
|
||||
{
|
||||
int mapif_guild_master_changed( std::shared_ptr<struct guild> g, int aid, int cid, time_t time ){
|
||||
unsigned char buf[18];
|
||||
WBUFW(buf,0)=0x3843;
|
||||
WBUFL(buf,2)=g->guild_id;
|
||||
@@ -1183,17 +1165,16 @@ int mapif_guild_master_changed(struct guild *g, int aid, int cid, time_t time)
|
||||
|
||||
int mapif_guild_castle_dataload(int fd, int sz, int *castle_ids)
|
||||
{
|
||||
struct guild_castle *gc = NULL;
|
||||
int num = (sz - 4) / sizeof(int);
|
||||
int len = 4 + num * sizeof(*gc);
|
||||
int len = 4 + num * sizeof( struct guild_castle );
|
||||
int i;
|
||||
|
||||
WFIFOHEAD(fd, len);
|
||||
WFIFOW(fd, 0) = 0x3840;
|
||||
WFIFOW(fd, 2) = len;
|
||||
for (i = 0; i < num; i++) {
|
||||
gc = inter_guildcastle_fromsql(*(castle_ids++));
|
||||
memcpy(WFIFOP(fd, 4 + i * sizeof(*gc)), gc, sizeof(*gc));
|
||||
std::shared_ptr<struct guild_castle> gc = inter_guildcastle_fromsql( *(castle_ids++) );
|
||||
memcpy( WFIFOP( fd, 4 + i * sizeof( struct guild_castle ) ), gc.get(), sizeof( struct guild_castle ) );
|
||||
}
|
||||
WFIFOSET(fd, len);
|
||||
return 0;
|
||||
@@ -1206,7 +1187,6 @@ int mapif_guild_castle_dataload(int fd, int sz, int *castle_ids)
|
||||
// Guild creation request
|
||||
int mapif_parse_CreateGuild(int fd,uint32 account_id,char *name,struct guild_member *master)
|
||||
{
|
||||
struct guild *g;
|
||||
int i=0;
|
||||
#ifdef NOISY
|
||||
ShowInfo("Creating Guild (%s)\n", name);
|
||||
@@ -1231,8 +1211,9 @@ int mapif_parse_CreateGuild(int fd,uint32 account_id,char *name,struct guild_mem
|
||||
}
|
||||
}
|
||||
|
||||
g = (struct guild *)aMalloc(sizeof(struct guild));
|
||||
memset(g,0,sizeof(struct guild));
|
||||
std::shared_ptr<struct guild> g = std::make_shared<struct guild>();
|
||||
|
||||
memset( g.get(), 0, sizeof( struct guild ) );
|
||||
|
||||
memcpy(g->name,name,NAME_LENGTH);
|
||||
memcpy(g->master,master->name,NAME_LENGTH);
|
||||
@@ -1263,13 +1244,12 @@ int mapif_parse_CreateGuild(int fd,uint32 account_id,char *name,struct guild_mem
|
||||
//Failed to Create guild....
|
||||
ShowError("Failed to create Guild %s (Guild Master: %s)\n", g->name, g->master);
|
||||
mapif_guild_created(fd,account_id,NULL);
|
||||
aFree(g);
|
||||
return 0;
|
||||
}
|
||||
ShowInfo("Created Guild %d - %s (Guild Master: %s)\n", g->guild_id, g->name, g->master);
|
||||
|
||||
//Add to cache
|
||||
idb_put(guild_db_, g->guild_id, g);
|
||||
// Add to cache
|
||||
guild_db[g->guild_id] = g;
|
||||
|
||||
// Report to client
|
||||
mapif_guild_created(fd,account_id,g);
|
||||
@@ -1285,13 +1265,12 @@ int mapif_parse_CreateGuild(int fd,uint32 account_id,char *name,struct guild_mem
|
||||
// Return guild info to client
|
||||
int mapif_parse_GuildInfo(int fd,int guild_id)
|
||||
{
|
||||
struct guild * g = inter_guild_fromsql(guild_id); //We use this because on start-up the info of castle-owned guilds is requied. [Skotlex]
|
||||
if(g)
|
||||
{
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if( g != nullptr ){
|
||||
if (!guild_calcinfo(g))
|
||||
mapif_guild_info(fd,g);
|
||||
}
|
||||
else
|
||||
}else
|
||||
mapif_guild_noinfo(fd,guild_id); // Failed to load info
|
||||
return 0;
|
||||
}
|
||||
@@ -1299,19 +1278,16 @@ int mapif_parse_GuildInfo(int fd,int guild_id)
|
||||
// Add member to guild
|
||||
int mapif_parse_GuildAddMember(int fd,int guild_id,struct guild_member *m)
|
||||
{
|
||||
struct guild * g;
|
||||
int i;
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(g==NULL){
|
||||
if( g == nullptr ){
|
||||
// Failed to add
|
||||
mapif_guild_memberadded(fd,guild_id,m->account_id,m->char_id,1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find an empty slot
|
||||
for(i=0;i<g->max_member;i++)
|
||||
{
|
||||
for( int i = 0; i < g->max_member; i++ ){
|
||||
if(g->member[i].account_id==0)
|
||||
{
|
||||
memcpy(&g->member[i],m,sizeof(struct guild_member));
|
||||
@@ -1337,9 +1313,9 @@ int mapif_parse_GuildLeave(int fd, int guild_id, uint32 account_id, uint32 char_
|
||||
{
|
||||
int i;
|
||||
|
||||
struct guild* g = inter_guild_fromsql(guild_id);
|
||||
if( g == NULL )
|
||||
{
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if( g == nullptr ){
|
||||
// Unknown guild, just update the player
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `guild_id`='0' WHERE `account_id`='%d' AND `char_id`='%d'", schema_config.char_db, account_id, char_id) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
@@ -1394,13 +1370,14 @@ int mapif_parse_GuildLeave(int fd, int guild_id, uint32 account_id, uint32 char_
|
||||
int mapif_parse_GuildChangeMemberInfoShort(int fd,int guild_id,uint32 account_id,uint32 char_id,int online,int lv,int class_)
|
||||
{
|
||||
// Could speed up by manipulating only guild_member
|
||||
struct guild * g;
|
||||
int i,sum,c;
|
||||
int prev_count, prev_alv;
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(g==NULL)
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if( g == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
ARR_FIND( 0, g->max_member, i, g->member[i].account_id == account_id && g->member[i].char_id == char_id );
|
||||
if( i < g->max_member )
|
||||
@@ -1446,11 +1423,11 @@ int mapif_parse_GuildChangeMemberInfoShort(int fd,int guild_id,uint32 account_id
|
||||
// BreakGuild
|
||||
int mapif_parse_BreakGuild(int fd,int guild_id)
|
||||
{
|
||||
struct guild * g;
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(g==NULL)
|
||||
if( g == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Delete guild from sql
|
||||
//printf("- Delete guild %d from guild\n",guild_id);
|
||||
@@ -1487,8 +1464,9 @@ int mapif_parse_BreakGuild(int fd,int guild_id)
|
||||
if(charserv_config.log_inter)
|
||||
inter_log("guild %s (id=%d) broken\n",g->name,guild_id);
|
||||
|
||||
//Remove the guild from memory. [Skotlex]
|
||||
idb_remove(guild_db_, guild_id);
|
||||
// Remove the guild from memory. [Skotlex]
|
||||
guild_db.erase( guild_id );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1501,10 +1479,11 @@ int mapif_parse_GuildMessage(int fd,int guild_id,uint32 account_id,char *mes,int
|
||||
// Modification of the guild
|
||||
int mapif_parse_GuildBasicInfoChange(int fd,int guild_id,int type,const char *data,int len)
|
||||
{
|
||||
struct guild *g = inter_guild_fromsql(guild_id);
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if (!g)
|
||||
if( g == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
short data_value = *((short *)data);
|
||||
|
||||
@@ -1542,11 +1521,12 @@ int mapif_parse_GuildMemberInfoChange(int fd,int guild_id,uint32 account_id,uint
|
||||
{
|
||||
// Could make some improvement in speed, because only change guild_member
|
||||
int i;
|
||||
struct guild * g;
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(g==NULL)
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if( g == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Search the member
|
||||
for(i=0;i<g->max_member;i++)
|
||||
@@ -1649,12 +1629,11 @@ int inter_guild_sex_changed(int guild_id,uint32 account_id,uint32 char_id, short
|
||||
|
||||
int inter_guild_charname_changed(int guild_id,uint32 account_id, uint32 char_id, char *name)
|
||||
{
|
||||
struct guild *g;
|
||||
int i, flag = 0;
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if( g == NULL )
|
||||
{
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if( g == nullptr ){
|
||||
ShowError("inter_guild_charrenamed: Can't find guild %d.\n", guild_id);
|
||||
return 0;
|
||||
}
|
||||
@@ -1687,11 +1666,11 @@ int inter_guild_charname_changed(int guild_id,uint32 account_id, uint32 char_id,
|
||||
int mapif_parse_GuildPosition(int fd,int guild_id,int idx,struct guild_position *p)
|
||||
{
|
||||
// Could make some improvement in speed, because only change guild_position
|
||||
struct guild * g;
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(g==NULL || idx<0 || idx>=MAX_GUILDPOSITION)
|
||||
if( g == nullptr || idx < 0 || idx >= MAX_GUILDPOSITION ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(&g->position[idx],p,sizeof(struct guild_position));
|
||||
mapif_guild_position(g,idx);
|
||||
@@ -1703,12 +1682,13 @@ int mapif_parse_GuildPosition(int fd,int guild_id,int idx,struct guild_position
|
||||
// Guild Skill UP
|
||||
int mapif_parse_GuildSkillUp(int fd,int guild_id,uint16 skill_id,uint32 account_id,int max)
|
||||
{
|
||||
struct guild * g;
|
||||
int idx = skill_id - GD_SKILLBASE;
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(g == NULL || idx < 0 || idx >= MAX_GUILDSKILL)
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if( g == nullptr || idx < 0 || idx >= MAX_GUILDSKILL ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(g->skill_point>0 && g->skill[idx].id>0 && g->skill[idx].lv<max )
|
||||
{
|
||||
@@ -1725,8 +1705,7 @@ int mapif_parse_GuildSkillUp(int fd,int guild_id,uint16 skill_id,uint32 account_
|
||||
}
|
||||
|
||||
//Manual deletion of an alliance when partnering guild does not exists. [Skotlex]
|
||||
int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, uint32 account_id1, uint32 account_id2, int flag)
|
||||
{
|
||||
int mapif_parse_GuildDeleteAlliance( std::shared_ptr<struct guild> g, int guild_id, uint32 account_id1, uint32 account_id2, int flag ){
|
||||
int i;
|
||||
char name[NAME_LENGTH];
|
||||
|
||||
@@ -1755,16 +1734,19 @@ int mapif_parse_GuildDeleteAlliance(struct guild *g, int guild_id, uint32 accoun
|
||||
int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,uint32 account_id1,uint32 account_id2,int flag)
|
||||
{
|
||||
// Could speed up
|
||||
struct guild *g[2];
|
||||
std::shared_ptr<struct guild> g[2];
|
||||
int j,i;
|
||||
g[0] = inter_guild_fromsql(guild_id1);
|
||||
g[1] = inter_guild_fromsql(guild_id2);
|
||||
|
||||
if(g[0] && g[1]==NULL && (flag & GUILD_ALLIANCE_REMOVE)) //Requested to remove an alliance with a not found guild.
|
||||
// Requested to remove an alliance with a not found guild.
|
||||
if( g[0] != nullptr && g[1] == nullptr && ( flag & GUILD_ALLIANCE_REMOVE ) ){
|
||||
return mapif_parse_GuildDeleteAlliance(g[0], guild_id2, account_id1, account_id2, flag); //Try to do a manual removal of said guild.
|
||||
}
|
||||
|
||||
if(g[0]==NULL || g[1]==NULL)
|
||||
if( g[0] == nullptr || g[1] == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(flag&GUILD_ALLIANCE_REMOVE)
|
||||
{
|
||||
@@ -1805,11 +1787,11 @@ int mapif_parse_GuildAlliance(int fd,int guild_id1,int guild_id2,uint32 account_
|
||||
// Change guild message
|
||||
int mapif_parse_GuildNotice(int fd,int guild_id,const char *mes1,const char *mes2)
|
||||
{
|
||||
struct guild *g;
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(g==NULL)
|
||||
if( g == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
memcpy(g->mes1,mes1,MAX_GUILDMES1);
|
||||
memcpy(g->mes2,mes2,MAX_GUILDMES2);
|
||||
@@ -1820,11 +1802,11 @@ int mapif_parse_GuildNotice(int fd,int guild_id,const char *mes1,const char *mes
|
||||
|
||||
int mapif_parse_GuildEmblem(int fd,int len,int guild_id,int dummy,const char *data)
|
||||
{
|
||||
struct guild * g;
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
if(g==NULL)
|
||||
if( g == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (len > sizeof(g->emblem_data))
|
||||
len = sizeof(g->emblem_data);
|
||||
@@ -1843,9 +1825,9 @@ int mapif_parse_GuildCastleDataLoad(int fd, int len, int *castle_ids)
|
||||
|
||||
int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value)
|
||||
{
|
||||
struct guild_castle *gc = inter_guildcastle_fromsql(castle_id);
|
||||
std::shared_ptr<struct guild_castle> gc = inter_guildcastle_fromsql( castle_id );
|
||||
|
||||
if (gc == NULL) {
|
||||
if( gc == nullptr ){
|
||||
ShowError("mapif_parse_GuildCastleDataSave: castle id=%d not found\n", castle_id);
|
||||
return 0;
|
||||
}
|
||||
@@ -1854,7 +1836,7 @@ int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value)
|
||||
case CD_GUILD_ID:
|
||||
if (charserv_config.log_inter && gc->guild_id != value) {
|
||||
int gid = (value) ? value : gc->guild_id;
|
||||
struct guild *g = (struct guild*)idb_get(guild_db_, gid);
|
||||
std::shared_ptr<struct guild> g = util::umap_find( guild_db, gid );
|
||||
inter_log("guild %s (id=%d) %s castle id=%d\n",
|
||||
(g) ? g->name : "??", gid, (value) ? "occupy" : "abandon", castle_id);
|
||||
}
|
||||
@@ -1882,14 +1864,14 @@ int mapif_parse_GuildCastleDataSave(int fd, int castle_id, int index, int value)
|
||||
|
||||
int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int len)
|
||||
{
|
||||
struct guild * g;
|
||||
struct guild_member gm;
|
||||
int pos;
|
||||
|
||||
g = inter_guild_fromsql(guild_id);
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if(g==NULL || len > NAME_LENGTH)
|
||||
if( g == nullptr || len > NAME_LENGTH ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Find member (name)
|
||||
for (pos = 0; pos < g->max_member && strncmp(g->member[pos].name, name, len); pos++);
|
||||
@@ -1922,7 +1904,7 @@ int mapif_parse_GuildMasterChange(int fd, int guild_id, const char* name, int le
|
||||
|
||||
int mapif_parse_GuildEmblemVersion(int fd, int guild_id, int version)
|
||||
{
|
||||
guild* g = inter_guild_fromsql(guild_id);
|
||||
std::shared_ptr<struct guild> g = inter_guild_fromsql( guild_id );
|
||||
|
||||
if (g == nullptr)
|
||||
return 0;
|
||||
|
||||
@@ -3,6 +3,8 @@
|
||||
|
||||
#include "int_mail.hpp"
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -11,11 +13,14 @@
|
||||
#include "../common/socket.hpp"
|
||||
#include "../common/sql.hpp"
|
||||
#include "../common/strlib.hpp"
|
||||
#include "../common/utilities.hpp"
|
||||
|
||||
#include "char.hpp"
|
||||
#include "char_mapif.hpp"
|
||||
#include "inter.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
bool mail_loadmessage(int mail_id, struct mail_message* msg);
|
||||
void mapif_Mail_return( int fd, uint32 char_id, int mail_id, uint32 account_id_receiver = 0, uint32 account_id_sender = 0 );
|
||||
bool mapif_Mail_delete( int fd, uint32 char_id, int mail_id, uint32 account_id = 0 );
|
||||
@@ -460,10 +465,10 @@ bool mapif_Mail_delete( int fd, uint32 char_id, int mail_id, uint32 account_id )
|
||||
|
||||
// If the char server triggered this, check if we have to notify a map server
|
||||
if( fd <= 0 ){
|
||||
struct online_char_data* character;
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), account_id );
|
||||
|
||||
// Check for online players
|
||||
if( ( character = (struct online_char_data*)idb_get( char_get_onlinedb(), account_id ) ) != nullptr && character->server >= 0 ){
|
||||
if( character != nullptr && character->server >= 0 ){
|
||||
fd = map_server[character->server].fd;
|
||||
}else{
|
||||
// The request was triggered inside the character server or the player is offline now
|
||||
@@ -561,10 +566,10 @@ void mapif_Mail_return( int fd, uint32 char_id, int mail_id, uint32 account_id_r
|
||||
|
||||
// If the char server triggered this, check if we have to notify a map server
|
||||
if( fd <= 0 ){
|
||||
struct online_char_data* character;
|
||||
std::shared_ptr<struct online_char_data> character = util::umap_find( char_get_onlinedb(), account_id_sender );
|
||||
|
||||
// Check for online players
|
||||
if( ( character = (struct online_char_data*)idb_get( char_get_onlinedb(), account_id_sender ) ) != nullptr && character->server >= 0 ){
|
||||
if( character != nullptr && character->server >= 0 ){
|
||||
fd = map_server[character->server].fd;
|
||||
}else{
|
||||
// The request was triggered inside the character server or the player is offline now
|
||||
|
||||
@@ -3,6 +3,9 @@
|
||||
|
||||
#include "int_party.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
@@ -14,11 +17,14 @@
|
||||
#include "../common/socket.hpp"
|
||||
#include "../common/sql.hpp"
|
||||
#include "../common/strlib.hpp"
|
||||
#include "../common/utilities.hpp"
|
||||
|
||||
#include "char.hpp"
|
||||
#include "char_mapif.hpp"
|
||||
#include "inter.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
struct party_data {
|
||||
struct party party;
|
||||
unsigned int min_lv, max_lv;
|
||||
@@ -26,18 +32,18 @@ struct party_data {
|
||||
unsigned char size; //Total size of party.
|
||||
};
|
||||
|
||||
static struct party_data *party_pt;
|
||||
static DBMap* party_db_; // int party_id -> struct party_data*
|
||||
// int party_id -> struct party_data*
|
||||
static std::unordered_map<int32, std::shared_ptr<struct party_data>> party_db;
|
||||
|
||||
int mapif_party_broken(int party_id,int flag);
|
||||
int party_check_empty(struct party_data *p);
|
||||
int party_check_empty( std::shared_ptr<struct party_data> p );
|
||||
int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type);
|
||||
int party_check_exp_share(struct party_data *p);
|
||||
int party_check_exp_share( std::shared_ptr<struct party_data> p );
|
||||
int mapif_party_optionchanged(int fd,struct party *p, uint32 account_id, int flag);
|
||||
int party_check_family_share(struct party_data *p);
|
||||
int party_check_family_share( std::shared_ptr<struct party_data> p );
|
||||
|
||||
//Updates party's level range and unsets even share if broken.
|
||||
static int int_party_check_lv(struct party_data *p) {
|
||||
static int int_party_check_lv( std::shared_ptr<struct party_data> p ){
|
||||
int i;
|
||||
unsigned int lv;
|
||||
p->min_lv = UINT_MAX;
|
||||
@@ -62,8 +68,7 @@ static int int_party_check_lv(struct party_data *p) {
|
||||
return 1;
|
||||
}
|
||||
//Calculates the state of a party.
|
||||
void int_party_calc_state(struct party_data *p)
|
||||
{
|
||||
void int_party_calc_state( std::shared_ptr<struct party_data> p ){
|
||||
int i;
|
||||
p->min_lv = UINT_MAX;
|
||||
p->max_lv = 0;
|
||||
@@ -116,7 +121,7 @@ int inter_party_tosql(struct party *p, int flag, int index)
|
||||
{
|
||||
// 'party' ('party_id','name','exp','item','leader_id','leader_char')
|
||||
char esc_name[NAME_LENGTH*2+1];// escaped party name
|
||||
int party_id;
|
||||
int32 party_id;
|
||||
|
||||
if( p == NULL || p->party_id == 0 )
|
||||
return 0;
|
||||
@@ -135,7 +140,7 @@ int inter_party_tosql(struct party *p, int flag, int index)
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` WHERE `party_id`='%d'", schema_config.party_db, party_id) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
//Remove from memory
|
||||
idb_remove(party_db_, party_id);
|
||||
party_db.erase( party_id );
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -186,11 +191,9 @@ int inter_party_tosql(struct party *p, int flag, int index)
|
||||
}
|
||||
|
||||
// Read party from mysql
|
||||
struct party_data *inter_party_fromsql(int party_id)
|
||||
{
|
||||
std::shared_ptr<struct party_data> inter_party_fromsql( int party_id ){
|
||||
int leader_id = 0;
|
||||
int leader_char = 0;
|
||||
struct party_data* p;
|
||||
struct party_member* m;
|
||||
char* data;
|
||||
size_t len;
|
||||
@@ -203,12 +206,11 @@ struct party_data *inter_party_fromsql(int party_id)
|
||||
return NULL;
|
||||
|
||||
//Load from memory
|
||||
p = (struct party_data*)idb_get(party_db_, party_id);
|
||||
if( p != NULL )
|
||||
return p;
|
||||
std::shared_ptr<struct party_data> p = util::umap_find( party_db, party_id );
|
||||
|
||||
p = party_pt;
|
||||
memset(p, 0, sizeof(struct party_data));
|
||||
if( p != nullptr ){
|
||||
return p;
|
||||
}
|
||||
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id`, `name`,`exp`,`item`, `leader_id`, `leader_char` FROM `%s` WHERE `party_id`='%d'", schema_config.party_db, party_id) )
|
||||
{
|
||||
@@ -219,6 +221,8 @@ struct party_data *inter_party_fromsql(int party_id)
|
||||
if( SQL_SUCCESS != Sql_NextRow(sql_handle) )
|
||||
return NULL;
|
||||
|
||||
p = std::make_shared<struct party_data>();
|
||||
|
||||
p->party.party_id = party_id;
|
||||
Sql_GetData(sql_handle, 1, &data, &len); memcpy(p->party.name, data, zmin(len, NAME_LENGTH));
|
||||
Sql_GetData(sql_handle, 2, &data, NULL); p->party.exp = (atoi(data) ? 1 : 0);
|
||||
@@ -249,47 +253,38 @@ struct party_data *inter_party_fromsql(int party_id)
|
||||
|
||||
if( charserv_config.save_log )
|
||||
ShowInfo("Party loaded (%d - %s).\n", party_id, p->party.name);
|
||||
//Add party to memory.
|
||||
CREATE(p, struct party_data, 1);
|
||||
memcpy(p, party_pt, sizeof(struct party_data));
|
||||
|
||||
//init state
|
||||
int_party_calc_state(p);
|
||||
idb_put(party_db_, party_id, p);
|
||||
|
||||
party_db[p->party.party_id] = p;
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int inter_party_sql_init(void)
|
||||
{
|
||||
//memory alloc
|
||||
party_db_ = idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
party_pt = (struct party_data*)aCalloc(sizeof(struct party_data), 1);
|
||||
if (!party_pt) {
|
||||
ShowFatalError("inter_party_sql_init: Out of Memory!\n");
|
||||
exit(EXIT_FAILURE);
|
||||
// Remove parties with no members on startup from party_db. [Skotlex]
|
||||
if (charserv_config.clear_parties) {
|
||||
ShowStatus("Cleaning party table...\n");
|
||||
if (SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` LEFT JOIN `%s` ON `%s`.leader_id =`%s`.account_id AND `%s`.leader_char = `%s`.char_id WHERE `%s`.account_id IS NULL",
|
||||
schema_config.party_db, schema_config.party_db, schema_config.char_db, schema_config.party_db, schema_config.char_db, schema_config.party_db, schema_config.char_db, schema_config.char_db))
|
||||
Sql_ShowDebug(sql_handle);
|
||||
}
|
||||
|
||||
/* Uncomment the following if you want to do a party_db cleanup (remove parties with no members) on startup.[Skotlex]
|
||||
ShowStatus("cleaning party table...\n");
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "DELETE FROM `%s` USING `%s` LEFT JOIN `%s` ON `%s`.leader_id =`%s`.account_id AND `%s`.leader_char = `%s`.char_id WHERE `%s`.account_id IS NULL",
|
||||
party_db, party_db, char_db, party_db, char_db, party_db, char_db, char_db) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
*/
|
||||
return 0;
|
||||
}
|
||||
|
||||
void inter_party_sql_final(void)
|
||||
{
|
||||
party_db_->destroy(party_db_, NULL);
|
||||
aFree(party_pt);
|
||||
return;
|
||||
party_db.clear();
|
||||
}
|
||||
|
||||
// Search for the party according to its name
|
||||
struct party_data* search_partyname(char* str)
|
||||
{
|
||||
std::shared_ptr<struct party_data> search_partyname( char* str ){
|
||||
char esc_name[NAME_LENGTH*2+1];
|
||||
char* data;
|
||||
struct party_data* p = NULL;
|
||||
std::shared_ptr<struct party_data> p = nullptr;
|
||||
|
||||
Sql_EscapeStringLen(sql_handle, esc_name, str, safestrnlen(str, NAME_LENGTH));
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "SELECT `party_id` FROM `%s` WHERE `name`='%s'", schema_config.party_db, esc_name) )
|
||||
@@ -304,7 +299,7 @@ struct party_data* search_partyname(char* str)
|
||||
return p;
|
||||
}
|
||||
|
||||
int party_check_family_share(struct party_data *p) {
|
||||
int party_check_family_share( std::shared_ptr<struct party_data> p ){
|
||||
int i;
|
||||
unsigned short map = 0;
|
||||
if (!p->family)
|
||||
@@ -340,16 +335,18 @@ int party_check_family_share(struct party_data *p) {
|
||||
}
|
||||
|
||||
// Returns whether this party can keep having exp share or not.
|
||||
int party_check_exp_share(struct party_data *p)
|
||||
{
|
||||
int party_check_exp_share( std::shared_ptr<struct party_data> p ){
|
||||
return (p->party.count < 2 || p->max_lv - p->min_lv <= party_share_level || party_check_family_share(p));
|
||||
}
|
||||
|
||||
// Is there any member in the party?
|
||||
int party_check_empty(struct party_data *p)
|
||||
{
|
||||
int party_check_empty( std::shared_ptr<struct party_data> p ){
|
||||
int i;
|
||||
if (p==NULL||p->party.party_id==0) return 1;
|
||||
|
||||
if( p == nullptr || p->party.party_id == 0 ){
|
||||
return 1;
|
||||
}
|
||||
|
||||
for(i=0;i<MAX_PARTY && !p->party.member[i].account_id;i++);
|
||||
if (i < MAX_PARTY) return 0;
|
||||
// If there is no member, then break the party
|
||||
@@ -503,15 +500,16 @@ int mapif_party_message(int party_id,uint32 account_id,char *mes,int len, int sf
|
||||
// Create Party
|
||||
int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct party_member *leader)
|
||||
{
|
||||
struct party_data *p;
|
||||
int i;
|
||||
if( (p=search_partyname(name))!=NULL){
|
||||
std::shared_ptr<struct party_data> p = search_partyname( name );
|
||||
|
||||
if( p != nullptr ){
|
||||
mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Check Authorised letters/symbols in the name of the character
|
||||
if (charserv_config.char_config.char_name_option == 1) { // only letters/symbols in char_name_letters are authorised
|
||||
for (i = 0; i < NAME_LENGTH && name[i]; i++)
|
||||
for( int i = 0; i < NAME_LENGTH && name[i]; i++ ){
|
||||
if (strchr(charserv_config.char_config.char_name_letters, name[i]) == NULL) {
|
||||
if( name[i] == '"' ) { /* client-special-char */
|
||||
normalize_name(name,"\"");
|
||||
@@ -521,15 +519,17 @@ int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct part
|
||||
mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else if (charserv_config.char_config.char_name_option == 2) { // letters/symbols in char_name_letters are forbidden
|
||||
for (i = 0; i < NAME_LENGTH && name[i]; i++)
|
||||
for( int i = 0; i < NAME_LENGTH && name[i]; i++ ){
|
||||
if (strchr(charserv_config.char_config.char_name_letters, name[i]) != NULL) {
|
||||
mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
p = (struct party_data*)aCalloc(1, sizeof(struct party_data));
|
||||
p = std::make_shared<struct party_data>();
|
||||
|
||||
memcpy(p->party.name,name,NAME_LENGTH);
|
||||
p->party.exp=0;
|
||||
@@ -543,11 +543,11 @@ int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct part
|
||||
if (inter_party_tosql(&p->party,PS_CREATE|PS_ADDMEMBER,0)) {
|
||||
//Add party to db
|
||||
int_party_calc_state(p);
|
||||
idb_put(party_db_, p->party.party_id, p);
|
||||
party_db[p->party.party_id] = p;
|
||||
mapif_party_info(fd, &p->party, 0);
|
||||
mapif_party_created(fd,leader->account_id,leader->char_id,&p->party);
|
||||
} else { //Failed to create party.
|
||||
aFree(p);
|
||||
}else{
|
||||
// Failed to create party.
|
||||
mapif_party_created(fd,leader->account_id,leader->char_id,NULL);
|
||||
}
|
||||
|
||||
@@ -557,22 +557,23 @@ int mapif_parse_CreateParty(int fd, char *name, int item, int item2, struct part
|
||||
// Party information request
|
||||
void mapif_parse_PartyInfo(int fd, int party_id, uint32 char_id)
|
||||
{
|
||||
struct party_data *p;
|
||||
p = inter_party_fromsql(party_id);
|
||||
if (p)
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if( p != nullptr ){
|
||||
mapif_party_info(fd, &p->party, char_id);
|
||||
else
|
||||
}else{
|
||||
mapif_party_noinfo(fd, party_id, char_id);
|
||||
}
|
||||
}
|
||||
|
||||
// Add a player to party request
|
||||
int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member)
|
||||
{
|
||||
struct party_data *p;
|
||||
int i;
|
||||
|
||||
p = inter_party_fromsql(party_id);
|
||||
if( p == NULL || p->size == MAX_PARTY ) {
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if( p == nullptr || p->size == MAX_PARTY ){
|
||||
mapif_party_memberadded(fd, party_id, member->account_id, member->char_id, 1);
|
||||
return 0;
|
||||
}
|
||||
@@ -606,9 +607,9 @@ int mapif_parse_PartyAddMember(int fd, int party_id, struct party_member *member
|
||||
//Party setting change request
|
||||
int mapif_parse_PartyChangeOption(int fd,int party_id,uint32 account_id,int exp,int item)
|
||||
{
|
||||
struct party_data *p;
|
||||
int flag = 0;
|
||||
p = inter_party_fromsql(party_id);
|
||||
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if(!p)
|
||||
return 0;
|
||||
@@ -628,12 +629,12 @@ int mapif_parse_PartyChangeOption(int fd,int party_id,uint32 account_id,int exp,
|
||||
//Request leave party
|
||||
int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_id, char *name, enum e_party_member_withdraw type)
|
||||
{
|
||||
struct party_data *p;
|
||||
int i,j=-1;
|
||||
|
||||
p = inter_party_fromsql(party_id);
|
||||
if( p == NULL )
|
||||
{// Party does not exists?
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
// Party does not exists?
|
||||
if( p == nullptr ){
|
||||
if( SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `party_id`='0' WHERE `party_id`='%d'", schema_config.char_db, party_id) )
|
||||
Sql_ShowDebug(sql_handle);
|
||||
return 0;
|
||||
@@ -680,12 +681,13 @@ int mapif_parse_PartyLeave(int fd, int party_id, uint32 account_id, uint32 char_
|
||||
// When member goes to other map or levels up.
|
||||
int mapif_parse_PartyChangeMap(int fd, int party_id, uint32 account_id, uint32 char_id, unsigned short map, int online, unsigned int lv)
|
||||
{
|
||||
struct party_data *p;
|
||||
int i;
|
||||
|
||||
p = inter_party_fromsql(party_id);
|
||||
if (p == NULL)
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if( p == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
for(i = 0; i < MAX_PARTY &&
|
||||
(p->party.member[i].account_id != account_id ||
|
||||
@@ -738,9 +740,7 @@ int mapif_parse_PartyChangeMap(int fd, int party_id, uint32 account_id, uint32 c
|
||||
//Request party dissolution
|
||||
int mapif_parse_BreakParty(int fd,int party_id)
|
||||
{
|
||||
struct party_data *p;
|
||||
|
||||
p = inter_party_fromsql(party_id);
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if(!p)
|
||||
return 0;
|
||||
@@ -757,16 +757,12 @@ int mapif_parse_PartyMessage(int fd,int party_id,uint32 account_id,char *mes,int
|
||||
|
||||
int mapif_parse_PartyLeaderChange(int fd,int party_id,uint32 account_id,uint32 char_id)
|
||||
{
|
||||
struct party_data *p;
|
||||
int i;
|
||||
|
||||
p = inter_party_fromsql(party_id);
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if(!p)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < MAX_PARTY; i++)
|
||||
{
|
||||
for( int i = 0; i < MAX_PARTY; i++ ){
|
||||
if(p->party.member[i].leader)
|
||||
p->party.member[i].leader = 0;
|
||||
if(p->party.member[i].account_id == account_id &&
|
||||
@@ -787,16 +783,16 @@ int mapif_parse_PartyLeaderChange(int fd,int party_id,uint32 account_id,uint32 c
|
||||
*/
|
||||
int mapif_parse_PartyShareLevel(int fd,unsigned int share_lvl)
|
||||
{
|
||||
struct party_data *p;
|
||||
DBIterator* iter = db_iterator(party_db_);
|
||||
|
||||
party_share_level = share_lvl;
|
||||
|
||||
for(p = (struct party_data *)dbi_first(iter); dbi_exists(iter); p = (struct party_data *)dbi_next(iter)) { //Update online parties
|
||||
if(p->party.count > 1)
|
||||
int_party_calc_state(p);
|
||||
// Update online parties
|
||||
for( const auto& pair : party_db ){
|
||||
std::shared_ptr<struct party_data> p = pair.second;
|
||||
|
||||
if( p->party.count > 1 ){
|
||||
int_party_calc_state( p );
|
||||
}
|
||||
}
|
||||
dbi_destroy(iter);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@@ -837,7 +833,6 @@ int inter_party_leave(int party_id,uint32 account_id, uint32 char_id, char *name
|
||||
|
||||
int inter_party_CharOnline(uint32 char_id, int party_id)
|
||||
{
|
||||
struct party_data* p;
|
||||
int i;
|
||||
|
||||
if( party_id == -1 )
|
||||
@@ -860,7 +855,8 @@ int inter_party_CharOnline(uint32 char_id, int party_id)
|
||||
if (party_id == 0)
|
||||
return 0; //No party...
|
||||
|
||||
p = inter_party_fromsql(party_id);
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if(!p) {
|
||||
ShowError("Character %d's party %d not found!\n", char_id, party_id);
|
||||
return 0;
|
||||
@@ -883,7 +879,6 @@ int inter_party_CharOnline(uint32 char_id, int party_id)
|
||||
}
|
||||
|
||||
int inter_party_CharOffline(uint32 char_id, int party_id) {
|
||||
struct party_data *p=NULL;
|
||||
int i;
|
||||
|
||||
if( party_id == -1 )
|
||||
@@ -907,8 +902,11 @@ int inter_party_CharOffline(uint32 char_id, int party_id) {
|
||||
return 0; //No party...
|
||||
|
||||
//Character has a party, set character offline and check if they were the only member online
|
||||
if ((p = inter_party_fromsql(party_id)) == NULL)
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if( p == nullptr ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
//Set member offline
|
||||
for(i=0; i< MAX_PARTY; i++) {
|
||||
@@ -923,20 +921,21 @@ int inter_party_CharOffline(uint32 char_id, int party_id) {
|
||||
}
|
||||
}
|
||||
|
||||
if(!p->party.count)
|
||||
//Parties don't have any data that needs be saved at this point... so just remove it from memory.
|
||||
idb_remove(party_db_, party_id);
|
||||
// Parties don't have any data that needs be saved at this point... so just remove it from memory.
|
||||
if( p->party.count == 0 ){
|
||||
party_db.erase( party_id );
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int inter_party_charname_changed(int party_id, uint32 char_id, char *name)
|
||||
{
|
||||
struct party_data* p = NULL;
|
||||
int i;
|
||||
|
||||
p = inter_party_fromsql(party_id);
|
||||
if( p == NULL || p->party.party_id == 0 )
|
||||
{
|
||||
std::shared_ptr<struct party_data> p = inter_party_fromsql( party_id );
|
||||
|
||||
if( p == nullptr || p->party.party_id == 0 ){
|
||||
ShowError("inter_party_charname_changed: Can't find party %d.\n", party_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -3,11 +3,14 @@
|
||||
|
||||
#include "inter.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <string>
|
||||
#include <sys/stat.h> // for stat/lstat/fstat - [Dekamaster/Ultimate GM Tool]
|
||||
#include <vector>
|
||||
|
||||
#include "../common/cbasetypes.hpp"
|
||||
#include "../common/database.hpp"
|
||||
@@ -34,12 +37,12 @@
|
||||
#include "int_quest.hpp"
|
||||
#include "int_storage.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
std::string cfgFile = "inter_athena.yml"; ///< Inter-Config file
|
||||
InterServerDatabase interServerDb;
|
||||
|
||||
#define WISDATA_TTL (60*1000) //Wis data Time To Live (60 seconds)
|
||||
#define WISDELLIST_MAX 256 // Number of elements in the list Delete data Wis
|
||||
|
||||
|
||||
Sql* sql_handle = NULL; ///Link to mysql db, connection FD
|
||||
|
||||
@@ -66,13 +69,18 @@ int inter_recv_packet_length[] = {
|
||||
2,-1, 6, 6, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, // 30A0- Clan packets
|
||||
};
|
||||
|
||||
#ifndef WHISPER_MESSAGE_SIZE
|
||||
#define WHISPER_MESSAGE_SIZE 512
|
||||
#endif
|
||||
|
||||
struct WisData {
|
||||
int id, fd, count, len, gmlvl;
|
||||
t_tick tick;
|
||||
char src[NAME_LENGTH], dst[NAME_LENGTH], msg[512];
|
||||
char src[NAME_LENGTH], dst[NAME_LENGTH], msg[WHISPER_MESSAGE_SIZE];
|
||||
};
|
||||
static DBMap* wis_db = NULL; // int wis_id -> struct WisData*
|
||||
static int wis_dellist[WISDELLIST_MAX], wis_delnum;
|
||||
|
||||
// int wis_id -> struct WisData*
|
||||
static std::unordered_map<int32, std::shared_ptr<struct WisData>> wis_db;
|
||||
|
||||
/* from pc.cpp due to @accinfo. any ideas to replace this crap are more than welcome. */
|
||||
const char* job_name(int class_) {
|
||||
@@ -405,7 +413,7 @@ void geoip_readdb(void){
|
||||
ShowStatus("Finished Reading " CL_GREEN "GeoIP" CL_RESET " Database.\n");
|
||||
}
|
||||
/* [Dekamaster/Nightroad] */
|
||||
/* WHY NOT A DBMAP: There are millions of entries in GeoIP and it has its own algorithm to go quickly through them, a DBMap wouldn't be efficient */
|
||||
/* There are millions of entries in GeoIP and it has its own algorithm to go quickly through them */
|
||||
const char* geoip_getcountry(uint32 ipnum){
|
||||
int depth;
|
||||
unsigned int x;
|
||||
@@ -987,7 +995,6 @@ int inter_init_sql(const char *file)
|
||||
Sql_ShowDebug(sql_handle);
|
||||
}
|
||||
|
||||
wis_db = idb_alloc(DB_OPT_RELEASE_DATA);
|
||||
interServerDb.load();
|
||||
inter_guild_sql_init();
|
||||
inter_storage_sql_init();
|
||||
@@ -1007,7 +1014,7 @@ int inter_init_sql(const char *file)
|
||||
// finalize
|
||||
void inter_final(void)
|
||||
{
|
||||
wis_db->destroy(wis_db, NULL);
|
||||
wis_db.clear();
|
||||
|
||||
inter_guild_sql_final();
|
||||
inter_storage_sql_final();
|
||||
@@ -1073,8 +1080,7 @@ int mapif_broadcast(unsigned char *mes, int len, unsigned long fontColor, short
|
||||
}
|
||||
|
||||
// Wis sending
|
||||
int mapif_wis_message(struct WisData *wd)
|
||||
{
|
||||
int mapif_wis_message( std::shared_ptr<struct WisData> wd ){
|
||||
unsigned char buf[2048];
|
||||
int headersize = 12 + 2 * NAME_LENGTH;
|
||||
|
||||
@@ -1116,40 +1122,19 @@ int mapif_disconnectplayer(int fd, uint32 account_id, uint32 char_id, int reason
|
||||
|
||||
//--------------------------------------------------------
|
||||
|
||||
/**
|
||||
* Existence check of WISP data
|
||||
* @see DBApply
|
||||
*/
|
||||
int check_ttl_wisdata_sub(DBKey key, DBData *data, va_list ap)
|
||||
{
|
||||
t_tick tick;
|
||||
struct WisData *wd = (struct WisData *)db_data2ptr(data);
|
||||
tick = va_arg(ap, t_tick);
|
||||
|
||||
if (DIFF_TICK(tick, wd->tick) > WISDATA_TTL && wis_delnum < WISDELLIST_MAX)
|
||||
wis_dellist[wis_delnum++] = wd->id;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int check_ttl_wisdata(void)
|
||||
{
|
||||
void check_ttl_wisdata(){
|
||||
t_tick tick = gettick();
|
||||
int i;
|
||||
|
||||
do {
|
||||
wis_delnum = 0;
|
||||
wis_db->foreach(wis_db, check_ttl_wisdata_sub, tick);
|
||||
for(i = 0; i < wis_delnum; i++) {
|
||||
struct WisData *wd = (struct WisData*)idb_get(wis_db, wis_dellist[i]);
|
||||
ShowWarning("inter: wis data id=%d time out : from %s to %s\n", wd->id, wd->src, wd->dst);
|
||||
// removed. not send information after a timeout. Just no answer for the player
|
||||
//mapif_wis_reply(wd->fd, wd->src, 1); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
|
||||
idb_remove(wis_db, wd->id);
|
||||
for( auto it = wis_db.begin(); it != wis_db.end(); ){
|
||||
std::shared_ptr<struct WisData> wd = it->second;
|
||||
|
||||
if( DIFF_TICK( tick, wd->tick ) > WISDATA_TTL ){
|
||||
ShowWarning( "inter: wis data id=%d time out : from %s to %s\n", wd->id, wd->src, wd->dst );
|
||||
it = wis_db.erase( it );
|
||||
}else{
|
||||
it++;
|
||||
}
|
||||
} while(wis_delnum >= WISDELLIST_MAX);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------------
|
||||
@@ -1193,7 +1178,6 @@ int mapif_wis_reply( int mapserver_fd, char* target, uint8 flag ){
|
||||
// Wisp/page request to send
|
||||
int mapif_parse_WisRequest(int fd)
|
||||
{
|
||||
struct WisData* wd;
|
||||
char name[NAME_LENGTH];
|
||||
char esc_name[NAME_LENGTH*2+1];// escaped name
|
||||
char* data;
|
||||
@@ -1203,7 +1187,7 @@ int mapif_parse_WisRequest(int fd)
|
||||
|
||||
if ( fd <= 0 ) {return 0;} // check if we have a valid fd
|
||||
|
||||
if (RFIFOW(fd,2)-headersize >= sizeof(wd->msg)) {
|
||||
if( RFIFOW( fd, 2 ) - headersize >= WHISPER_MESSAGE_SIZE ){
|
||||
ShowWarning("inter: Wis message size too long.\n");
|
||||
return 0;
|
||||
} else if (RFIFOW(fd,2)-headersize <= 0) { // normaly, impossible, but who knows...
|
||||
@@ -1237,11 +1221,11 @@ int mapif_parse_WisRequest(int fd)
|
||||
{
|
||||
static int wisid = 0;
|
||||
|
||||
CREATE(wd, struct WisData, 1);
|
||||
|
||||
// Whether the failure of previous wisp/page transmission (timeout)
|
||||
check_ttl_wisdata();
|
||||
|
||||
std::shared_ptr<struct WisData> wd = std::make_shared<struct WisData>();
|
||||
|
||||
wd->id = ++wisid;
|
||||
wd->fd = fd;
|
||||
wd->len= RFIFOW(fd,2)-headersize;
|
||||
@@ -1250,8 +1234,10 @@ int mapif_parse_WisRequest(int fd)
|
||||
safestrncpy(wd->dst, RFIFOCP(fd,8+NAME_LENGTH), NAME_LENGTH);
|
||||
safestrncpy(wd->msg, RFIFOCP(fd,8+2*NAME_LENGTH), wd->len);
|
||||
wd->tick = gettick();
|
||||
idb_put(wis_db, wd->id, wd);
|
||||
mapif_wis_message(wd);
|
||||
|
||||
wis_db[wd->id] = wd;
|
||||
|
||||
mapif_wis_message( wd );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1263,19 +1249,20 @@ int mapif_parse_WisRequest(int fd)
|
||||
// Wisp/page transmission result
|
||||
int mapif_parse_WisReply(int fd)
|
||||
{
|
||||
int id;
|
||||
int32 id;
|
||||
uint8 flag;
|
||||
struct WisData *wd;
|
||||
|
||||
id = RFIFOL(fd,2);
|
||||
flag = RFIFOB(fd,6);
|
||||
wd = (struct WisData*)idb_get(wis_db, id);
|
||||
if (wd == NULL)
|
||||
std::shared_ptr<struct WisData> wd = util::umap_find( wis_db, id );
|
||||
|
||||
if( wd == nullptr ){
|
||||
return 0; // This wisp was probably suppress before, because it was timeout of because of target was found on another map-server
|
||||
}
|
||||
|
||||
if ((--wd->count) <= 0 || flag != 1) {
|
||||
mapif_wis_reply(wd->fd, wd->src, flag); // flag: 0: success to send wisper, 1: target character is not loged in?, 2: ignored by target
|
||||
idb_remove(wis_db, id);
|
||||
wis_db.erase( id );
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -18,6 +18,8 @@
|
||||
#include "showmsg.hpp"
|
||||
#include "timer.hpp"
|
||||
|
||||
using namespace rathena::server_core;
|
||||
|
||||
//map confs
|
||||
const char* MAP_CONF_NAME;
|
||||
const char* INTER_CONF_NAME;
|
||||
@@ -110,14 +112,12 @@ int cli_get_options(int argc, char ** argv) {
|
||||
MSG_CONF_NAME_EN = argv[++i];
|
||||
}
|
||||
else if (strcmp(arg, "run-once") == 0) { // close the map-server as soon as its done.. for testing [Celest]
|
||||
runflag = CORE_ST_STOP;
|
||||
}
|
||||
else if (SERVER_TYPE & (ATHENA_SERVER_LOGIN | ATHENA_SERVER_CHAR)) { //login or char
|
||||
global_core->set_run_once( true );
|
||||
}else if( global_core->get_type() == e_core_type::LOGIN || global_core->get_type() == e_core_type::CHARACTER ){
|
||||
if (strcmp(arg, "lan-config") == 0) {
|
||||
if (opt_has_next_value(arg, i, argc))
|
||||
LAN_CONF_NAME = argv[++i];
|
||||
}
|
||||
else if (SERVER_TYPE == ATHENA_SERVER_LOGIN) { //login
|
||||
}else if( global_core->get_type() == e_core_type::LOGIN ){
|
||||
if (strcmp(arg, "login-config") == 0) {
|
||||
if (opt_has_next_value(arg, i, argc))
|
||||
LOGIN_CONF_NAME = argv[++i];
|
||||
@@ -126,8 +126,7 @@ int cli_get_options(int argc, char ** argv) {
|
||||
ShowError("Unknown option '%s'.\n", argv[i]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else if (SERVER_TYPE == ATHENA_SERVER_CHAR) { //char
|
||||
}else if( global_core->get_type() == e_core_type::CHARACTER ){
|
||||
if (strcmp(arg, "char-config") == 0) {
|
||||
if (opt_has_next_value(arg, i, argc))
|
||||
CHAR_CONF_NAME = argv[++i];
|
||||
@@ -141,8 +140,7 @@ int cli_get_options(int argc, char ** argv) {
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (SERVER_TYPE == ATHENA_SERVER_MAP) { //map
|
||||
}else if( global_core->get_type() == e_core_type::MAP ){
|
||||
if (strcmp(arg, "map-config") == 0) {
|
||||
if (opt_has_next_value(arg, i, argc))
|
||||
MAP_CONF_NAME = argv[++i];
|
||||
|
||||
@@ -128,6 +128,7 @@
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\zlib\include\;$(SolutionDir)3rdparty\mysql\include\;$(SolutionDir)3rdparty\libconfig\;$(SolutionDir)3rdparty\yaml-cpp\include\</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)3rdparty\zlib\include\;$(SolutionDir)3rdparty\libconfig\</AdditionalIncludeDirectories>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
|
||||
@@ -160,6 +160,7 @@
|
||||
<PreprocessorDefinitions>$(DefineConstants);WIN32;FD_SETSIZE=4096;PCRE_SUPPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;_DEBUG;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<AdditionalIncludeDirectories>$(SolutionDir)\3rdparty\rapidyaml\src;$(SolutionDir)\3rdparty\rapidyaml\ext\c4core\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
@@ -235,4 +236,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
||||
|
||||
@@ -37,19 +37,18 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
/// Called when a terminate signal is received.
|
||||
void (*shutdown_callback)(void) = NULL;
|
||||
using namespace rathena::server_core;
|
||||
|
||||
Core* global_core = nullptr;
|
||||
|
||||
#if defined(BUILDBOT)
|
||||
int buildbotflag = 0;
|
||||
#endif
|
||||
|
||||
int runflag = CORE_ST_RUN;
|
||||
char db_path[12] = "db"; /// relative path for db from server
|
||||
char conf_path[12] = "conf"; /// relative path for conf from server
|
||||
|
||||
char *SERVER_NAME = NULL;
|
||||
char SERVER_TYPE = ATHENA_SERVER_NONE;
|
||||
|
||||
#ifndef MINICORE // minimalist Core
|
||||
// Added by Gabuzomeu
|
||||
@@ -91,10 +90,9 @@ static BOOL WINAPI console_handler(DWORD c_event) {
|
||||
case CTRL_CLOSE_EVENT:
|
||||
case CTRL_LOGOFF_EVENT:
|
||||
case CTRL_SHUTDOWN_EVENT:
|
||||
if( shutdown_callback != NULL )
|
||||
shutdown_callback();
|
||||
else
|
||||
runflag = CORE_ST_STOP;// auto-shutdown
|
||||
if( global_core != nullptr ){
|
||||
global_core->signal_shutdown();
|
||||
}
|
||||
break;
|
||||
default:
|
||||
return FALSE;
|
||||
@@ -119,14 +117,15 @@ static void sig_proc(int sn) {
|
||||
case SIGTERM:
|
||||
if (++is_called > 3)
|
||||
exit(EXIT_SUCCESS);
|
||||
if( shutdown_callback != NULL )
|
||||
shutdown_callback();
|
||||
else
|
||||
runflag = CORE_ST_STOP;// auto-shutdown
|
||||
if( global_core != nullptr ){
|
||||
global_core->signal_shutdown();
|
||||
}
|
||||
break;
|
||||
case SIGSEGV:
|
||||
case SIGFPE:
|
||||
do_abort();
|
||||
if( global_core != nullptr ){
|
||||
global_core->signal_crash();
|
||||
}
|
||||
// Pass the signal to the system's default handler
|
||||
compat_signal(sn, SIG_DFL);
|
||||
raise(sn);
|
||||
@@ -329,11 +328,14 @@ void usercheck(void)
|
||||
#endif
|
||||
}
|
||||
|
||||
/*======================================
|
||||
* CORE : MAINROUTINE
|
||||
*--------------------------------------*/
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
int Core::start( int argc, char **argv ){
|
||||
if( this->get_status() != e_core_status::NOT_STARTED) {
|
||||
ShowFatalError( "Core was already started and cannot be started again!\n" );
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
this->set_status( e_core_status::CORE_INITIALIZING );
|
||||
|
||||
{// initialize program arguments
|
||||
char *p1;
|
||||
if((p1 = strrchr(argv[0], '/')) != NULL || (p1 = strrchr(argv[0], '\\')) != NULL ){
|
||||
@@ -352,17 +354,10 @@ int main (int argc, char **argv)
|
||||
}
|
||||
|
||||
malloc_init();// needed for Show* in display_title() [FlavioJS]
|
||||
|
||||
#ifdef MINICORE // minimalist Core
|
||||
display_title();
|
||||
usercheck();
|
||||
do_init(argc,argv);
|
||||
do_final();
|
||||
#else// not MINICORE
|
||||
set_server_type();
|
||||
display_title();
|
||||
usercheck();
|
||||
|
||||
#ifndef MINICORE
|
||||
Sql_Init();
|
||||
db_init();
|
||||
signals_init();
|
||||
@@ -370,24 +365,41 @@ int main (int argc, char **argv)
|
||||
#ifdef _WIN32
|
||||
cevents_init();
|
||||
#endif
|
||||
|
||||
timer_init();
|
||||
socket_init();
|
||||
#endif
|
||||
|
||||
do_init(argc,argv);
|
||||
this->set_status( e_core_status::CORE_INITIALIZED );
|
||||
|
||||
// Main runtime cycle
|
||||
while (runflag != CORE_ST_STOP) {
|
||||
t_tick next = do_timer(gettick_nocache());
|
||||
|
||||
if (SERVER_TYPE != ATHENA_SERVER_WEB)
|
||||
do_sockets(next);
|
||||
else
|
||||
do_wait(next);
|
||||
this->set_status( e_core_status::SERVER_INITIALIZING );
|
||||
if( !this->initialize( argc, argv ) ){
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
|
||||
do_final();
|
||||
// If initialization did not trigger shutdown
|
||||
if( this->m_status != e_core_status::STOPPING ){
|
||||
this->set_status( e_core_status::SERVER_INITIALIZED );
|
||||
|
||||
this->set_status( e_core_status::RUNNING );
|
||||
#ifndef MINICORE
|
||||
if( !this->m_run_once ){
|
||||
// Main runtime cycle
|
||||
while( this->get_status() == e_core_status::RUNNING ){
|
||||
t_tick next = do_timer( gettick_nocache() );
|
||||
|
||||
this->handle_main( next );
|
||||
}
|
||||
}
|
||||
#endif
|
||||
this->set_status( e_core_status::STOPPING );
|
||||
}
|
||||
|
||||
this->set_status( e_core_status::SERVER_FINALIZING );
|
||||
this->finalize();
|
||||
this->set_status( e_core_status::SERVER_FINALIZED );
|
||||
|
||||
this->set_status( e_core_status::CORE_FINALIZING );
|
||||
#ifndef MINICORE
|
||||
timer_final();
|
||||
socket_final();
|
||||
db_final();
|
||||
@@ -395,6 +407,7 @@ int main (int argc, char **argv)
|
||||
#endif
|
||||
|
||||
malloc_final();
|
||||
this->set_status( e_core_status::CORE_FINALIZED );
|
||||
|
||||
#if defined(BUILDBOT)
|
||||
if( buildbotflag ){
|
||||
@@ -402,5 +415,71 @@ int main (int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
this->set_status( e_core_status::STOPPED );
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
bool Core::initialize( int argc, char* argv[] ){
|
||||
// Do nothing
|
||||
return true;
|
||||
}
|
||||
|
||||
void Core::handle_main( t_tick next ){
|
||||
#ifndef MINICORE
|
||||
// By default we handle all socket packets
|
||||
do_sockets( next );
|
||||
#endif
|
||||
}
|
||||
|
||||
void Core::handle_crash(){
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void Core::handle_shutdown(){
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void Core::finalize(){
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void Core::set_status( e_core_status status ){
|
||||
this->m_status = status;
|
||||
}
|
||||
|
||||
e_core_status Core::get_status(){
|
||||
return this->m_status;
|
||||
}
|
||||
|
||||
e_core_type Core::get_type(){
|
||||
return this->m_type;
|
||||
}
|
||||
|
||||
bool Core::is_running(){
|
||||
return this->get_status() == e_core_status::RUNNING;
|
||||
}
|
||||
|
||||
void Core::set_run_once( bool run_once ){
|
||||
this->m_run_once = run_once;
|
||||
}
|
||||
|
||||
void Core::signal_crash(){
|
||||
this->set_status( e_core_status::STOPPING );
|
||||
|
||||
if( this->m_crashed ){
|
||||
ShowFatalError( "Received another crash signal, while trying to handle the last crash!\n" );
|
||||
}else{
|
||||
ShowFatalError( "Received a crash signal, trying to handle it as good as possible!\n" );
|
||||
this->m_crashed = true;
|
||||
this->handle_crash();
|
||||
}
|
||||
|
||||
// Now stop the process
|
||||
exit( EXIT_FAILURE );
|
||||
}
|
||||
|
||||
void Core::signal_shutdown(){
|
||||
this->set_status( e_core_status::STOPPING );
|
||||
this->handle_shutdown();
|
||||
}
|
||||
|
||||
@@ -4,55 +4,102 @@
|
||||
#ifndef CORE_HPP
|
||||
#define CORE_HPP
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
#include "timer.hpp"
|
||||
|
||||
#ifdef _WIN32
|
||||
#include "winapi.hpp" // Console close event handling
|
||||
#endif
|
||||
|
||||
/* so that developers with --enable-debug can raise signals from any section of the code they'd like */
|
||||
#ifdef DEBUG
|
||||
#include <signal.h>
|
||||
#endif
|
||||
|
||||
extern int arg_c;
|
||||
extern char **arg_v;
|
||||
|
||||
#if defined(BUILDBOT)
|
||||
extern int buildbotflag;
|
||||
#endif
|
||||
|
||||
#define UNKNOWN_VERSION '\x02'
|
||||
|
||||
/// @see E_CORE_ST
|
||||
extern int runflag;
|
||||
extern char *SERVER_NAME;
|
||||
extern char db_path[12]; /// relative path for db from servers
|
||||
extern char conf_path[12]; /// relative path for conf from servers
|
||||
|
||||
enum {
|
||||
ATHENA_SERVER_NONE = 0, // not defined
|
||||
ATHENA_SERVER_LOGIN = 1, // login server
|
||||
ATHENA_SERVER_CHAR = 2, // char server
|
||||
ATHENA_SERVER_INTER = 4, // inter server
|
||||
ATHENA_SERVER_MAP = 8, // map server
|
||||
ATHENA_SERVER_WEB = 16, // web server
|
||||
};
|
||||
|
||||
extern char SERVER_TYPE;
|
||||
|
||||
extern int parse_console(const char* buf);
|
||||
const char *get_svn_revision(void);
|
||||
const char *get_git_hash(void);
|
||||
extern int do_init(int,char**);
|
||||
extern void set_server_type(void);
|
||||
extern void do_abort(void);
|
||||
extern void do_final(void);
|
||||
|
||||
/// The main loop continues until runflag is CORE_ST_STOP
|
||||
enum E_CORE_ST
|
||||
{
|
||||
CORE_ST_STOP = 0,
|
||||
CORE_ST_RUN,
|
||||
CORE_ST_LAST
|
||||
};
|
||||
namespace rathena{
|
||||
namespace server_core{
|
||||
enum class e_core_status{
|
||||
NOT_STARTED,
|
||||
CORE_INITIALIZING,
|
||||
CORE_INITIALIZED,
|
||||
SERVER_INITIALIZING,
|
||||
SERVER_INITIALIZED,
|
||||
RUNNING,
|
||||
STOPPING,
|
||||
SERVER_FINALIZING,
|
||||
SERVER_FINALIZED,
|
||||
CORE_FINALIZING,
|
||||
CORE_FINALIZED,
|
||||
STOPPED,
|
||||
};
|
||||
|
||||
/// Called when a terminate signal is received. (Ctrl+C pressed)
|
||||
/// If NULL, runflag is set to CORE_ST_STOP instead.
|
||||
extern void (*shutdown_callback)(void);
|
||||
enum class e_core_type{
|
||||
LOGIN,
|
||||
CHARACTER,
|
||||
MAP,
|
||||
TOOL,
|
||||
WEB
|
||||
};
|
||||
|
||||
class Core{
|
||||
private:
|
||||
e_core_status m_status;
|
||||
e_core_type m_type;
|
||||
bool m_run_once;
|
||||
bool m_crashed;
|
||||
|
||||
protected:
|
||||
virtual bool initialize( int argc, char* argv[] );
|
||||
virtual void handle_main( t_tick next );
|
||||
virtual void finalize();
|
||||
virtual void handle_crash();
|
||||
virtual void handle_shutdown();
|
||||
void set_status( e_core_status status );
|
||||
|
||||
public:
|
||||
Core( e_core_type type ){
|
||||
this->m_status = e_core_status::NOT_STARTED;
|
||||
this->m_run_once = false;
|
||||
this->m_crashed = false;
|
||||
this->m_type = type;
|
||||
}
|
||||
|
||||
e_core_status get_status();
|
||||
e_core_type get_type();
|
||||
bool is_running();
|
||||
// TODO: refactor to protected
|
||||
void set_run_once( bool run_once );
|
||||
void signal_crash();
|
||||
void signal_shutdown();
|
||||
int start( int argc, char* argv[] );
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
extern rathena::server_core::Core* global_core;
|
||||
|
||||
template <typename T> int main_core( int argc, char *argv[] ){
|
||||
T server = {};
|
||||
|
||||
global_core = &server;
|
||||
|
||||
return server.start( argc, argv );
|
||||
}
|
||||
|
||||
#endif /* CORE_HPP */
|
||||
|
||||
@@ -193,7 +193,7 @@ static void *ers_obj_alloc_entry(ERS *self)
|
||||
instance->Cache->ReuseList = instance->Cache->ReuseList->Next;
|
||||
} else if (instance->Cache->Free > 0) {
|
||||
instance->Cache->Free--;
|
||||
ret = &instance->Cache->Blocks[instance->Cache->Used - 1][instance->Cache->Free * instance->Cache->ObjectSize + sizeof(struct ers_list)];
|
||||
ret = &instance->Cache->Blocks[instance->Cache->Used - 1][static_cast<size_t>( instance->Cache->Free ) * static_cast<size_t>( instance->Cache->ObjectSize ) + sizeof( struct ers_list )];
|
||||
} else {
|
||||
if (instance->Cache->Used == instance->Cache->Max) {
|
||||
instance->Cache->Max = (instance->Cache->Max * 4) + 3;
|
||||
@@ -204,7 +204,7 @@ static void *ers_obj_alloc_entry(ERS *self)
|
||||
instance->Cache->Used++;
|
||||
|
||||
instance->Cache->Free = instance->Cache->ChunkSize -1;
|
||||
ret = &instance->Cache->Blocks[instance->Cache->Used - 1][instance->Cache->Free * instance->Cache->ObjectSize + sizeof(struct ers_list)];
|
||||
ret = &instance->Cache->Blocks[instance->Cache->Used - 1][static_cast<size_t>( instance->Cache->Free ) * static_cast<size_t>( instance->Cache->ObjectSize ) + sizeof( struct ers_list )];
|
||||
}
|
||||
|
||||
instance->Count++;
|
||||
|
||||
@@ -81,6 +81,12 @@ typedef uint32 t_itemid;
|
||||
#define MAX_AMOUNT 30000 ////Max amount of a single stacked item
|
||||
#define MAX_ZENY INT_MAX ///Max zeny
|
||||
#define MAX_BANK_ZENY SINT32_MAX ///Max zeny in Bank
|
||||
#ifndef MAX_CASHPOINT
|
||||
#define MAX_CASHPOINT INT_MAX
|
||||
#endif
|
||||
#ifndef MAX_KAFRAPOINT
|
||||
#define MAX_KAFRAPOINT INT_MAX
|
||||
#endif
|
||||
#define MAX_FAME 1000000000 ///Max fame points
|
||||
#define MAX_CART 100 ///Maximum item in cart
|
||||
#define MAX_SKILL 1454 ///Maximum skill can be hold by Player, Homunculus, & Mercenary (skill list) AND skill_db limit
|
||||
@@ -353,8 +359,8 @@ enum equip_pos : uint32 {
|
||||
};
|
||||
|
||||
struct point {
|
||||
unsigned short map;
|
||||
short x,y;
|
||||
uint16 map;
|
||||
uint16 x,y;
|
||||
};
|
||||
|
||||
struct startitem {
|
||||
@@ -402,6 +408,8 @@ struct status_change_data {
|
||||
unsigned short type; //SC_type
|
||||
long val1, val2, val3, val4;
|
||||
t_tick tick; //Remaining duration.
|
||||
t_tick tick_total; // Total duration
|
||||
t_tick tick_time; // Interval duration
|
||||
};
|
||||
|
||||
#define MAX_BONUS_SCRIPT_LENGTH 512
|
||||
@@ -693,14 +701,14 @@ struct party {
|
||||
struct party_member member[MAX_PARTY];
|
||||
};
|
||||
|
||||
struct map_session_data;
|
||||
class map_session_data;
|
||||
struct guild_member {
|
||||
uint32 account_id, char_id;
|
||||
short hair,hair_color,gender,class_,lv;
|
||||
t_exp exp;
|
||||
short online,position;
|
||||
char name[NAME_LENGTH];
|
||||
struct map_session_data *sd;
|
||||
map_session_data *sd;
|
||||
unsigned char modified;
|
||||
uint32 last_login;
|
||||
};
|
||||
@@ -754,11 +762,25 @@ struct guild {
|
||||
int32 chargeshout_flag_id;
|
||||
};
|
||||
|
||||
enum e_woe_type{
|
||||
WOE_FIRST_EDITION = 1,
|
||||
WOE_SECOND_EDITION,
|
||||
WOE_THIRD_EDITION,
|
||||
WOE_MAX
|
||||
};
|
||||
|
||||
struct guild_castle {
|
||||
int castle_id;
|
||||
int mapindex;
|
||||
char castle_name[NAME_LENGTH];
|
||||
char castle_event[NPC_NAME_LENGTH];
|
||||
e_woe_type type;
|
||||
uint16 client_id;
|
||||
bool warp_enabled;
|
||||
uint16 warp_x;
|
||||
uint16 warp_y;
|
||||
uint32 zeny;
|
||||
uint32 zeny_siege;
|
||||
int guild_id;
|
||||
int economy;
|
||||
int defense;
|
||||
@@ -1121,7 +1143,7 @@ struct clan{
|
||||
char master[NAME_LENGTH];
|
||||
char map[MAP_NAME_LENGTH_EXT];
|
||||
short max_member, connect_member;
|
||||
struct map_session_data *members[MAX_CLAN];
|
||||
map_session_data *members[MAX_CLAN];
|
||||
struct clan_alliance alliance[MAX_CLANALLIANCE];
|
||||
unsigned short instance_id;
|
||||
};
|
||||
|
||||
@@ -40,9 +40,6 @@
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "cbasetypes.hpp"
|
||||
#include "malloc.hpp"
|
||||
#include "mmo.hpp"
|
||||
@@ -890,14 +887,6 @@ int WFIFOSET(int fd, size_t len)
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// replacement for do_sockets, where it does nothing
|
||||
int do_wait(t_tick next)
|
||||
{
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(next));
|
||||
return 0;
|
||||
}
|
||||
|
||||
int do_sockets(t_tick next)
|
||||
{
|
||||
#ifndef SOCKET_EPOLL
|
||||
|
||||
@@ -133,7 +133,6 @@ int WFIFOSET(int fd, size_t len);
|
||||
int RFIFOSKIP(int fd, size_t len);
|
||||
|
||||
int do_sockets(t_tick next);
|
||||
int do_wait(t_tick next);
|
||||
void do_close(int fd);
|
||||
void socket_init(void);
|
||||
void socket_final(void);
|
||||
|
||||
@@ -109,6 +109,7 @@
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>FD_SETSIZE=4096;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_DEPRECATE;_WINSOCK_DEPRECATED_NO_WARNINGS;LIBCONFIG_STATIC;YY_USE_CONST;WIN32;_DEBUG;_CONSOLE;_LIB;_ITERATOR_DEBUG_LEVEL=0;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
|
||||
<ConformanceMode>true</ConformanceMode>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user