Compare commits
36 Commits
hotfix/swo
...
refactor/p
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1ab4ebe576 | ||
|
|
69635631c0 | ||
|
|
3ada0c11be | ||
|
|
90b2b9cbbf | ||
|
|
7ddd035442 | ||
|
|
38ca0998fd | ||
|
|
29a3c5263b | ||
|
|
827517f8cf | ||
|
|
6d2ef66bbb | ||
|
|
7ebf47e31c | ||
|
|
2ebdd50e08 | ||
|
|
d949740cd9 | ||
|
|
16e9d52204 | ||
|
|
cad5cab976 | ||
|
|
9e959f7fd6 | ||
|
|
0e434aa73b | ||
|
|
2963e52fc6 | ||
|
|
7c44390606 | ||
|
|
45b588c654 | ||
|
|
5124ddf575 | ||
|
|
0f0bd685d9 | ||
|
|
f15cb72f94 | ||
|
|
75f518859f | ||
|
|
b5e3e5e69b | ||
|
|
3cbdcf999f | ||
|
|
cd7341930e | ||
|
|
25b98c87db | ||
|
|
5df7de2b15 | ||
|
|
089c3056cf | ||
|
|
d05e11aecd | ||
|
|
310fcd6fa1 | ||
|
|
348803193c | ||
|
|
62b0b12274 | ||
|
|
4a7d2b45b5 | ||
|
|
86fcc98081 | ||
|
|
480cf26283 |
9
.git-blame-ignore-revs
Normal file
9
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,9 @@
|
||||
# Massive EOL normalization & 'svn:eol-style native' flag setting for all txt/conf/h/c files.
|
||||
# https://github.com/rathena/rathena/commit/637ae9a4dcde0d5885a18841d2f3875e06893c30
|
||||
637ae9a4dcde0d5885a18841d2f3875e06893c30
|
||||
# Applied AStyle code formating as discussed on tid:74602.
|
||||
# https://github.com/rathena/rathena/commit/a7c32653f70bd420bdf5a621acdf3aea5c6e6002
|
||||
a7c32653f70bd420bdf5a621acdf3aea5c6e6002
|
||||
# Undid r16968: SVN Replaced with source:/trunk/src/@16966 (tid:74924).
|
||||
# https://github.com/rathena/rathena/commit/a2bdc47dafb32f6d18ed350d8bbe79b8f679a049
|
||||
a2bdc47dafb32f6d18ed350d8bbe79b8f679a049
|
||||
2
.github/workflows/build_servers_gcc.yml
vendored
2
.github/workflows/build_servers_gcc.yml
vendored
@@ -31,7 +31,7 @@ jobs:
|
||||
# Available: ubuntu-22.04, ubuntu-20.04
|
||||
os: [ubuntu-latest]
|
||||
# Older versions of GCC are not available via unaltered aptitude repo lists.
|
||||
gcc: ['9', '10', '11']
|
||||
gcc: ['9', '10', '11', '12', '13']
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
|
||||
@@ -33,8 +33,7 @@ max_exp_gain_rate: 0
|
||||
// Method of calculating earned experience when defeating a monster:
|
||||
// 0 = uses damage given / total damage as damage ratio
|
||||
// 1 = uses damage given / max_hp as damage ratio
|
||||
// NOTE: Using type 1 disables the bonus where the first attacker gets
|
||||
// his share of the exp doubled when multiple people attack the mob.
|
||||
// 2 = 0 + first attacker counts twice
|
||||
exp_calc_type: 0
|
||||
|
||||
// Experience increase per attacker. That is, every additional attacker to the
|
||||
|
||||
@@ -79,10 +79,10 @@ monster_chase_refresh: 30
|
||||
// 8: Enable mob-warping when standing on Dimensional Door
|
||||
mob_warp: 0
|
||||
|
||||
// If these are set above 0, they define the time (in ms) during which monsters
|
||||
// will have their 'AI' active after all players have left their vicinity.
|
||||
mob_active_time: 0
|
||||
boss_active_time: 0
|
||||
// Defines the time (in ms) during which monsters will have their AI active
|
||||
// after all players have left their vicinity.
|
||||
mob_active_time: 5000
|
||||
boss_active_time: 5000
|
||||
|
||||
// Mobs and Pets view-range adjustment (range2 column in the mob_db) (Note 2)
|
||||
view_range_rate: 100
|
||||
@@ -302,3 +302,8 @@ slave_stick_with_master: no
|
||||
// Also used in delaying the spawning of guardians when a guild is not loaded.
|
||||
// Default (Official): 1000
|
||||
mob_respawn_time: 1000
|
||||
|
||||
// Defines the time (in ms) after which a monster unlocks its target when trapped.
|
||||
// During this time monsters will still be in idle mode and use idle skills on random
|
||||
// targets, but they continue chasing their original target when no longer trapped.
|
||||
mob_unlock_time: 2000
|
||||
|
||||
45
db/import-tmpl/produce_db.yml
Normal file
45
db/import-tmpl/produce_db.yml
Normal file
@@ -0,0 +1,45 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2023 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 Produce Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Produce Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - ItemLevel Number which determines what kind of a crafting window will pop-up.
|
||||
# Recipe:
|
||||
# - Product AegisName of the produced item.
|
||||
# SkillName Skill name required. (Default: null)
|
||||
# SkillLevel Skill level required. (Default: 1)
|
||||
# Consumed: List of items consumed to produce the Product.
|
||||
# - Item AegisName of the consumed item.
|
||||
# Amount Amount required.
|
||||
# Clear Remove the item with the given AegisName from Consumed. (Optional)
|
||||
# NotConsumed: List of items not consumed to produce the Product. (Default: null)
|
||||
# - Item AegisName of the unconsumed item.
|
||||
# Clear Remove the item with the given AegisName from NotConsumed. (Optional)
|
||||
# BaseRate Base rate (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000)
|
||||
# Make: List of item amounts with their individual rate produced by Change Material (ItemLevel: 26). (Default: null)
|
||||
# - Amount Amount of item created (unique to the list) for Change Material (ItemLevel: 26).
|
||||
# Rate Rate to create the Amount (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000. 0 to remove on import)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: PRODUCE_DB
|
||||
Version: 1
|
||||
@@ -1,11 +0,0 @@
|
||||
// Change Material Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// ID,ProductID,BaseRate,MakeAmount1,MakeAmountRate1...,MakeAmount5,MakeAmountRate5
|
||||
//
|
||||
// NOTE:
|
||||
// - ID is used to identify item order that will be used for overwriting on db/import.
|
||||
// Value is started from 0 until 74 (MAX_SKILL_CHANGEMATERIAL_DB-1). Use same ID on import file to overwrite original result & requirements
|
||||
// - Up to 5 ID/Amount pairs can be specified.
|
||||
// - Rate = n/10%
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -102,7 +102,7 @@
|
||||
1019,Peco Peco@NPC_EMOTION,chase,197,1,2000,0,5000,yes,self,always,0,6,,,,,,
|
||||
1019,Peco Peco@NPC_FIREATTACK,attack,186,1,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
1019,Peco Peco@NPC_PROVOCATION,chase,194,1,200,0,5000,yes,target,always,0,,,,,,19,
|
||||
1020,Mandragora@NPC_GROUNDATTACK,attack,185,1,2000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1020,Mandragora@NPC_GROUNDATTACK,attack,185,1,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
1023,Orc Warrior@NPC_EMOTION,chase,197,1,2000,0,5000,yes,self,always,0,,,,,,,
|
||||
1023,Orc Warrior@NPC_GROUNDATTACK,attack,185,2,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1023,Orc Warrior@NPC_EMOTION,chase,197,1,200,0,5000,yes,self,always,0,19,0x81,,,,,
|
||||
@@ -349,7 +349,7 @@
|
||||
1067,Cornutus@NPC_WATERATTACK,attack,184,2,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1067,Cornutus@CR_AUTOGUARD,attack,249,2,500,0,300000,yes,self,always,0,,,,,,,
|
||||
1067,Cornutus@CR_AUTOGUARD,chase,249,2,2000,0,300000,yes,self,longrangeattacked,,,,,,,,
|
||||
1068,Hydra@NPC_WATERATTACK,attack,184,2,500,500,5000,no,randomtarget,always,0,,,,,,,
|
||||
1068,Hydra@NPC_WATERATTACK,attack,184,2,500,500,5000,no,target,always,0,,,,,,,
|
||||
1069,Swordfish@NPC_WATERATTACK,attack,184,1,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
1069,Swordfish@WZ_WATERBALL,attack,86,3,500,1500,5000,yes,target,always,0,,,,,,,
|
||||
1069,Swordfish@WZ_WATERBALL,chase,86,3,500,1500,5000,yes,target,always,0,,,,,,,
|
||||
@@ -601,9 +601,9 @@
|
||||
1117,Evil Druid@NPC_UNDEADATTACK,chase,347,3,500,500,5000,no,target,always,0,,,,,,9,
|
||||
1117,Evil Druid@WZ_HEAVENDRIVE,attack,91,5,500,1200,5000,yes,target,always,0,,,,,,,
|
||||
1117,Evil Druid@WZ_HEAVENDRIVE,chase,91,5,500,1200,5000,yes,target,always,0,,,,,,,
|
||||
1118,Flora@NPC_BLOODDRAIN,attack,199,1,500,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1118,Flora@NPC_BLOODDRAIN,attack,199,1,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1118,Flora@NPC_EMOTION,idle,197,1,2000,0,5000,yes,self,always,0,2,,,,,,
|
||||
1118,Flora@NPC_GROUNDATTACK,attack,185,1,2000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1118,Flora@NPC_GROUNDATTACK,attack,185,1,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
1119,Frilldora@AS_CLOAKING,attack,135,1,2000,200,5000,yes,self,always,0,,,,,,,
|
||||
1119,Frilldora@AS_CLOAKING,idle,135,1,2000,200,5000,yes,self,always,0,,,,,,,
|
||||
1119,Frilldora@AS_CLOAKING,chase,135,1,2000,200,5000,yes,self,always,0,,,,,,,
|
||||
@@ -1297,7 +1297,7 @@
|
||||
1276,Raydric Archer@CR_AUTOGUARD,attack,249,2,500,0,300000,yes,self,always,0,,,,,,,
|
||||
1277,Greatest General@NPC_BLINDATTACK,idle,177,3,10000,1500,5000,no,randomtarget,longrangeattacked,,,,,,,6,
|
||||
1277,Greatest General@NPC_BLINDATTACK,idle,177,3,10000,1500,5000,no,randomtarget,casttargeted,,,,,,,6,
|
||||
1277,Greatest General@NPC_FIREATTACK,attack,186,2,500,500,5000,no,randomtarget,always,0,,,,,,,
|
||||
1277,Greatest General@NPC_FIREATTACK,attack,186,2,500,500,5000,no,target,always,0,,,,,,,
|
||||
1277,Greatest General@WZ_EARTHSPIKE,idle,90,3,5000,1500,5000,no,randomtarget,longrangeattacked,,,,,,,6,
|
||||
1277,Greatest General@WZ_EARTHSPIKE,idle,90,3,5000,1500,5000,no,randomtarget,casttargeted,,,,,,,6,
|
||||
1278,Stalactite Golem@NPC_STUNATTACK,attack,179,4,500,1500,5000,no,target,always,0,,,,,,6,
|
||||
@@ -1580,7 +1580,7 @@
|
||||
1367,Blazer@WZ_SIGHTRASHER,attack,81,5,500,1000,5000,no,target,always,0,,,,,,6,
|
||||
1368,Geographer@AL_HEAL,attack,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,60,,,,,,,
|
||||
1368,Geographer@AL_HEAL,idle,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,60,,,,,,,
|
||||
1368,Geographer@NPC_SLEEPATTACK,attack,182,5,500,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1368,Geographer@NPC_SLEEPATTACK,attack,182,5,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1369,Grand Peco@AS_SONICBLOW,attack,136,5,500,800,5000,no,target,always,0,,,,,,6,
|
||||
1369,Grand Peco@NPC_FIREATTACK,attack,186,3,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1369,Grand Peco@NPC_EMOTION,chase,197,1,200,0,5000,yes,self,always,0,19,0x81,,,,,
|
||||
@@ -2563,8 +2563,8 @@
|
||||
1510,Hylozoist@MO_BODYRELOCATION,chase,264,1,2000,500,5000,no,target,always,0,,,,,,,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,idle,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,idle,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,target,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,target,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_SUMMONMONSTER,idle,209,5,5000,0,10000,no,self,longrangeattacked,0,1474,1477,1438,,,9,
|
||||
1511,Amon Ra@NPC_SUMMONMONSTER,idle,209,5,5000,0,10000,no,self,casttargeted,0,1474,1477,1438,,,9,
|
||||
1511,Amon Ra@NPC_SUMMONMONSTER,attack,209,5,5000,0,10000,no,self,longrangeattacked,0,1474,1477,1438,,,9,
|
||||
@@ -2583,11 +2583,11 @@
|
||||
1511,Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,skillused,83,,,,,,9,
|
||||
1511,Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,longrangeattacked,,,,,,,9,
|
||||
1511,Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,casttargeted,,,,,,,9,
|
||||
1511,Amon Ra@WZ_METEOR,attack,83,11,5000,0,3000,yes,randomtarget,always,0,,,,,,9,
|
||||
1511,Amon Ra@WZ_METEOR,attack,83,11,5000,0,3000,yes,target,always,0,,,,,,9,
|
||||
1511,Amon Ra@WZ_FIREPILLAR,idle,80,10,10000,0,2000,yes,around2,always,0,,,,,,,
|
||||
1511,Amon Ra@WZ_FIREPILLAR,idle,80,10,10000,0,2000,yes,around2,always,0,,,,,,,
|
||||
1511,Amon Ra@WZ_FIREPILLAR,attack,80,10,5000,0,2000,yes,around2,always,0,,,,,,,
|
||||
1511,Amon Ra@NPC_DARKBLESSING,attack,203,1,5000,0,2000,no,randomtarget,always,0,,,,,,,
|
||||
1511,Amon Ra@NPC_DARKBLESSING,attack,203,1,5000,0,2000,no,target,always,0,,,,,,,
|
||||
1511,Amon Ra@WZ_METEOR,idle,83,11,10000,0,5000,yes,randomtarget,always,0,,,,,,9,
|
||||
1511,Amon Ra@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
|
||||
1511,Amon Ra@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
|
||||
@@ -3398,18 +3398,18 @@
|
||||
1663,Laurell Weinder@NPC_EMOTION,idle,197,1,10000,0,5000,yes,self,skillused,28,15,,,,,,
|
||||
1663,Laurell Weinder@NPC_EMOTION,attack,197,1,10000,0,5000,yes,self,skillused,28,15,,,,,,
|
||||
1663,Laurell Weinder@NPC_EMOTION,chase,197,1,10000,0,5000,yes,self,skillused,28,15,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,5,1000,1000,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,3,2000,500,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,5,1000,1000,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,3,2000,500,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,5,1000,1000,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,3,2000,500,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,5,1000,1000,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,3,2000,500,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,5,1000,1000,10000,yes,target,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,3,2000,500,5000,yes,target,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,5,1000,1000,10000,yes,target,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,3,2000,500,5000,yes,target,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,5,1000,1000,10000,yes,target,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,3,2000,500,5000,yes,target,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,5,1000,1000,10000,yes,target,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,3,2000,500,5000,yes,target,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1668,Archdam@NPC_PIERCINGATT,attack,158,5,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1668,Archdam@NPC_GUIDEDATTACK,attack,172,2,500,1000,20000,no,target,always,0,,,,,,29,
|
||||
1668,Archdam@KN_SPEARSTAB,attack,58,5,500,800,5000,no,target,always,0,,,,,,,
|
||||
@@ -3446,9 +3446,9 @@
|
||||
1673,Dimik@NPC_COMBOATTACK,attack,171,4,500,700,5000,no,target,always,0,,,,,,,
|
||||
1673,Dimik@NPC_COMBOATTACK,chase,171,4,500,700,5000,no,target,always,0,,,,,,,
|
||||
1673,Dimik@NPC_FIREATTACK,attack,186,3,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,10,500,1000,30000,yes,randomtarget,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,3,1000,0,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,10,500,1000,30000,yes,target,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,3,1000,0,10000,yes,target,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1675,Venatu@NPC_SILENCEATTACK,attack,178,3,500,700,5000,no,target,always,0,,,,,,,
|
||||
1675,Venatu@NPC_GUIDEDATTACK,attack,172,3,500,1000,20000,no,target,always,0,,,,,,6,
|
||||
1675,Venatu@NPC_STUNATTACK,attack,179,2,500,1500,5000,no,target,always,0,,,,,,11,
|
||||
@@ -3524,11 +3524,11 @@
|
||||
1688,Lady Tany@AL_TELEPORT,idle,26,1,1000,0,30000,yes,self,always,0,,,,,,,
|
||||
1688,Lady Tany@AL_TELEPORT,attack,26,1,1000,0,30000,yes,self,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_EXPULSION,attack,674,1,1000,1000,10000,no,target,myhpltmaxrate,60,,,,,,,
|
||||
1688,Lady Tany@AC_CHARGEARROW,attack,148,1,2000,0,5000,yes,randomtarget,always,0,,,,,,6,
|
||||
1688,Lady Tany@NPC_COMBOATTACK,attack,171,1,1000,0,5000,no,randomtarget,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,randomtarget,always,0,,,,,,6,
|
||||
1688,Lady Tany@NPC_GUIDEDATTACK,attack,172,5,500,0,20000,no,randomtarget,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_STUNATTACK,attack,179,5,500,0,5000,no,randomtarget,always,0,,,,,,,
|
||||
1688,Lady Tany@AC_CHARGEARROW,attack,148,1,2000,0,5000,yes,target,always,0,,,,,,6,
|
||||
1688,Lady Tany@NPC_COMBOATTACK,attack,171,1,1000,0,5000,no,target,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1688,Lady Tany@NPC_GUIDEDATTACK,attack,172,5,500,0,20000,no,target,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_STUNATTACK,attack,179,5,500,0,5000,no,target,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_DEFENDER,attack,205,1,500,0,30000,yes,self,longrangeattacked,,,,,,,29,
|
||||
1688,Lady Tany@NPC_POWERUP,attack,349,5,10000,0,30000,yes,self,myhpltmaxrate,30,,,,,,6,
|
||||
1688,Lady Tany@NPC_SUMMONSLAVE,attack,196,5,10000,2000,5000,no,self,slavele,2,1691,,,,,,
|
||||
@@ -4220,18 +4220,18 @@
|
||||
1779,Ktullanux@NPC_AGIUP,attack,350,5,2000,0,100000,yes,self,always,0,,,,,,,
|
||||
1779,Ktullanux@NPC_AGIUP,attack,350,5,10000,0,25000,yes,self,myhpltmaxrate,30,,,,,,,
|
||||
1779,Ktullanux@AL_HEAL,idle,28,11,10000,0,10000,yes,self,myhpltmaxrate,50,,,,,,,
|
||||
1780,Muscipular@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1780,Muscipular@KN_SPEARSTAB,attack,58,5,500,800,5000,no,randomtarget,always,0,,,,,,6,
|
||||
1780,Muscipular@NPC_GROUNDATTACK,attack,185,1,1000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1780,Muscipular@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1780,Muscipular@KN_SPEARSTAB,attack,58,5,500,800,5000,no,target,always,0,,,,,,6,
|
||||
1780,Muscipular@NPC_GROUNDATTACK,attack,185,1,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1780,Muscipular@AL_HEAL,attack,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,50,,,,,,,
|
||||
1780,Muscipular@AL_HEAL,idle,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,50,,,,,,,
|
||||
1780,Muscipular@NPC_PETRIFYATTACK,attack,180,5,500,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1781,Drosera@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1781,Drosera@KN_PIERCE,attack,56,5,500,700,5000,no,randomtarget,always,0,,,,,,,
|
||||
1781,Drosera@NPC_GROUNDATTACK,attack,185,1,1000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1780,Muscipular@NPC_PETRIFYATTACK,attack,180,5,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1781,Drosera@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1781,Drosera@KN_PIERCE,attack,56,5,500,700,5000,no,target,always,0,,,,,,,
|
||||
1781,Drosera@NPC_GROUNDATTACK,attack,185,1,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1781,Drosera@RG_CLOSECONFINE,attack,1005,1,1000,0,30000,yes,target,always,0,,,,,,,
|
||||
1781,Drosera@NPC_GUIDEDATTACK,attack,172,3,500,1000,20000,no,randomtarget,always,0,,,,,,6,
|
||||
1781,Drosera@NPC_SLEEPATTACK,attack,182,5,500,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1781,Drosera@NPC_GUIDEDATTACK,attack,172,3,500,1000,20000,no,target,always,0,,,,,,6,
|
||||
1781,Drosera@NPC_SLEEPATTACK,attack,182,5,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1782,Roween@NPC_WINDATTACK,attack,187,2,500,500,5000,no,target,always,0,,,,,,,
|
||||
1782,Roween@NPC_COMBOATTACK,attack,171,4,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1782,Roween@NPC_EMOTION,idle,197,1,2000,0,5000,yes,self,always,0,22,0x308D,,,,,
|
||||
|
||||
49
db/pre-re/produce_db.yml
Normal file
49
db/pre-re/produce_db.yml
Normal file
@@ -0,0 +1,49 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2023 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 Produce Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Produce Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - ItemLevel Number which determines what kind of a crafting window will pop-up.
|
||||
# Recipe:
|
||||
# - Product AegisName of the produced item.
|
||||
# SkillName Skill name required. (Default: null)
|
||||
# SkillLevel Skill level required. (Default: 1)
|
||||
# Consumed: List of items consumed to produce the Product.
|
||||
# - Item AegisName of the consumed item.
|
||||
# Amount Amount required.
|
||||
# Clear Remove the item with the given AegisName from Consumed. (Optional)
|
||||
# NotConsumed: List of items not consumed to produce the Product. (Default: null)
|
||||
# - Item AegisName of the unconsumed item.
|
||||
# Clear Remove the item with the given AegisName from NotConsumed. (Optional)
|
||||
# BaseRate Base rate (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000)
|
||||
# Make: List of item amounts with their individual rate produced by Change Material (ItemLevel: 26). (Default: null)
|
||||
# - Amount Amount of item created (unique to the list) for Change Material (ItemLevel: 26).
|
||||
# Rate Rate to create the Amount (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000. 0 to remove on import)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: PRODUCE_DB
|
||||
Version: 1
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
- Path: db/pre-re/skill_produce_db.yml
|
||||
@@ -4153,7 +4153,6 @@ Body:
|
||||
Time: 120000
|
||||
- Level: 5
|
||||
Time: 60000
|
||||
Duration2: 3000
|
||||
Requires:
|
||||
SpCost: 10
|
||||
ItemCost:
|
||||
@@ -4408,6 +4407,7 @@ Body:
|
||||
TargetType: Ground
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
IgnoreAtkCard: true
|
||||
Flags:
|
||||
IsTrap: true
|
||||
AlterRangeResearchTrap: true
|
||||
@@ -5184,6 +5184,8 @@ Body:
|
||||
MaxLevel: 1
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
IgnoreAtkCard: true
|
||||
Flags:
|
||||
IsQuest: true
|
||||
Range: 1
|
||||
@@ -6885,12 +6887,9 @@ Body:
|
||||
MaxLevel: 10
|
||||
Type: Magic
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
IgnoreAtkCard: true
|
||||
IgnoreFlee: true
|
||||
Flags:
|
||||
TargetSelf: true
|
||||
Range: 5
|
||||
Range: 9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Holy
|
||||
@@ -9999,15 +9998,15 @@ Body:
|
||||
Element: Weapon
|
||||
Duration1:
|
||||
- Level: 1
|
||||
Time: 4000
|
||||
Time: 2000
|
||||
- Level: 2
|
||||
Time: 8000
|
||||
Time: 4000
|
||||
- Level: 3
|
||||
Time: 12000
|
||||
Time: 6000
|
||||
- Level: 4
|
||||
Time: 16000
|
||||
Time: 8000
|
||||
- Level: 5
|
||||
Time: 24000
|
||||
Time: 10000
|
||||
CastDelayFlags:
|
||||
IgnoreStatus: true
|
||||
Requires:
|
||||
@@ -10023,7 +10022,7 @@ Body:
|
||||
- Level: 5
|
||||
Amount: 12
|
||||
SpiritSphereCost: 1
|
||||
Status: Stop
|
||||
Status: Ankle
|
||||
- Id: 372
|
||||
Name: CH_CHAINCRUSH
|
||||
Description: Chain Crush Combo
|
||||
@@ -10802,7 +10801,7 @@ Body:
|
||||
IgnoreDefense: true
|
||||
Flags:
|
||||
TargetTrap: true
|
||||
Range: 5
|
||||
Range: 4
|
||||
Hit: Multi_Hit
|
||||
HitCount: 5
|
||||
Element: Weapon
|
||||
@@ -10844,7 +10843,7 @@ Body:
|
||||
Weapon:
|
||||
1hSpear: true
|
||||
2hSpear: true
|
||||
Status: Stop
|
||||
Status: Ankle
|
||||
- Id: 398
|
||||
Name: LK_HEADCRUSH
|
||||
Description: Traumatic Blow
|
||||
@@ -11063,7 +11062,7 @@ Body:
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
NoDamage: true
|
||||
Range: 7
|
||||
Range: 9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
ActiveInstance: 3
|
||||
@@ -14295,6 +14294,7 @@ Body:
|
||||
TargetType: Ground
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
IgnoreAtkCard: true
|
||||
IgnoreFlee: true
|
||||
Flags:
|
||||
AlterRangeSnakeEye: true
|
||||
@@ -14380,7 +14380,7 @@ Body:
|
||||
Type: Weapon
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
IgnoreFlee: true
|
||||
IgnoreAtkCard: true
|
||||
Range: 9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
@@ -14398,7 +14398,6 @@ Body:
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
IgnoreAtkCard: true
|
||||
IgnoreFlee: true
|
||||
Range: 9
|
||||
Hit: Multi_Hit
|
||||
HitCount: 3
|
||||
@@ -14474,7 +14473,7 @@ Body:
|
||||
Flags:
|
||||
IgnoreBgReduction: true
|
||||
IgnoreGvgReduction: true
|
||||
Range: 9
|
||||
Range: 7
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
CopyFlags:
|
||||
@@ -14511,6 +14510,8 @@ Body:
|
||||
MaxLevel: 5
|
||||
Type: Weapon
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
IgnoreAtkCard: true
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Weapon
|
||||
@@ -16331,7 +16332,7 @@ Body:
|
||||
Flags:
|
||||
IsNpc: true
|
||||
HitCount: 1
|
||||
Duration1: -1
|
||||
Duration1: 300000
|
||||
Status: Invincible
|
||||
- Id: 686
|
||||
Name: NPC_INVINCIBLEOFF
|
||||
@@ -16343,8 +16344,6 @@ Body:
|
||||
Flags:
|
||||
IsNpc: true
|
||||
HitCount: 1
|
||||
Duration1: 60000
|
||||
Status: InvincibleOff
|
||||
- Id: 687
|
||||
Name: NPC_ALLHEAL
|
||||
Description: Full Heal
|
||||
@@ -17181,6 +17180,7 @@ Body:
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
IgnoreAtkCard: true
|
||||
Flags:
|
||||
IsQuest: true
|
||||
Range: -1
|
||||
@@ -32585,6 +32585,7 @@ Body:
|
||||
TargetType: Ground
|
||||
DamageFlags:
|
||||
Splash: true
|
||||
IgnoreAtkCard: true
|
||||
Flags:
|
||||
IsTrap: true
|
||||
AlterRangeResearchTrap: true
|
||||
@@ -32751,7 +32752,7 @@ Body:
|
||||
IgnoreDefense: true
|
||||
Flags:
|
||||
TargetTrap: true
|
||||
Range: 5
|
||||
Range: 4
|
||||
Hit: Multi_Hit
|
||||
HitCount: 5
|
||||
Element: Weapon
|
||||
@@ -32794,7 +32795,7 @@ Body:
|
||||
Amount: 27
|
||||
- Level: 5
|
||||
Amount: 30
|
||||
Status: Stop
|
||||
Status: Ankle
|
||||
- Id: 8219
|
||||
Name: ML_DEFENDER
|
||||
Description: Defending_Aura
|
||||
|
||||
3005
db/pre-re/skill_produce_db.yml
Normal file
3005
db/pre-re/skill_produce_db.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -769,7 +769,6 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnChangeMap: true
|
||||
MinDuration: 5000
|
||||
- Status: Keeping
|
||||
DurationLookup: NPC_KEEPING
|
||||
CalcFlags:
|
||||
@@ -2824,23 +2823,12 @@ Body:
|
||||
Icon: EFST_INVINCIBLE
|
||||
DurationLookup: NPC_INVINCIBLE
|
||||
CalcFlags:
|
||||
Aspd: true
|
||||
Speed: true
|
||||
Flags:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
EndOnStart:
|
||||
Invincibleoff: true
|
||||
- Status: Invincibleoff
|
||||
DurationLookup: NPC_INVINCIBLEOFF
|
||||
CalcFlags:
|
||||
Speed: true
|
||||
Flags:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
EndOnStart:
|
||||
Invincible: true
|
||||
- Status: Manu_Atk
|
||||
Icon: EFST_MANU_ATK
|
||||
Flags:
|
||||
|
||||
53
db/produce_db.yml
Normal file
53
db/produce_db.yml
Normal file
@@ -0,0 +1,53 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2023 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 Produce Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Produce Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - ItemLevel Number which determines what kind of a crafting window will pop-up.
|
||||
# Recipe:
|
||||
# - Product AegisName of the produced item.
|
||||
# SkillName Skill name required. (Default: null)
|
||||
# SkillLevel Skill level required. (Default: 1)
|
||||
# Consumed: List of items consumed to produce the Product.
|
||||
# - Item AegisName of the consumed item.
|
||||
# Amount Amount required.
|
||||
# Clear Remove the item with the given AegisName from Consumed. (Optional)
|
||||
# NotConsumed: List of items not consumed to produce the Product. (Default: null)
|
||||
# - Item AegisName of the unconsumed item.
|
||||
# Clear Remove the item with the given AegisName from NotConsumed. (Optional)
|
||||
# BaseRate Base rate (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000)
|
||||
# Make: List of item amounts with their individual rate produced by Change Material (ItemLevel: 26). (Default: null)
|
||||
# - Amount Amount of item created (unique to the list) for Change Material (ItemLevel: 26).
|
||||
# Rate Rate to create the Amount (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000. 0 to remove on import)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: PRODUCE_DB
|
||||
Version: 1
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
- Path: db/pre-re/produce_db.yml
|
||||
Mode: Prerenewal
|
||||
- Path: db/re/produce_db.yml
|
||||
Mode: Renewal
|
||||
- Path: db/import/produce_db.yml
|
||||
@@ -948,7 +948,7 @@ Body:
|
||||
Refineable: true
|
||||
Script: |
|
||||
bonus2 bAddEff,Eff_Curse,30;
|
||||
bonus2 bComaClass,Class_All,10;
|
||||
bonus2 bComaClass,Class_Normal,10;
|
||||
- Id: 1133
|
||||
AegisName: Fire_Brand
|
||||
Name: Fireblend
|
||||
@@ -185843,13 +185843,10 @@ Body:
|
||||
Script: |
|
||||
.@r = getrefine();
|
||||
.@val = getskilllv("GN_CARTBOOST");
|
||||
.@a = (.@r>= 7 ? 20 : (.@r>= 5 ? 10 : 3));
|
||||
.@b = (.@r>= 7 ? 100 : (.@r>= 5 ? 50 : 0));
|
||||
bonus bUnbreakableShoes;
|
||||
bonus bMdef,10;
|
||||
bonus bMaxHPrate,.@a;
|
||||
bonus bMaxSPrate,.@a;
|
||||
bonus2 bVariableCastrate,"GN_CARTCANNON",-.@b;
|
||||
bonus bMaxHPrate,3;
|
||||
bonus bMaxSPrate,3;
|
||||
bonus bHit,20*.@val;
|
||||
bonus bAspdRate,4*.@val;
|
||||
bonus bAtkRate,4*getskilllv("GN_FIRE_EXPANSION");
|
||||
@@ -185861,14 +185858,12 @@ Body:
|
||||
bonus bMaxSPrate,7;
|
||||
bonus2 bVariableCastrate,"GN_CARTCANNON",-50;
|
||||
bonus2 bSkillAtk,"GN_CARTCANNON",BaseLevel/2;
|
||||
bonus bAllStats,BaseLevel/2;
|
||||
}
|
||||
if (.@r>=7) {
|
||||
bonus bMaxHPrate,10;
|
||||
bonus bMaxSPrate,10;
|
||||
bonus2 bVariableCastrate,"GN_CARTCANNON",-50;
|
||||
bonus2 bSkillAtk,"GN_CARTCANNON",BaseLevel/2;
|
||||
bonus bAllStats,BaseLevel/2;
|
||||
}
|
||||
- Id: 470062
|
||||
AegisName: Lethargy_P_Shoes
|
||||
|
||||
@@ -56781,7 +56781,8 @@ Body:
|
||||
NoMail: true
|
||||
NoAuction: true
|
||||
Script: |
|
||||
itemskill "RK_LUXANIMA",1;
|
||||
if ((eaclass()&EAJ_THIRDMASK) == EAJ_RUNE_KNIGHT)
|
||||
itemskill "RK_LUXANIMA",1;
|
||||
- Id: 22541
|
||||
AegisName: PCBang_Coupon_Box6
|
||||
Name: PC Room Coupon Box VI
|
||||
|
||||
@@ -78188,7 +78188,7 @@ Body:
|
||||
AttackDelay: 1020
|
||||
AttackMotion: 500
|
||||
DamageMotion: 768
|
||||
Ai: 10
|
||||
Ai: 21
|
||||
Class: Boss
|
||||
Drops:
|
||||
- Item: Brinaranea_Card
|
||||
@@ -78220,7 +78220,7 @@ Body:
|
||||
AttackDelay: 608
|
||||
AttackMotion: 408
|
||||
DamageMotion: 336
|
||||
Ai: 10
|
||||
Ai: 21
|
||||
Class: Boss
|
||||
Drops:
|
||||
- Item: Muspellskoll_Card
|
||||
@@ -78362,7 +78362,7 @@ Body:
|
||||
AttackDelay: 750
|
||||
AttackMotion: 510
|
||||
DamageMotion: 500
|
||||
Ai: 10
|
||||
Ai: 21
|
||||
Class: Boss
|
||||
Drops:
|
||||
- Item: M_Morocc_Card
|
||||
|
||||
@@ -102,7 +102,7 @@
|
||||
1019,Peco Peco@NPC_EMOTION,chase,197,1,2000,0,5000,yes,self,always,0,6,,,,,,
|
||||
1019,Peco Peco@NPC_FIREATTACK,attack,186,1,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
1019,Peco Peco@NPC_PROVOCATION,chase,194,1,200,0,5000,yes,target,always,0,,,,,,19,
|
||||
1020,Mandragora@NPC_GROUNDATTACK,attack,185,1,2000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1020,Mandragora@NPC_GROUNDATTACK,attack,185,1,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
1023,Orc Warrior@NPC_EMOTION,chase,197,1,2000,0,5000,yes,self,always,0,,,,,,,
|
||||
1023,Orc Warrior@NPC_GROUNDATTACK,attack,185,2,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1023,Orc Warrior@NPC_EMOTION,chase,197,1,200,0,5000,yes,self,always,0,19,0x81,,,,,
|
||||
@@ -351,7 +351,7 @@
|
||||
1067,Cornutus@NPC_WATERATTACK,attack,184,2,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1067,Cornutus@CR_AUTOGUARD,attack,249,2,500,0,300000,yes,self,always,0,,,,,,,
|
||||
1067,Cornutus@CR_AUTOGUARD,chase,249,2,2000,0,300000,yes,self,longrangeattacked,,,,,,,,
|
||||
1068,Hydra@NPC_WATERATTACK,attack,184,2,500,500,5000,no,randomtarget,always,0,,,,,,,
|
||||
1068,Hydra@NPC_WATERATTACK,attack,184,2,500,500,5000,no,target,always,0,,,,,,,
|
||||
1069,Swordfish@NPC_WATERATTACK,attack,184,1,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
1069,Swordfish@WZ_WATERBALL,attack,86,3,500,1500,5000,yes,target,always,0,,,,,,,
|
||||
1069,Swordfish@WZ_WATERBALL,chase,86,3,500,1500,5000,yes,target,always,0,,,,,,,
|
||||
@@ -603,9 +603,9 @@
|
||||
1117,Evil Druid@NPC_UNDEADATTACK,chase,347,3,500,500,5000,no,target,always,0,,,,,,9,
|
||||
1117,Evil Druid@WZ_HEAVENDRIVE,attack,91,5,500,1200,5000,yes,target,always,0,,,,,,,
|
||||
1117,Evil Druid@WZ_HEAVENDRIVE,chase,91,5,500,1200,5000,yes,target,always,0,,,,,,,
|
||||
1118,Flora@NPC_BLOODDRAIN,attack,199,1,500,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1118,Flora@NPC_BLOODDRAIN,attack,199,1,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1118,Flora@NPC_EMOTION,idle,197,1,2000,0,5000,yes,self,always,0,2,,,,,,
|
||||
1118,Flora@NPC_GROUNDATTACK,attack,185,1,2000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1118,Flora@NPC_GROUNDATTACK,attack,185,1,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
1119,Frilldora@AS_CLOAKING,attack,135,1,2000,200,5000,yes,self,always,0,,,,,,,
|
||||
1119,Frilldora@AS_CLOAKING,idle,135,1,2000,200,5000,yes,self,always,0,,,,,,,
|
||||
1119,Frilldora@AS_CLOAKING,chase,135,1,2000,200,5000,yes,self,always,0,,,,,,,
|
||||
@@ -1301,7 +1301,7 @@
|
||||
1276,Raydric Archer@CR_AUTOGUARD,attack,249,2,500,0,300000,yes,self,always,0,,,,,,,
|
||||
1277,Greatest General@NPC_BLINDATTACK,idle,177,3,10000,1500,5000,no,randomtarget,longrangeattacked,,,,,,,6,
|
||||
1277,Greatest General@NPC_BLINDATTACK,idle,177,3,10000,1500,5000,no,randomtarget,casttargeted,,,,,,,6,
|
||||
1277,Greatest General@NPC_FIREATTACK,attack,186,2,500,500,5000,no,randomtarget,always,0,,,,,,,
|
||||
1277,Greatest General@NPC_FIREATTACK,attack,186,2,500,500,5000,no,target,always,0,,,,,,,
|
||||
1277,Greatest General@WZ_EARTHSPIKE,idle,90,3,5000,1500,5000,no,randomtarget,longrangeattacked,,,,,,,6,
|
||||
1277,Greatest General@WZ_EARTHSPIKE,idle,90,3,5000,1500,5000,no,randomtarget,casttargeted,,,,,,,6,
|
||||
1278,Stalactite Golem@NPC_STUNATTACK,attack,179,4,500,1500,5000,no,target,always,0,,,,,,6,
|
||||
@@ -1584,7 +1584,7 @@
|
||||
1367,Blazer@WZ_SIGHTRASHER,attack,81,5,500,1000,5000,no,target,always,0,,,,,,6,
|
||||
1368,Geographer@AL_HEAL,attack,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,60,,,,,,,
|
||||
1368,Geographer@AL_HEAL,idle,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,60,,,,,,,
|
||||
1368,Geographer@NPC_SLEEPATTACK,attack,182,5,500,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1368,Geographer@NPC_SLEEPATTACK,attack,182,5,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1369,Grand Peco@AS_SONICBLOW,attack,136,5,500,800,5000,no,target,always,0,,,,,,6,
|
||||
1369,Grand Peco@NPC_FIREATTACK,attack,186,3,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1369,Grand Peco@NPC_EMOTION,chase,197,1,200,0,5000,yes,self,always,0,19,0x81,,,,,
|
||||
@@ -2569,8 +2569,8 @@
|
||||
1510,Hylozoist@MO_BODYRELOCATION,chase,264,1,2000,500,5000,no,target,always,0,,,,,,,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,idle,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,idle,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,target,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,target,always,0,,,,,,29,
|
||||
1511,Amon Ra@NPC_SUMMONMONSTER,idle,209,5,5000,0,10000,no,self,longrangeattacked,0,1474,1477,1438,,,9,
|
||||
1511,Amon Ra@NPC_SUMMONMONSTER,idle,209,5,5000,0,10000,no,self,casttargeted,0,1474,1477,1438,,,9,
|
||||
1511,Amon Ra@NPC_SUMMONMONSTER,attack,209,5,5000,0,10000,no,self,longrangeattacked,0,1474,1477,1438,,,9,
|
||||
@@ -2589,11 +2589,11 @@
|
||||
1511,Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,skillused,83,,,,,,9,
|
||||
1511,Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,longrangeattacked,,,,,,,9,
|
||||
1511,Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,casttargeted,,,,,,,9,
|
||||
1511,Amon Ra@WZ_METEOR,attack,83,11,5000,0,3000,yes,randomtarget,always,0,,,,,,9,
|
||||
1511,Amon Ra@WZ_METEOR,attack,83,11,5000,0,3000,yes,target,always,0,,,,,,9,
|
||||
1511,Amon Ra@WZ_FIREPILLAR,idle,80,10,10000,0,2000,yes,around2,always,0,,,,,,,
|
||||
1511,Amon Ra@WZ_FIREPILLAR,idle,80,10,10000,0,2000,yes,around2,always,0,,,,,,,
|
||||
1511,Amon Ra@WZ_FIREPILLAR,attack,80,10,5000,0,2000,yes,around2,always,0,,,,,,,
|
||||
1511,Amon Ra@NPC_DARKBLESSING,attack,203,1,5000,0,2000,no,randomtarget,always,0,,,,,,,
|
||||
1511,Amon Ra@NPC_DARKBLESSING,attack,203,1,5000,0,2000,no,target,always,0,,,,,,,
|
||||
1511,Amon Ra@WZ_METEOR,idle,83,11,10000,0,5000,yes,randomtarget,always,0,,,,,,9,
|
||||
1511,Amon Ra@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
|
||||
1511,Amon Ra@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
|
||||
@@ -3405,18 +3405,18 @@
|
||||
1663,Laurell Weinder@NPC_EMOTION,idle,197,1,10000,0,5000,yes,self,skillused,28,15,,,,,,
|
||||
1663,Laurell Weinder@NPC_EMOTION,attack,197,1,10000,0,5000,yes,self,skillused,28,15,,,,,,
|
||||
1663,Laurell Weinder@NPC_EMOTION,chase,197,1,10000,0,5000,yes,self,skillused,28,15,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,5,1000,1000,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,3,2000,500,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,5,1000,1000,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,3,2000,500,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,5,1000,1000,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,3,2000,500,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,5,1000,1000,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,3,2000,500,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,5,1000,1000,10000,yes,target,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,3,2000,500,5000,yes,target,always,0,,,,,,,
|
||||
1664,Photon Cannon@NPC_WINDATTACK,attack,187,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,5,1000,1000,10000,yes,target,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,3,2000,500,5000,yes,target,always,0,,,,,,,
|
||||
1665,Photon Cannon@NPC_FIREATTACK,attack,186,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,5,1000,1000,10000,yes,target,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,3,2000,500,5000,yes,target,always,0,,,,,,,
|
||||
1666,Photon Cannon@NPC_WATERATTACK,attack,184,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,5,1000,1000,10000,yes,target,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,3,2000,500,5000,yes,target,always,0,,,,,,,
|
||||
1667,Photon Cannon@NPC_GROUNDATTACK,attack,185,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1668,Archdam@NPC_PIERCINGATT,attack,158,5,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1668,Archdam@NPC_GUIDEDATTACK,attack,172,2,500,1000,20000,no,target,always,0,,,,,,29,
|
||||
1668,Archdam@KN_SPEARSTAB,attack,58,5,500,800,5000,no,target,always,0,,,,,,,
|
||||
@@ -3453,9 +3453,9 @@
|
||||
1673,Dimik@NPC_COMBOATTACK,attack,171,4,500,700,5000,no,target,always,0,,,,,,,
|
||||
1673,Dimik@NPC_COMBOATTACK,chase,171,4,500,700,5000,no,target,always,0,,,,,,,
|
||||
1673,Dimik@NPC_FIREATTACK,attack,186,3,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,10,500,1000,30000,yes,randomtarget,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,3,1000,0,10000,yes,randomtarget,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,1,10000,0,0,yes,randomtarget,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,10,500,1000,30000,yes,target,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,3,1000,0,10000,yes,target,always,0,,,,,,,
|
||||
1674,Monemus@NPC_FIREATTACK,attack,186,1,10000,0,0,yes,target,always,0,,,,,,,
|
||||
1675,Venatu@NPC_SILENCEATTACK,attack,178,3,500,700,5000,no,target,always,0,,,,,,,
|
||||
1675,Venatu@NPC_GUIDEDATTACK,attack,172,3,500,1000,20000,no,target,always,0,,,,,,6,
|
||||
1675,Venatu@NPC_STUNATTACK,attack,179,2,500,1500,5000,no,target,always,0,,,,,,11,
|
||||
@@ -3531,11 +3531,11 @@
|
||||
1688,Lady Tany@AL_TELEPORT,idle,26,1,1000,0,30000,yes,self,always,0,,,,,,,
|
||||
1688,Lady Tany@AL_TELEPORT,attack,26,1,1000,0,30000,yes,self,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_EXPULSION,attack,674,1,1000,1000,10000,no,target,myhpltmaxrate,60,,,,,,,
|
||||
1688,Lady Tany@AC_CHARGEARROW,attack,148,1,2000,0,5000,yes,randomtarget,always,0,,,,,,6,
|
||||
1688,Lady Tany@NPC_COMBOATTACK,attack,171,1,1000,0,5000,no,randomtarget,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,randomtarget,always,0,,,,,,6,
|
||||
1688,Lady Tany@NPC_GUIDEDATTACK,attack,172,5,500,0,20000,no,randomtarget,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_STUNATTACK,attack,179,5,500,0,5000,no,randomtarget,always,0,,,,,,,
|
||||
1688,Lady Tany@AC_CHARGEARROW,attack,148,1,2000,0,5000,yes,target,always,0,,,,,,6,
|
||||
1688,Lady Tany@NPC_COMBOATTACK,attack,171,1,1000,0,5000,no,target,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1688,Lady Tany@NPC_GUIDEDATTACK,attack,172,5,500,0,20000,no,target,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_STUNATTACK,attack,179,5,500,0,5000,no,target,always,0,,,,,,,
|
||||
1688,Lady Tany@NPC_DEFENDER,attack,205,1,500,0,30000,yes,self,longrangeattacked,,,,,,,29,
|
||||
1688,Lady Tany@NPC_POWERUP,attack,349,5,10000,0,30000,yes,self,myhpltmaxrate,30,,,,,,6,
|
||||
1688,Lady Tany@NPC_SUMMONSLAVE,attack,196,5,10000,2000,5000,no,self,slavele,2,1691,,,,,,
|
||||
@@ -4228,18 +4228,18 @@
|
||||
1779,Ktullanux@NPC_AGIUP,attack,350,5,2000,0,100000,yes,self,always,0,,,,,,,
|
||||
1779,Ktullanux@NPC_AGIUP,attack,350,5,10000,0,25000,yes,self,myhpltmaxrate,30,,,,,,,
|
||||
1779,Ktullanux@AL_HEAL,idle,28,11,10000,0,10000,yes,self,myhpltmaxrate,50,,,,,,,
|
||||
1780,Muscipular@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1780,Muscipular@KN_SPEARSTAB,attack,58,5,500,800,5000,no,randomtarget,always,0,,,,,,6,
|
||||
1780,Muscipular@NPC_GROUNDATTACK,attack,185,1,1000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1780,Muscipular@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1780,Muscipular@KN_SPEARSTAB,attack,58,5,500,800,5000,no,target,always,0,,,,,,6,
|
||||
1780,Muscipular@NPC_GROUNDATTACK,attack,185,1,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1780,Muscipular@AL_HEAL,attack,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,50,,,,,,,
|
||||
1780,Muscipular@AL_HEAL,idle,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,50,,,,,,,
|
||||
1780,Muscipular@NPC_PETRIFYATTACK,attack,180,5,500,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1781,Drosera@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1781,Drosera@KN_PIERCE,attack,56,5,500,700,5000,no,randomtarget,always,0,,,,,,,
|
||||
1781,Drosera@NPC_GROUNDATTACK,attack,185,1,1000,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1780,Muscipular@NPC_PETRIFYATTACK,attack,180,5,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1781,Drosera@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1781,Drosera@KN_PIERCE,attack,56,5,500,700,5000,no,target,always,0,,,,,,,
|
||||
1781,Drosera@NPC_GROUNDATTACK,attack,185,1,1000,0,5000,yes,target,always,0,,,,,,,
|
||||
1781,Drosera@RG_CLOSECONFINE,attack,1005,1,1000,0,30000,yes,target,always,0,,,,,,,
|
||||
1781,Drosera@NPC_GUIDEDATTACK,attack,172,3,500,1000,20000,no,randomtarget,always,0,,,,,,6,
|
||||
1781,Drosera@NPC_SLEEPATTACK,attack,182,5,500,0,5000,yes,randomtarget,always,0,,,,,,,
|
||||
1781,Drosera@NPC_GUIDEDATTACK,attack,172,3,500,1000,20000,no,target,always,0,,,,,,6,
|
||||
1781,Drosera@NPC_SLEEPATTACK,attack,182,5,500,0,5000,yes,target,always,0,,,,,,,
|
||||
1782,Roween@NPC_WINDATTACK,attack,187,2,500,500,5000,no,target,always,0,,,,,,,
|
||||
1782,Roween@NPC_COMBOATTACK,attack,171,4,500,500,5000,no,target,always,0,,,,,,6,
|
||||
1782,Roween@NPC_EMOTION,idle,197,1,2000,0,5000,yes,self,always,0,22,0x308D,,,,,
|
||||
@@ -7980,8 +7980,8 @@
|
||||
2311,Manananggal@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
|
||||
2311,Manananggal@AL_TELEPORT,idle,26,1,1000,0,30000,yes,self,always,0,,,,,,,
|
||||
2311,Manananggal@AL_TELEPORT,attack,26,1,100,0,30000,yes,self,always,0,,,,,,,
|
||||
2311,Manananggal@NPC_BLOODDRAIN,chase,199,1,2000,0,5000,yes,randomtarget,myhpltmaxrate,50,,,,,,3,
|
||||
2311,Manananggal@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,randomtarget,myhpltmaxrate,50,,,,,,3,
|
||||
2311,Manananggal@NPC_BLOODDRAIN,chase,199,1,2000,0,5000,yes,target,myhpltmaxrate,50,,,,,,3,
|
||||
2311,Manananggal@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,target,myhpltmaxrate,50,,,,,,3,
|
||||
2311,Manananggal@NPC_COMBOATTACK,chase,171,5,1000,0,5000,yes,target,always,0,,,,,,7,
|
||||
2311,Manananggal@NPC_COMBOATTACK,attack,171,5,1000,0,5000,yes,target,always,0,,,,,,7,
|
||||
2312,Mangkukulam@AL_TELEPORT,idle,26,1,500,0,30000,yes,self,always,0,,,,,,,
|
||||
@@ -8009,8 +8009,8 @@
|
||||
2315,Wakwak@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
|
||||
2315,Wakwak@AL_TELEPORT,idle,26,1,500,0,30000,yes,self,always,0,,,,,,,
|
||||
2315,Wakwak@AL_TELEPORT,attack,26,1,50,0,30000,yes,self,always,0,,,,,,,
|
||||
2315,Wakwak@NPC_BLOODDRAIN,chase,199,1,2000,0,5000,yes,randomtarget,myhpltmaxrate,50,,,,,,3,
|
||||
2315,Wakwak@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,randomtarget,myhpltmaxrate,50,,,,,,3,
|
||||
2315,Wakwak@NPC_BLOODDRAIN,chase,199,1,2000,0,5000,yes,target,myhpltmaxrate,50,,,,,,3,
|
||||
2315,Wakwak@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,target,myhpltmaxrate,50,,,,,,3,
|
||||
2315,Wakwak@NPC_DARKTHUNDER,chase,341,3,1000,500,5000,yes,target,always,0,,,,,,29,
|
||||
2315,Wakwak@NPC_DARKTHUNDER,attack,341,3,1000,500,5000,yes,target,always,0,,,,,,29,
|
||||
2315,Wakwak@NPC_CURSEATTACK,attack,181,3,500,800,5000,no,target,always,0,,,,,,0,
|
||||
@@ -8113,7 +8113,7 @@
|
||||
2331,Seaweed@AL_HEAL,idle,28,9,10000,500,5000,yes,friend,friendhpltmaxrate,100,,,,,,2,
|
||||
2337,Hidden Mob@NPC_INVISIBLE,idle,353,1,10000,0,30000,yes,self,always,0,,,,,,,
|
||||
2337,Hidden Mob@NPC_INVISIBLE,attack,353,1,10000,0,30000,yes,self,always,0,,,,,,,
|
||||
2337,Hidden Mob@WZ_METEOR,attack,83,5,10000,0,1000,yes,randomtarget,always,0,,,,,,,
|
||||
2337,Hidden Mob@WZ_METEOR,attack,83,5,10000,0,1000,yes,target,always,0,,,,,,,
|
||||
2338,Bangungot Manananggal@AL_TELEPORT,idle,26,1,500,0,5000,yes,self,always,0,,,,,,,
|
||||
2338,Bangungot Manananggal@NPC_BLOODDRAIN,attack,199,1,1000,0,5000,no,target,always,0,,,,,,3,
|
||||
2338,Bangungot Manananggal@NPC_COMBOATTACK,attack,171,5,500,700,5000,no,target,always,0,,,,,,1,
|
||||
@@ -8129,11 +8129,11 @@
|
||||
2339,Bangungot Mangkukulam@NPC_DARKSTRIKE,chase,340,9,500,700,5000,no,target,always,0,,,,,,29,
|
||||
2339,Bangungot Mangkukulam@NPC_MENTALBREAKER,attack,159,3,500,800,5000,no,target,always,0,,,,,,14,
|
||||
2339,Bangungot Mangkukulam@NPC_MENTALBREAKER,chase,159,3,500,800,5000,no,target,always,0,,,,,,14,
|
||||
2340,Tiyanak@NPC_BLOODDRAIN,attack,199,1,500,0,5000,yes,randomtarget,always,0,,,,,,2,
|
||||
2340,Tiyanak@NPC_BLOODDRAIN,attack,199,1,500,0,5000,yes,target,always,0,,,,,,2,
|
||||
2340,Tiyanak@NPC_EMOTION,idle,197,1,2000,0,5000,yes,self,always,0,29,,,,,,
|
||||
2340,Tiyanak@CR_AUTOGUARD,chase,249,2,2000,0,300000,yes,self,longrangeattacked,,,,,,,,
|
||||
2340,Tiyanak@CR_AUTOGUARD,attack,249,2,500,0,300000,yes,self,always,0,,,,,,,
|
||||
2340,Tiyanak@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,randomtarget,always,0,,,,,,6,
|
||||
2340,Tiyanak@NPC_CRITICALSLASH,attack,170,1,500,500,5000,no,target,always,0,,,,,,6,
|
||||
2340,Tiyanak@NPC_REBIRTH,dead,208,3,2000,0,10000,yes,self,always,0,,,,,,,
|
||||
2341,RWC Boss@NPC_CALLSLAVE,attack,352,1,10000,0,30000,yes,self,always,0,,,,,,,
|
||||
2341,RWC Boss@NPC_CALLSLAVE,idle,352,1,10000,0,30000,yes,self,always,0,,,,,,,
|
||||
@@ -8162,7 +8162,7 @@
|
||||
2341,RWC Boss@NPC_CRITICALWOUND,attack,673,4,2000,0,5000,yes,target,always,0,,,,,,,
|
||||
2343,Hidden Mob@NPC_INVISIBLE,idle,353,1,10000,0,30000,yes,self,always,0,,,,,,,
|
||||
2343,Hidden Mob@NPC_INVISIBLE,attack,353,1,10000,0,30000,yes,self,always,0,,,,,,,
|
||||
2343,Hidden Mob@WZ_STORMGUST,attack,89,5,10000,0,1000,yes,randomtarget,always,0,,,,,,,
|
||||
2343,Hidden Mob@WZ_STORMGUST,attack,89,5,10000,0,1000,yes,target,always,0,,,,,,,
|
||||
|
||||
// Nightmare Pyramids
|
||||
2353,Nightmare Minorous@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
|
||||
@@ -8198,8 +8198,8 @@
|
||||
2360,Nightmare Ancient Mummy@NPC_DARKBREATH,attack,202,4,500,800,5000,no,target,always,0,,,,,,7,
|
||||
2362,Nightmare Amon Ra@NPC_BLOODDRAIN,idle,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
2362,Nightmare Amon Ra@NPC_BLOODDRAIN,idle,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
2362,Nightmare Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
2362,Nightmare Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,randomtarget,always,0,,,,,,29,
|
||||
2362,Nightmare Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,target,always,0,,,,,,29,
|
||||
2362,Nightmare Amon Ra@NPC_BLOODDRAIN,attack,199,1,2000,0,5000,yes,target,always,0,,,,,,29,
|
||||
2362,Nightmare Amon Ra@NPC_SUMMONMONSTER,idle,209,5,5000,0,10000,no,self,longrangeattacked,0,2357,2359,2361,,,9,
|
||||
2362,Nightmare Amon Ra@NPC_SUMMONMONSTER,idle,209,5,5000,0,10000,no,self,casttargeted,0,1474,1477,1438,,,9,
|
||||
2362,Nightmare Amon Ra@NPC_SUMMONMONSTER,attack,209,5,5000,0,10000,no,self,longrangeattacked,0,2357,2359,2361,,,9,
|
||||
@@ -8218,11 +8218,11 @@
|
||||
2362,Nightmare Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,skillused,83,,,,,,9,
|
||||
2362,Nightmare Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,longrangeattacked,,,,,,,9,
|
||||
2362,Nightmare Amon Ra@WZ_METEOR,idle,83,11,10000,0,0,yes,randomtarget,casttargeted,,,,,,,9,
|
||||
2362,Nightmare Amon Ra@WZ_METEOR,attack,83,11,5000,0,3000,yes,randomtarget,always,0,,,,,,9,
|
||||
2362,Nightmare Amon Ra@WZ_METEOR,attack,83,11,5000,0,3000,yes,target,always,0,,,,,,9,
|
||||
2362,Nightmare Amon Ra@WZ_FIREPILLAR,idle,80,10,10000,0,2000,yes,around2,always,0,,,,,,,
|
||||
2362,Nightmare Amon Ra@WZ_FIREPILLAR,idle,80,10,10000,0,2000,yes,around2,always,0,,,,,,,
|
||||
2362,Nightmare Amon Ra@WZ_FIREPILLAR,attack,80,10,5000,0,2000,yes,around2,always,0,,,,,,,
|
||||
2362,Nightmare Amon Ra@NPC_DARKBLESSING,attack,203,1,5000,0,2000,no,randomtarget,always,0,,,,,,,
|
||||
2362,Nightmare Amon Ra@NPC_DARKBLESSING,attack,203,1,5000,0,2000,no,target,always,0,,,,,,,
|
||||
2362,Nightmare Amon Ra@WZ_METEOR,idle,83,11,10000,0,5000,yes,randomtarget,always,0,,,,,,9,
|
||||
2362,Nightmare Amon Ra@AL_TELEPORT,idle,26,1,10000,0,0,yes,self,rudeattacked,,,,,,,,
|
||||
2362,Nightmare Amon Ra@AL_TELEPORT,walk,26,1,5000,0,5000,yes,self,rudeattacked,,,,,,,,
|
||||
|
||||
50
db/re/produce_db.yml
Normal file
50
db/re/produce_db.yml
Normal file
@@ -0,0 +1,50 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2023 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 Produce Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Produce Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - ItemLevel Number which determines what kind of a crafting window will pop-up.
|
||||
# Recipe:
|
||||
# - Product AegisName of the produced item.
|
||||
# SkillName Skill name required. (Default: null)
|
||||
# SkillLevel Skill level required. (Default: 1)
|
||||
# Consumed: List of items consumed to produce the Product.
|
||||
# - Item AegisName of the consumed item.
|
||||
# Amount Amount required.
|
||||
# Clear Remove the item with the given AegisName from Consumed. (Optional)
|
||||
# NotConsumed: List of items not consumed to produce the Product. (Default: null)
|
||||
# - Item AegisName of the unconsumed item.
|
||||
# Clear Remove the item with the given AegisName from NotConsumed. (Optional)
|
||||
# BaseRate Base rate (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000)
|
||||
# Make: List of item amounts with their individual rate produced by Change Material (ItemLevel: 26). (Default: null)
|
||||
# - Amount Amount of item created (unique to the list) for Change Material (ItemLevel: 26).
|
||||
# Rate Rate to create the Amount (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000. 0 to remove on import)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: PRODUCE_DB
|
||||
Version: 1
|
||||
|
||||
Footer:
|
||||
Imports:
|
||||
- Path: db/re/skill_produce_db.yml
|
||||
- Path: db/re/skill_changematerial_db.yml
|
||||
911
db/re/skill_changematerial_db.yml
Normal file
911
db/re/skill_changematerial_db.yml
Normal file
@@ -0,0 +1,911 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2023 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 Produce Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Produce Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - ItemLevel Number which determines what kind of a crafting window will pop-up.
|
||||
# Recipe:
|
||||
# - Product AegisName of the produced item.
|
||||
# Skill: Skill requirement. (Default: null)
|
||||
# Name Skill name required.
|
||||
# Level Skill level required.
|
||||
# Consumed: List of items consumed to produce the Product.
|
||||
# - Item AegisName of the consumed item.
|
||||
# Amount Amount required.
|
||||
# Clear Remove the item with the given AegisName from Consumed. (Optional)
|
||||
# NotConsumed: List of items not consumed to produce the Product. (Default: null)
|
||||
# - Item AegisName of the unconsumed item.
|
||||
# Clear Remove the item with the given AegisName from NotConsumed. (Optional)
|
||||
# BaseRate Base rate (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000)
|
||||
# Make: List of item amounts with their individual rate produced by Change Material (ItemLevel: 26). (Default: null)
|
||||
# - Amount Amount of item created (unique to the list) for Change Material (ItemLevel: 26).
|
||||
# Rate Rate to create the Amount (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000. 0 to remove on import)
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: PRODUCE_DB
|
||||
Version: 1
|
||||
|
||||
Body:
|
||||
|
||||
- ItemLevel: 26
|
||||
Recipe:
|
||||
- Product: Sacred_Masque
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 8
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Grasshopper's_Leg
|
||||
Amount: 45
|
||||
- Item: Yoyo_Tail
|
||||
Amount: 35
|
||||
- Product: Long_Hair
|
||||
Make:
|
||||
- Amount: 4
|
||||
Rate: 800
|
||||
- Amount: 6
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Pencil_Case
|
||||
Amount: 40
|
||||
- Item: Tiger's_Skin
|
||||
Amount: 5
|
||||
- Product: Phracon
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 8
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Glass_Bead
|
||||
Amount: 40
|
||||
- Item: Spawn
|
||||
Amount: 45
|
||||
- Product: Lantern
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 3
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Blossom_Of_Maneater
|
||||
Amount: 20
|
||||
- Item: Solid_Shell
|
||||
Amount: 10
|
||||
- Product: Acorn
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 4
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Cactus_Needle
|
||||
Amount: 30
|
||||
- Item: Snail's_Shell
|
||||
Amount: 10
|
||||
- Product: Frozen_Heart
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 6
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Moth_Dust
|
||||
Amount: 35
|
||||
- Item: Raccoondog_Doll
|
||||
Amount: 25
|
||||
- Product: Horrendous_Mouth
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 9
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Dragon_Scale
|
||||
Amount: 45
|
||||
- Item: Stem
|
||||
Amount: 45
|
||||
- Product: Detrimindexta
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 5
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Chrysalis
|
||||
Amount: 40
|
||||
- Item: Flesh_Of_Clam
|
||||
Amount: 10
|
||||
- Product: Detonator
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 7
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Feather_Of_Birds
|
||||
Amount: 25
|
||||
- Item: Nose_Ring
|
||||
Amount: 45
|
||||
- Product: Tweezer
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 4
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Monkey_Doll
|
||||
Amount: 5
|
||||
- Item: Worm_Peelings
|
||||
Amount: 40
|
||||
- Product: Petite_DiablOfs_Horn
|
||||
Make:
|
||||
- Amount: 1
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Resin
|
||||
Amount: 10
|
||||
- Item: Stone_Heart
|
||||
Amount: 5
|
||||
- Product: Root_Of_Maneater
|
||||
Make:
|
||||
- Amount: 4
|
||||
Rate: 800
|
||||
- Amount: 6
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Talon
|
||||
Amount: 25
|
||||
- Item: Tooth_Of_
|
||||
Amount: 20
|
||||
- Product: Conch
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 3
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Gill
|
||||
Amount: 5
|
||||
- Item: Immortal_Heart
|
||||
Amount: 25
|
||||
- Product: Rotten_Scale
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 7
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Shell
|
||||
Amount: 20
|
||||
- Item: Thin_N'_Long_Tongue
|
||||
Amount: 50
|
||||
- Product: Elder_Pixie's_Beard
|
||||
Make:
|
||||
- Amount: 8
|
||||
Rate: 800
|
||||
- Amount: 12
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bee_Sting
|
||||
Amount: 35
|
||||
- Item: Petite_DiablOfs_Wing
|
||||
Amount: 45
|
||||
- Product: Lizard_Scruff
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 3
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Karvodailnirol
|
||||
Amount: 15
|
||||
- Item: Scale_Of_Snakes
|
||||
Amount: 20
|
||||
- Product: Emveretarcon
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 4
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Grasshopper_Doll
|
||||
Amount: 40
|
||||
- Item: Heart_Of_Mermaid
|
||||
Amount: 5
|
||||
- Product: Chinese_Ink
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 4
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bear's_Foot
|
||||
Amount: 20
|
||||
- Item: Black_Ladle
|
||||
Amount: 25
|
||||
- Product: Spiderweb
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 8
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Fin
|
||||
Amount: 50
|
||||
- Item: Slender_Snake
|
||||
Amount: 35
|
||||
- Product: Reins
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 8
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Chonchon_Doll
|
||||
Amount: 30
|
||||
- Item: Stuffed_Doll
|
||||
Amount: 50
|
||||
- Product: Wooden_Block
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 2
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Rotten_Bandage
|
||||
Amount: 10
|
||||
- Item: Single_Cell
|
||||
Amount: 10
|
||||
- Product: Tentacle
|
||||
Make:
|
||||
- Amount: 4
|
||||
Rate: 800
|
||||
- Amount: 6
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Decayed_Nail
|
||||
Amount: 40
|
||||
- Item: Wild_Boar's_Mane
|
||||
Amount: 5
|
||||
- Product: Mixture
|
||||
Make:
|
||||
- Amount: 4
|
||||
Rate: 800
|
||||
- Amount: 6
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Posionous_Canine
|
||||
Amount: 15
|
||||
- Item: Powder_Of_Butterfly
|
||||
Amount: 30
|
||||
- Product: Colorful_Shell
|
||||
Make:
|
||||
- Amount: 9
|
||||
Rate: 800
|
||||
- Amount: 13
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Horn
|
||||
Amount: 50
|
||||
- Item: Zargon
|
||||
Amount: 45
|
||||
- Product: Wing_Of_Moth
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 5
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Frozen_Rose
|
||||
Amount: 20
|
||||
- Item: Reptile_Tongue
|
||||
Amount: 30
|
||||
- Product: Nipper
|
||||
Make:
|
||||
- Amount: 6
|
||||
Rate: 800
|
||||
- Amount: 9
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Earthworm_Peeling
|
||||
Amount: 40
|
||||
- Item: Sticky_Mucus
|
||||
Amount: 25
|
||||
- Product: Turtle_Shell
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 4
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Fluff
|
||||
Amount: 5
|
||||
- Item: Poring_Doll
|
||||
Amount: 40
|
||||
- Product: Nail_Of_Orc
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 6
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Garlet
|
||||
Amount: 10
|
||||
- Item: Raccoon_Leaf
|
||||
Amount: 50
|
||||
- Product: Dragon_Canine
|
||||
Make:
|
||||
- Amount: 8
|
||||
Rate: 800
|
||||
- Amount: 12
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Osiris_Doll
|
||||
Amount: 50
|
||||
- Item: Sticky_Webfoot
|
||||
Amount: 35
|
||||
- Product: Skirt_Of_Virgin
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 6
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Head_Of_Medusa
|
||||
Amount: 35
|
||||
- Item: Scales_Shell
|
||||
Amount: 30
|
||||
- Product: Dragon_Train
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 6
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Sharpened_Cuspid
|
||||
Amount: 35
|
||||
- Item: Tooth_Of_Bat
|
||||
Amount: 25
|
||||
- Product: Dokkaebi_Horn
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 4
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Lip_Of_Ancient_Fish
|
||||
Amount: 25
|
||||
- Item: Shining_Scales
|
||||
Amount: 15
|
||||
- Product: Grit
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 8
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Crystal_Mirror
|
||||
Amount: 35
|
||||
- Item: Limb_Of_Mantis
|
||||
Amount: 50
|
||||
- Product: Sharp_Scale
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 3
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Clam_Shell
|
||||
Amount: 20
|
||||
- Item: Horseshoe
|
||||
Amount: 10
|
||||
- Product: Short_Leg
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 6
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Claw_Of_Wolves
|
||||
Amount: 20
|
||||
- Item: Scell
|
||||
Amount: 45
|
||||
- Product: Starsand_Of_Witch
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 2
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Blue_Porcelain
|
||||
Amount: 15
|
||||
- Item: Insect_Feeler
|
||||
Amount: 10
|
||||
- Product: Fox_Tail
|
||||
Make:
|
||||
- Amount: 2
|
||||
Rate: 800
|
||||
- Amount: 3
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Animal's_Skin
|
||||
Amount: 10
|
||||
- Item: Rouge
|
||||
Amount: 15
|
||||
- Product: Cobold_Hair
|
||||
Make:
|
||||
- Amount: 6
|
||||
Rate: 800
|
||||
- Amount: 9
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Jellopy
|
||||
Amount: 45
|
||||
- Item: Wedding_Bouquet
|
||||
Amount: 20
|
||||
- Product: Jaws_Of_Ant
|
||||
Make:
|
||||
- Amount: 4
|
||||
Rate: 800
|
||||
- Amount: 6
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Spore_Doll
|
||||
Amount: 20
|
||||
- Item: Witherless_Rose
|
||||
Amount: 20
|
||||
- Product: Voucher_Of_Orcish_Hero
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 5
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Nail_Of_Mole
|
||||
Amount: 45
|
||||
- Item: Tree_Root
|
||||
Amount: 5
|
||||
- Product: Sacred_Marks
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 4
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Pumpkin_Head
|
||||
Amount: 30
|
||||
- Item: Scorpion's_Tail
|
||||
Amount: 10
|
||||
- Product: Alchol
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 9
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Orcish_Voucher
|
||||
Amount: 50
|
||||
- Item: Skel_Bone
|
||||
Amount: 40
|
||||
- Product: Crap_Shell
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 8
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Baphomet_Doll
|
||||
Amount: 50
|
||||
- Item: Fish_Tail
|
||||
Amount: 30
|
||||
- Product: Tendon
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 3
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Feather
|
||||
Amount: 5
|
||||
- Item: Orcish_Cuspid
|
||||
Amount: 25
|
||||
- Product: Tiger_Footskin
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 2
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Pointed_Scale
|
||||
Amount: 5
|
||||
- Item: White_Platter
|
||||
Amount: 20
|
||||
- Product: Hinalle
|
||||
Make:
|
||||
- Amount: 2
|
||||
Rate: 200
|
||||
- Amount: 4
|
||||
Rate: 800
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bunch_Of_Flowers
|
||||
Amount: 45
|
||||
- Item: Moustache_Of_Mole
|
||||
Amount: 40
|
||||
- Product: Counteragent
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 4
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Evil_Horn
|
||||
Amount: 15
|
||||
- Item: Mementos
|
||||
Amount: 30
|
||||
- Product: Tooth_Of_Ancient_Fish
|
||||
Make:
|
||||
- Amount: 6
|
||||
Rate: 800
|
||||
- Amount: 9
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bill_Of_Birds
|
||||
Amount: 35
|
||||
- Item: Transparent_Cloth
|
||||
Amount: 30
|
||||
- Product: Rat_Tail
|
||||
Make:
|
||||
- Amount: 7
|
||||
Rate: 800
|
||||
- Amount: 10
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Golden_Hair
|
||||
Amount: 40
|
||||
- Item: Mushroom_Spore
|
||||
Amount: 35
|
||||
- Product: Coal
|
||||
BaseRate: 500
|
||||
Make:
|
||||
- Amount: 1
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Guard
|
||||
Amount: 1
|
||||
- Product: Steel
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Tsurugi
|
||||
Amount: 1
|
||||
- Product: Cigar
|
||||
Make:
|
||||
- Amount: 1
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Orcish_Axe
|
||||
Amount: 1
|
||||
- Product: Bone_Wand
|
||||
BaseRate: 200
|
||||
Make:
|
||||
- Amount: 1
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Broken_Farming_Utensil
|
||||
Amount: 100
|
||||
- Item: Clattering_Skull
|
||||
Amount: 100
|
||||
- Product: Cigar
|
||||
Make:
|
||||
- Amount: 1
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Orcish_Axe
|
||||
Amount: 1
|
||||
- Item: Orcish_Voucher
|
||||
Amount: 100
|
||||
- Product: Starsand_Of_Witch
|
||||
BaseRate: 800
|
||||
Make:
|
||||
- Amount: 2
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Moth_Dust
|
||||
Amount: 100
|
||||
- Item: Scell
|
||||
Amount: 100
|
||||
- Product: Soft_Feather
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 200
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Feather
|
||||
Amount: 30
|
||||
- Item: Feather_Of_Birds
|
||||
Amount: 30
|
||||
- Product: Wind_Of_Verdure
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 500
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Ice_Piece
|
||||
Amount: 100
|
||||
- Product: Crystal_Blue
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 500
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Claw_Of_Wolves
|
||||
Amount: 100
|
||||
- Product: Soft_Silk_Cloth
|
||||
Make:
|
||||
- Amount: 2
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Transparent_Cloth
|
||||
Amount: 10
|
||||
- Product: Transparent_Cloth
|
||||
Make:
|
||||
- Amount: 5
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Soft_Silk_Cloth
|
||||
Amount: 2
|
||||
- Product: Boost500_To_Throw
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 100
|
||||
- Amount: 2
|
||||
Rate: 250
|
||||
- Amount: 5
|
||||
Rate: 500
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Boost500
|
||||
Amount: 10
|
||||
- Item: Empty_Potion
|
||||
Amount: 10
|
||||
- Item: Flexible_String
|
||||
Amount: 10
|
||||
- Product: Full_SwingK_To_Throw
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 100
|
||||
- Amount: 2
|
||||
Rate: 250
|
||||
- Amount: 5
|
||||
Rate: 500
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Empty_Potion
|
||||
Amount: 10
|
||||
- Item: Flexible_String
|
||||
Amount: 10
|
||||
- Item: Full_SwingK
|
||||
Amount: 10
|
||||
- Product: Mana_Plus_To_Throw
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 100
|
||||
- Amount: 2
|
||||
Rate: 250
|
||||
- Amount: 5
|
||||
Rate: 500
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Empty_Potion
|
||||
Amount: 10
|
||||
- Item: Flexible_String
|
||||
Amount: 10
|
||||
- Item: Mana_Plus
|
||||
Amount: 10
|
||||
- Product: Cure_Free_To_Throw
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 100
|
||||
- Amount: 2
|
||||
Rate: 250
|
||||
- Amount: 5
|
||||
Rate: 500
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Cure_Free
|
||||
Amount: 10
|
||||
- Item: Empty_Potion
|
||||
Amount: 10
|
||||
- Item: Flexible_String
|
||||
Amount: 10
|
||||
- Product: Stamina_Up_M_To_Throw
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 100
|
||||
- Amount: 2
|
||||
Rate: 250
|
||||
- Amount: 5
|
||||
Rate: 500
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Empty_Potion
|
||||
Amount: 10
|
||||
- Item: Flexible_String
|
||||
Amount: 10
|
||||
- Item: Stamina_Up_M
|
||||
Amount: 10
|
||||
- Product: Digestive_F_To_Throw
|
||||
Make:
|
||||
- Amount: 1
|
||||
Rate: 100
|
||||
- Amount: 2
|
||||
Rate: 250
|
||||
- Amount: 5
|
||||
Rate: 500
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Digestive_F
|
||||
Amount: 10
|
||||
- Item: Empty_Potion
|
||||
Amount: 10
|
||||
- Item: Flexible_String
|
||||
Amount: 10
|
||||
- Product: HP_Inc_PotS_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: HP_Increase_PotionS
|
||||
Amount: 10
|
||||
- Product: HP_Inc_PotM_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: HP_Increase_PotionM
|
||||
Amount: 10
|
||||
- Product: HP_Inc_PotL_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: HP_Increase_PotionL
|
||||
Amount: 10
|
||||
- Product: SP_Inc_PotS_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: SP_Increase_PotionS
|
||||
Amount: 10
|
||||
- Product: SP_Inc_PotM_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: SP_Increase_PotionM
|
||||
Amount: 10
|
||||
- Product: SP_Inc_PotL_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: SP_Increase_PotionL
|
||||
Amount: 10
|
||||
- Product: En_White_PotZ_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: Enrich_White_PotionZ
|
||||
Amount: 10
|
||||
- Product: Vitata500_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: Vitata500
|
||||
Amount: 10
|
||||
- Product: En_Cel_Juice_To_Throw
|
||||
Make:
|
||||
- Amount: 10
|
||||
SkillName: GN_CHANGEMATERIAL
|
||||
SkillLevel: 1
|
||||
Consumed:
|
||||
- Item: Bottle_To_Throw
|
||||
Amount: 10
|
||||
- Item: Enrich_Celermine_Juice
|
||||
Amount: 10
|
||||
@@ -7234,9 +7234,8 @@ Body:
|
||||
Type: Magic
|
||||
TargetType: Self
|
||||
DamageFlags:
|
||||
IgnoreAtkCard: true
|
||||
IgnoreFlee: true
|
||||
Range: 5
|
||||
IgnoreDefense: true
|
||||
Range: 9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Element: Holy
|
||||
@@ -10250,15 +10249,15 @@ Body:
|
||||
Element: Weapon
|
||||
Duration1:
|
||||
- Level: 1
|
||||
Time: 4000
|
||||
Time: 2000
|
||||
- Level: 2
|
||||
Time: 8000
|
||||
Time: 4000
|
||||
- Level: 3
|
||||
Time: 12000
|
||||
Time: 6000
|
||||
- Level: 4
|
||||
Time: 16000
|
||||
Time: 8000
|
||||
- Level: 5
|
||||
Time: 24000
|
||||
Time: 10000
|
||||
CastDelayFlags:
|
||||
IgnoreStatus: true
|
||||
Requires:
|
||||
@@ -10274,7 +10273,7 @@ Body:
|
||||
- Level: 5
|
||||
Amount: 12
|
||||
SpiritSphereCost: 1
|
||||
Status: Stop
|
||||
Status: Ankle
|
||||
- Id: 372
|
||||
Name: CH_CHAINCRUSH
|
||||
Description: Chain Crush Combo
|
||||
@@ -11048,7 +11047,7 @@ Body:
|
||||
TargetType: Attack
|
||||
Flags:
|
||||
TargetTrap: true
|
||||
Range: 5
|
||||
Range: 4
|
||||
Hit: Multi_Hit
|
||||
HitCount: 5
|
||||
Element: Weapon
|
||||
@@ -11103,7 +11102,7 @@ Body:
|
||||
2hSword: true
|
||||
1hSpear: true
|
||||
2hSpear: true
|
||||
Status: Stop
|
||||
Status: Ankle
|
||||
- Id: 398
|
||||
Name: LK_HEADCRUSH
|
||||
Description: Traumatic Blow
|
||||
@@ -11313,7 +11312,7 @@ Body:
|
||||
TargetType: Attack
|
||||
DamageFlags:
|
||||
NoDamage: true
|
||||
Range: 7
|
||||
Range: 9
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
ActiveInstance: 3
|
||||
@@ -16709,7 +16708,7 @@ Body:
|
||||
Flags:
|
||||
IsNpc: true
|
||||
HitCount: 1
|
||||
Duration1: -1
|
||||
Duration1: 300000
|
||||
Status: Invincible
|
||||
- Id: 686
|
||||
Name: NPC_INVINCIBLEOFF
|
||||
@@ -16721,8 +16720,6 @@ Body:
|
||||
Flags:
|
||||
IsNpc: true
|
||||
HitCount: 1
|
||||
Duration1: 60000
|
||||
Status: InvincibleOff
|
||||
- Id: 687
|
||||
Name: NPC_ALLHEAL
|
||||
Description: Full Heal
|
||||
@@ -46224,7 +46221,7 @@ Body:
|
||||
TargetType: Attack
|
||||
Flags:
|
||||
TargetTrap: true
|
||||
Range: 5
|
||||
Range: 4
|
||||
Hit: Multi_Hit
|
||||
HitCount: 5
|
||||
Element: Weapon
|
||||
@@ -46268,7 +46265,7 @@ Body:
|
||||
Amount: 27
|
||||
- Level: 5
|
||||
Amount: 30
|
||||
Status: Stop
|
||||
Status: Ankle
|
||||
- Id: 8219
|
||||
Name: ML_DEFENDER
|
||||
Description: Defending_Aura
|
||||
@@ -46959,9 +46956,7 @@ Body:
|
||||
Range: 2
|
||||
Hit: Single
|
||||
HitCount: 1
|
||||
Duration1: 10000
|
||||
Cooldown: 30000
|
||||
Status: InvincibleOff
|
||||
- Id: 8401
|
||||
Name: EL_CIRCLE_OF_FIRE
|
||||
Description: Circle of Fire
|
||||
|
||||
2531
db/re/skill_produce_db.yml
Normal file
2531
db/re/skill_produce_db.yml
Normal file
File diff suppressed because it is too large
Load Diff
@@ -786,7 +786,6 @@ Body:
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
RemoveOnChangeMap: true
|
||||
MinDuration: 5000
|
||||
- Status: Keeping
|
||||
DurationLookup: NPC_KEEPING
|
||||
CalcFlags:
|
||||
@@ -2928,23 +2927,12 @@ Body:
|
||||
Icon: EFST_INVINCIBLE
|
||||
DurationLookup: NPC_INVINCIBLE
|
||||
CalcFlags:
|
||||
Aspd: true
|
||||
Speed: true
|
||||
Flags:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
EndOnStart:
|
||||
Invincibleoff: true
|
||||
- Status: Invincibleoff
|
||||
DurationLookup: NPC_INVINCIBLEOFF
|
||||
CalcFlags:
|
||||
Speed: true
|
||||
Flags:
|
||||
NoDispell: true
|
||||
NoBanishingBuster: true
|
||||
NoClearance: true
|
||||
EndOnStart:
|
||||
Invincible: true
|
||||
- Status: Manu_Atk
|
||||
Icon: EFST_MANU_ATK
|
||||
Flags:
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
//===== By: ==================================================
|
||||
//= rAthena Dev Team
|
||||
//===== Last Updated: ========================================
|
||||
//= 20130613
|
||||
//= 20240414
|
||||
//===== Description: =========================================
|
||||
//= List of available permissions and their functions.
|
||||
//============================================================
|
||||
@@ -227,6 +227,6 @@ Allows player to use the client command /macro_detector.
|
||||
|
||||
*macro_register
|
||||
|
||||
Allows player to use the client commands /maco_register (used to add new captcha) and /macro_preview (used to preview captcha by ID).
|
||||
Allows player to use the client commands /macro_register (used to add new captcha) and /macro_preview (used to preview captcha by ID).
|
||||
|
||||
---------------------------------------
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2023 rAthena Development Team
|
||||
# Copyright(C) 2024 rAthena Development Team
|
||||
# https://rathena.org - https://github.com/rathena
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
|
||||
24
doc/yaml/db/produce_db.yml
Normal file
24
doc/yaml/db/produce_db.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
###########################################################################
|
||||
# Item Produce Database
|
||||
###########################################################################
|
||||
#
|
||||
# Item Produce Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - ItemLevel Number which determines what kind of a crafting window will pop-up.
|
||||
# Recipe:
|
||||
# - Product AegisName of the produced item.
|
||||
# SkillName Skill name required. (Default: null)
|
||||
# SkillLevel Skill level required. (Default: 1)
|
||||
# Consumed: List of items consumed to produce the Product.
|
||||
# - Item AegisName of the consumed item.
|
||||
# Amount Amount required.
|
||||
# Clear Remove the item with the given AegisName from Consumed. (Optional)
|
||||
# NotConsumed: List of items not consumed to produce the Product. (Default: null)
|
||||
# - Item AegisName of the unconsumed item.
|
||||
# Clear Remove the item with the given AegisName from NotConsumed. (Optional)
|
||||
# BaseRate Base rate (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000)
|
||||
# Make: List of item amounts with their individual rate produced by Change Material (ItemLevel: 26). (Default: null)
|
||||
# - Amount Amount of item created (unique to the list) for Change Material (ItemLevel: 26).
|
||||
# Rate Rate to create the Amount (in n/10%) for Change Material (ItemLevel: 26). (Default: 1000. 0 to remove on import)
|
||||
###########################################################################
|
||||
File diff suppressed because it is too large
Load Diff
@@ -2820,7 +2820,8 @@ void char_set_defaults(){
|
||||
*/
|
||||
void char_config_split_startpoint( char* w1_value, char* w2_value, struct s_point_str start_point[MAX_STARTPOINT], short* count ){
|
||||
char *lineitem, **fields;
|
||||
int i = 0, fields_length = 3 + 1;
|
||||
int i = 0;
|
||||
size_t fields_length = 3 + 1;
|
||||
|
||||
(*count) = 0; // Reset to begin reading
|
||||
|
||||
@@ -2859,7 +2860,8 @@ void char_config_split_startpoint( char* w1_value, char* w2_value, struct s_poin
|
||||
void char_config_split_startitem(char *w1_value, char *w2_value, struct startitem start_items[MAX_STARTITEM])
|
||||
{
|
||||
char *lineitem, **fields;
|
||||
int i = 0, fields_length = 3 + 1;
|
||||
int i = 0;
|
||||
size_t fields_length = 3 + 1;
|
||||
|
||||
fields = (char **)aMalloc(fields_length * sizeof(char *));
|
||||
if (fields == NULL)
|
||||
|
||||
@@ -91,7 +91,7 @@ void chlogif_pincode_start(int fd, struct char_session_data* sd){
|
||||
* @param tick : Scheduled tick
|
||||
* @param id : GID linked to that timered call
|
||||
* @param data : data transmited for delayed function
|
||||
* @return
|
||||
* @return
|
||||
*/
|
||||
TIMER_FUNC(chlogif_send_acc_tologin){
|
||||
if ( chlogif_isconnected() ){
|
||||
@@ -391,27 +391,70 @@ int chlogif_parse_keepalive(int fd){
|
||||
*/
|
||||
void chlogif_parse_change_sex_sub(int sex, int acc, int char_id, int class_, int guild_id)
|
||||
{
|
||||
// job modification //@TODO switch would be faster
|
||||
if (class_ == JOB_BARD || class_ == JOB_DANCER)
|
||||
class_ = (sex == SEX_MALE ? JOB_BARD : JOB_DANCER);
|
||||
else if (class_ == JOB_CLOWN || class_ == JOB_GYPSY)
|
||||
class_ = (sex == SEX_MALE ? JOB_CLOWN : JOB_GYPSY);
|
||||
else if (class_ == JOB_BABY_BARD || class_ == JOB_BABY_DANCER)
|
||||
class_ = (sex == SEX_MALE ? JOB_BABY_BARD : JOB_BABY_DANCER);
|
||||
else if (class_ == JOB_MINSTREL || class_ == JOB_WANDERER)
|
||||
class_ = (sex == SEX_MALE ? JOB_MINSTREL : JOB_WANDERER);
|
||||
else if (class_ == JOB_MINSTREL_T || class_ == JOB_WANDERER_T)
|
||||
class_ = (sex == SEX_MALE ? JOB_MINSTREL_T : JOB_WANDERER_T);
|
||||
else if (class_ == JOB_BABY_MINSTREL || class_ == JOB_BABY_WANDERER)
|
||||
class_ = (sex == SEX_MALE ? JOB_BABY_MINSTREL : JOB_BABY_WANDERER);
|
||||
else if (class_ == JOB_KAGEROU || class_ == JOB_OBORO)
|
||||
class_ = (sex == SEX_MALE ? JOB_KAGEROU : JOB_OBORO);
|
||||
else if (class_ == JOB_BABY_KAGEROU || class_ == JOB_BABY_OBORO)
|
||||
class_ = (sex == SEX_MALE ? JOB_BABY_KAGEROU : JOB_BABY_OBORO);
|
||||
else if (class_ == JOB_TROUBADOUR || class_ == JOB_TROUVERE)
|
||||
class_ = (sex == SEX_MALE ? JOB_TROUBADOUR : JOB_TROUVERE);
|
||||
else if (class_ == JOB_SHINKIRO || class_ == JOB_SHIRANUI)
|
||||
class_ = (sex == SEX_MALE ? JOB_SHINKIRO : JOB_SHIRANUI);
|
||||
// job modification
|
||||
switch (class_)
|
||||
{
|
||||
case JOB_BARD:
|
||||
class_ = JOB_DANCER;
|
||||
break;
|
||||
case JOB_DANCER:
|
||||
class_ = JOB_BARD;
|
||||
break;
|
||||
case JOB_CLOWN:
|
||||
class_ = JOB_GYPSY;
|
||||
break;
|
||||
case JOB_GYPSY:
|
||||
class_ = JOB_CLOWN;
|
||||
break;
|
||||
case JOB_BABY_BARD:
|
||||
class_ = JOB_BABY_DANCER;
|
||||
break;
|
||||
case JOB_BABY_DANCER:
|
||||
class_ = JOB_BABY_BARD;
|
||||
break;
|
||||
case JOB_MINSTREL:
|
||||
class_ = JOB_WANDERER;
|
||||
break;
|
||||
case JOB_WANDERER:
|
||||
class_ = JOB_MINSTREL;
|
||||
break;
|
||||
case JOB_MINSTREL_T:
|
||||
class_ = JOB_WANDERER_T;
|
||||
break;
|
||||
case JOB_WANDERER_T:
|
||||
class_ = JOB_MINSTREL_T;
|
||||
break;
|
||||
case JOB_BABY_MINSTREL:
|
||||
class_ = JOB_BABY_WANDERER;
|
||||
break;
|
||||
case JOB_BABY_WANDERER:
|
||||
class_ = JOB_BABY_MINSTREL;
|
||||
break;
|
||||
case JOB_KAGEROU:
|
||||
class_ = JOB_OBORO;
|
||||
break;
|
||||
case JOB_OBORO:
|
||||
class_ = JOB_KAGEROU;
|
||||
break;
|
||||
case JOB_BABY_KAGEROU:
|
||||
class_ = JOB_BABY_OBORO;
|
||||
break;
|
||||
case JOB_BABY_OBORO:
|
||||
class_ = JOB_BABY_KAGEROU;
|
||||
break;
|
||||
case JOB_TROUBADOUR:
|
||||
class_ = JOB_TROUVERE;
|
||||
break;
|
||||
case JOB_TROUVERE:
|
||||
class_ = JOB_TROUBADOUR;
|
||||
break;
|
||||
case JOB_SHINKIRO:
|
||||
class_ = JOB_SHIRANUI;
|
||||
break;
|
||||
case JOB_SHIRANUI:
|
||||
class_ = JOB_SHINKIRO;
|
||||
break;
|
||||
}
|
||||
|
||||
if (SQL_ERROR == Sql_Query(sql_handle, "UPDATE `%s` SET `equip` = '0' WHERE `char_id` = '%d'", schema_config.inventory_db, char_id))
|
||||
Sql_ShowDebug(sql_handle);
|
||||
|
||||
@@ -205,7 +205,7 @@ public:
|
||||
}
|
||||
|
||||
// Resize to only fit all existing non null entries
|
||||
this->cache.resize(max_key);
|
||||
this->cache.resize(max_key + 1);
|
||||
// Free the memory that was allocated too much
|
||||
this->cache.shrink_to_fit();
|
||||
this->loaded = true;
|
||||
|
||||
@@ -278,9 +278,8 @@ namespace rathena {
|
||||
|
||||
if( rathena::util::safe_addition( a, b, result ) ){
|
||||
return cap;
|
||||
}else{
|
||||
return result;
|
||||
}
|
||||
return std::min(result, cap);
|
||||
}
|
||||
|
||||
template <typename T> void tolower( T& string ){
|
||||
|
||||
@@ -34,6 +34,8 @@
|
||||
#include "pc_groups.hpp"
|
||||
#include "pet.hpp"
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
struct Battle_Config battle_config;
|
||||
static struct eri *delay_damage_ers; //For battle delay damage structures.
|
||||
|
||||
@@ -254,33 +256,42 @@ struct block_list* battle_getenemyarea(struct block_list *src, int x, int y, int
|
||||
return bl_list[rnd()%c];
|
||||
}
|
||||
|
||||
/*========================================== [Playtester]
|
||||
/**
|
||||
* Deals damage without delay, applies additional effects and triggers monster events
|
||||
* This function is called from battle_delay_damage or battle_delay_damage_sub
|
||||
* All other instances of battle damage should also go through this function (i.e. anything that displays a damage number)
|
||||
* Consider calling this function or battle_fix_damage instead status_fix_damage directly
|
||||
* @param src: Source of damage
|
||||
* @param target: Target of damage
|
||||
* @param damage: Damage to be dealt
|
||||
* @param delay: Damage delay
|
||||
* @param skill_lv: Level of skill used
|
||||
* @param skill_id: ID o skill used
|
||||
* @param skill_id: ID of skill used
|
||||
* @param dmg_lv: State of the attack (miss, etc.)
|
||||
* @param attack_type: Type of the attack (BF_NORMAL|BF_SKILL|BF_SHORT|BF_LONG|BF_WEAPON|BF_MAGIC|BF_MISC)
|
||||
* @param additional_effects: Whether additional effect should be applied
|
||||
* @param additional_effects: Whether additional effects should be applied (otherwise it's just damage+coma)
|
||||
* @param isspdamage: If the damage is done to SP
|
||||
* @param tick: Current tick
|
||||
*------------------------------------------*/
|
||||
void battle_damage(struct block_list *src, struct block_list *target, int64 damage, t_tick delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, t_tick tick, bool isspdamage) {
|
||||
* @return HP+SP+AP (0 if HP/SP/AP remained unchanged)
|
||||
*/
|
||||
int battle_damage(struct block_list *src, struct block_list *target, int64 damage, t_tick delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, t_tick tick, bool isspdamage) {
|
||||
int dmg_change;
|
||||
map_session_data* sd = nullptr;
|
||||
if (src)
|
||||
sd = BL_CAST(BL_PC, src);
|
||||
map_freeblock_lock();
|
||||
if (isspdamage)
|
||||
status_fix_spdamage(src, target, damage, delay, skill_id);
|
||||
dmg_change = status_fix_spdamage(src, target, damage, delay, skill_id);
|
||||
else if (sd && battle_check_coma(*sd, *target, (e_battle_flag)attack_type))
|
||||
dmg_change = status_damage(src, target, damage, 0, delay, 16, skill_id); // Coma attack
|
||||
else
|
||||
status_fix_damage(src, target, damage, delay, skill_id); // We have to separate here between reflect damage and others [icescope]
|
||||
dmg_change = status_fix_damage(src, target, damage, delay, skill_id);
|
||||
if (attack_type && !status_isdead(target) && additional_effects)
|
||||
skill_additional_effect(src, target, skill_id, skill_lv, attack_type, dmg_lv, tick);
|
||||
if (dmg_lv > ATK_BLOCK && attack_type)
|
||||
if (dmg_lv > ATK_BLOCK && attack_type && additional_effects)
|
||||
skill_counter_additional_effect(src, target, skill_id, skill_lv, attack_type, tick);
|
||||
// This is the last place where we have access to the actual damage type, so any monster events depending on type must be placed here
|
||||
if (target->type == BL_MOB) {
|
||||
if (target->type == BL_MOB && additional_effects) {
|
||||
mob_data *md = BL_CAST(BL_MOB, target);
|
||||
|
||||
if (md != nullptr) {
|
||||
@@ -298,6 +309,7 @@ void battle_damage(struct block_list *src, struct block_list *target, int64 dama
|
||||
}
|
||||
}
|
||||
map_freeblock_unlock();
|
||||
return dmg_change;
|
||||
}
|
||||
|
||||
/// Damage Delayed Structure
|
||||
@@ -331,9 +343,7 @@ TIMER_FUNC(battle_delay_damage_sub){
|
||||
//Deal damage
|
||||
battle_damage(src, target, dat->damage, dat->delay, dat->skill_lv, dat->skill_id, dat->dmg_lv, dat->attack_type, dat->additional_effects, tick, dat->isspdamage);
|
||||
} else if( !src && dat->skill_id == CR_REFLECTSHIELD ) { // it was monster reflected damage, and the monster died, we pass the damage to the character as expected
|
||||
map_freeblock_lock();
|
||||
status_fix_damage(target, target, dat->damage, dat->delay, dat->skill_id);
|
||||
map_freeblock_unlock();
|
||||
battle_fix_damage(target, target, dat->damage, dat->delay, dat->skill_id);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -412,6 +422,10 @@ int battle_delay_damage(t_tick tick, int amotion, struct block_list *src, struct
|
||||
return 0;
|
||||
}
|
||||
|
||||
int battle_fix_damage(struct block_list* src, struct block_list* target, int64 damage, t_tick walkdelay, uint16 skill_id) {
|
||||
return battle_damage(src, target, damage, walkdelay, 0, skill_id, ATK_DEF, BF_MISC, false, gettick(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Does attribute fix modifiers.
|
||||
* Added passing of the chars so that the status changes can affect it. [Skotlex]
|
||||
@@ -1548,11 +1562,6 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
return 0;
|
||||
}
|
||||
|
||||
status_change* tsc = status_get_sc(bl); //check target status
|
||||
|
||||
if( tsc && tsc->getSCE(SC_INVINCIBLE) && !tsc->getSCE(SC_INVINCIBLEOFF) )
|
||||
return 1;
|
||||
|
||||
switch (skill_id) {
|
||||
#ifndef RENEWAL
|
||||
case PA_PRESSURE:
|
||||
@@ -1566,6 +1575,8 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
return damage; //These skills bypass everything else.
|
||||
}
|
||||
|
||||
status_change* tsc = status_get_sc(bl); //check target status
|
||||
|
||||
// Nothing can reduce the damage, but Safety Wall and Millennium Shield can block it completely.
|
||||
// So can defense sphere's but what the heck is that??? [Rytech]
|
||||
if (skill_id == SJ_NOVAEXPLOSING && !(tsc && (tsc->getSCE(SC_SAFETYWALL) || tsc->getSCE(SC_MILLENNIUMSHIELD)))) {
|
||||
@@ -1880,9 +1891,6 @@ int64 battle_calc_damage(struct block_list *src,struct block_list *bl,struct Dam
|
||||
}
|
||||
}
|
||||
|
||||
if( sc->getSCE(SC_INVINCIBLE) && !sc->getSCE(SC_INVINCIBLEOFF) )
|
||||
damage += damage * 75 / 100;
|
||||
|
||||
if ((sce = sc->getSCE(SC_BLOODLUST)) && flag&BF_WEAPON && damage > 0 && rnd()%100 < sce->val3)
|
||||
status_heal(src, damage * sce->val4 / 100, 0, 3);
|
||||
|
||||
@@ -2499,7 +2507,7 @@ static int64 battle_calc_base_damage(struct block_list *src, struct status_data
|
||||
if (atkmin > atkmax)
|
||||
atkmin = atkmax;
|
||||
|
||||
if(flag&BDMG_ARROW && !(flag&BDMG_THROW)) { //Bows
|
||||
if(flag&BDMG_ARROW) { //Bows
|
||||
atkmin = atkmin*atkmax/100;
|
||||
if (atkmin > atkmax)
|
||||
atkmax = atkmin;
|
||||
@@ -2845,6 +2853,10 @@ bool is_infinite_defense(struct block_list *target, int flag)
|
||||
if(status_has_mode(tstatus,MD_IGNOREMISC) && flag&(BF_MISC) )
|
||||
return true;
|
||||
|
||||
status_change* tsc = status_get_sc(target);
|
||||
if (tsc && tsc->getSCE(SC_INVINCIBLE))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -3359,12 +3371,11 @@ static bool attack_ignores_def(struct Damage* wd, struct block_list *src, struct
|
||||
/**
|
||||
* This function lists which skills are unaffected by refine bonus, masteries, Star Crumbs and Spirit Spheres
|
||||
* This function is also used to determine if atkpercent applies
|
||||
* @param src: Source of the attack
|
||||
* @param skill_id: Skill being used
|
||||
* @param chk_flag: The bonus that is currently being checked for, see e_bonus_chk_flag
|
||||
* @return true = bonus applies; false = bonus does not apply
|
||||
*/
|
||||
static bool battle_skill_stacks_masteries_vvs(struct block_list &src, uint16 skill_id, e_bonus_chk_flag chk_flag)
|
||||
static bool battle_skill_stacks_masteries_vvs(uint16 skill_id, e_bonus_chk_flag chk_flag)
|
||||
{
|
||||
switch (skill_id) {
|
||||
// PC skills that are unaffected
|
||||
@@ -3381,41 +3392,9 @@ static bool battle_skill_stacks_masteries_vvs(struct block_list &src, uint16 ski
|
||||
case LG_EARTHDRIVE:
|
||||
case NPC_DRAGONBREATH:
|
||||
return false;
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS:
|
||||
// Grand Cross is influenced by refine bonus but not by atkpercent / masteries / Star Crumbs / Spirit Spheres
|
||||
if (chk_flag != BCHK_REFINE)
|
||||
return false;
|
||||
break;
|
||||
case LK_SPIRALPIERCE:
|
||||
// Spiral Pierce is influenced only by refine bonus and Star Crumbs for players
|
||||
if (src.type == BL_PC && chk_flag != BCHK_REFINE && chk_flag != BCHK_STAR)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function lists which skills are unaffected by EDP and the elemental bonus from Magnum Break / EDP
|
||||
* Unit skills (e.g. Bomb and Freezing Trap) are never affected.
|
||||
* @param skill_id: Skill being used
|
||||
* @return true = bonus applies; false = bonus does not apply
|
||||
*/
|
||||
static bool battle_skill_stacks_edp_element(uint16 skill_id)
|
||||
{
|
||||
switch (skill_id) {
|
||||
case TF_SPRINKLESAND:
|
||||
case AS_SPLASHER:
|
||||
case ASC_METEORASSAULT:
|
||||
case ASC_BREAKER:
|
||||
case AS_VENOMKNIFE:
|
||||
case AM_ACIDTERROR:
|
||||
return false;
|
||||
default:
|
||||
//Unit skills
|
||||
if (skill_get_unit_id(skill_id))
|
||||
if (chk_flag != BCHK_REFINE && chk_flag != BCHK_STAR)
|
||||
return false;
|
||||
break;
|
||||
}
|
||||
@@ -3670,7 +3649,9 @@ int battle_get_misc_element(struct block_list* src, struct block_list* target, u
|
||||
static void battle_min_damage(struct Damage &wd, struct block_list &src, uint16 skill_id, int64 min) {
|
||||
if (is_attack_right_handed(&src, skill_id)) {
|
||||
wd.damage = cap_value(wd.damage, min, INT64_MAX);
|
||||
#ifndef RENEWAL
|
||||
wd.basedamage = cap_value(wd.basedamage, min, INT64_MAX);
|
||||
#endif
|
||||
}
|
||||
// Left-hand damage is always capped to 0
|
||||
if (is_attack_left_handed(&src, skill_id)) {
|
||||
@@ -3789,27 +3770,45 @@ static void battle_calc_element_damage(struct Damage* wd, struct block_list *src
|
||||
// These mastery bonuses are non-elemental and should apply even if the attack misses
|
||||
// They are still increased by the EDP/Magnum Break bonus damage (WATK_ELEMENT)
|
||||
// In renewal these bonuses do not apply when the attack misses
|
||||
if (sd && battle_skill_stacks_masteries_vvs(*src, skill_id, BCHK_STAR)) {
|
||||
if (sd && battle_skill_stacks_masteries_vvs(skill_id, BCHK_STAR)) {
|
||||
// Star Crumb bonus damage
|
||||
ATK_ADD2(wd->damage, wd->damage2, sd->right_weapon.star, sd->left_weapon.star);
|
||||
}
|
||||
// Check if general mastery bonuses apply (above check is only for Star Crumb)
|
||||
if (battle_skill_stacks_masteries_vvs(*src, skill_id, BCHK_ALL)) {
|
||||
if (battle_skill_stacks_masteries_vvs(skill_id, BCHK_ALL)) {
|
||||
// Spirit Sphere bonus damage
|
||||
ATK_ADD(wd->damage, wd->damage2, battle_get_spiritball_damage(*wd, *src, skill_id));
|
||||
|
||||
// Skill-specific bonuses
|
||||
if (skill_id == TF_POISON) {
|
||||
ATK_ADD(wd->damage, wd->damage2, 15 * skill_lv);
|
||||
// Envenom applies the attribute table to the base damage and then again to the final damage
|
||||
wd->damage = battle_attr_fix(src, target, wd->damage, right_element, tstatus->def_ele, tstatus->ele_lv, 1);
|
||||
switch(skill_id) {
|
||||
case TF_POISON:
|
||||
ATK_ADD(wd->damage, wd->damage2, 15 * skill_lv);
|
||||
// Envenom applies the attribute table to the base damage and then again to the final damage
|
||||
wd->damage = battle_attr_fix(src, target, wd->damage, right_element, tstatus->def_ele, tstatus->ele_lv, 1);
|
||||
break;
|
||||
case NJ_SYURIKEN:
|
||||
ATK_ADD(wd->damage, wd->damage2, 4 * skill_lv);
|
||||
if (sd) {
|
||||
ATK_ADD(wd->damage, wd->damage2, 3 * pc_checkskill(sd, NJ_TOBIDOUGU));
|
||||
ATK_ADD(wd->damage, wd->damage2, sd->bonus.arrow_atk);
|
||||
}
|
||||
// Applies attribute table on neutral element to the final damage
|
||||
wd->damage = battle_attr_fix(src, target, wd->damage, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv, 1);
|
||||
break;
|
||||
case NJ_KUNAI:
|
||||
if (sd) {
|
||||
ATK_ADD(wd->damage, wd->damage2, 3 * sd->bonus.arrow_atk);
|
||||
}
|
||||
// Applies attribute table on neutral element to the final damage
|
||||
wd->damage = battle_attr_fix(src, target, wd->damage, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// These bonuses do not apply to skills that ignore element, unit skills and skills that have their own base damage formula
|
||||
// These bonuses do not apply to skills that ignore +% damage cards
|
||||
// If damage was reduced below 0 and was not increased again to a positive value through mastery bonuses, these bonuses are ignored
|
||||
// Any of these are only applied to your right hand weapon in pre-renewal
|
||||
if (!nk[NK_IGNOREELEMENT] && (wd->damage > 0 || wd->damage2 > 0) && sc && battle_skill_stacks_edp_element(skill_id)) {
|
||||
if (!nk[NK_IGNOREELEMENT] && !nk[NK_IGNOREATKCARD] && (wd->damage > 0 || wd->damage2 > 0) && sc) {
|
||||
|
||||
// EDP bonus damage
|
||||
// This has to be applied after mastery bonuses but still before the elemental extra damage
|
||||
@@ -3850,12 +3849,14 @@ static void battle_calc_attack_masteries(struct Damage* wd, struct block_list *s
|
||||
struct status_data *sstatus = status_get_status_data(src);
|
||||
int t_class = status_get_class(target);
|
||||
|
||||
#ifndef RENEWAL
|
||||
if (sd) {
|
||||
wd->basedamage = battle_addmastery(sd, target, wd->basedamage, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Check if mastery damage applies to current skill
|
||||
if (sd && battle_skill_stacks_masteries_vvs(*src, skill_id, BCHK_ALL))
|
||||
if (sd && battle_skill_stacks_masteries_vvs(skill_id, BCHK_ALL))
|
||||
{ //Add mastery damage
|
||||
uint16 skill;
|
||||
|
||||
@@ -3880,14 +3881,12 @@ static void battle_calc_attack_masteries(struct Damage* wd, struct block_list *s
|
||||
ATK_ADD2(wd->masteryAtk, wd->masteryAtk2, sd->right_weapon.star, sd->left_weapon.star);
|
||||
// Spirit Sphere bonus damage
|
||||
ATK_ADD(wd->masteryAtk, wd->masteryAtk2, battle_get_spiritball_damage(*wd, *src, skill_id));
|
||||
#endif
|
||||
|
||||
if (skill_id == NJ_SYURIKEN && (skill = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0) { // !TODO: Confirm new mastery formula
|
||||
if (skill_id == NJ_SYURIKEN && (skill = pc_checkskill(sd,NJ_TOBIDOUGU)) > 0) {
|
||||
ATK_ADD(wd->damage, wd->damage2, 3 * skill);
|
||||
#ifdef RENEWAL
|
||||
ATK_ADD(wd->masteryAtk, wd->masteryAtk2, 3 * skill);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
switch(skill_id) {
|
||||
case RA_WUGDASH:
|
||||
@@ -3956,10 +3955,10 @@ static void battle_calc_damage_parts(struct Damage* wd, struct block_list *src,s
|
||||
|
||||
if (sd && sd->sc.getSCE(SC_SEVENWIND)) { // Mild Wind applies element to status ATK as well as weapon ATK [helvetica]
|
||||
wd->statusAtk = battle_attr_fix(src, target, wd->statusAtk, right_element, tstatus->def_ele, tstatus->ele_lv);
|
||||
wd->statusAtk2 = battle_attr_fix(src, target, wd->statusAtk, left_element, tstatus->def_ele, tstatus->ele_lv);
|
||||
wd->statusAtk2 = battle_attr_fix(src, target, wd->statusAtk2, left_element, tstatus->def_ele, tstatus->ele_lv);
|
||||
} else { // status atk is considered neutral on normal attacks [helvetica]
|
||||
wd->statusAtk = battle_attr_fix(src, target, wd->statusAtk, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
|
||||
wd->statusAtk2 = battle_attr_fix(src, target, wd->statusAtk, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
|
||||
wd->statusAtk2 = battle_attr_fix(src, target, wd->statusAtk2, ELE_NEUTRAL, tstatus->def_ele, tstatus->ele_lv);
|
||||
}
|
||||
|
||||
// Check critical
|
||||
@@ -4178,8 +4177,9 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
|
||||
|
||||
default:
|
||||
// Flags that apply to both pre-renewal and renewal
|
||||
bflag = (is_attack_critical(wd, src, target, skill_id, skill_lv, false) ? BDMG_CRIT : BDMG_NONE) |
|
||||
(!skill_id && sc && sc->getSCE(SC_CHANGE) ? BDMG_MAGIC : BDMG_NONE);
|
||||
bflag = BDMG_NONE;
|
||||
if (is_attack_critical(wd, src, target, skill_id, skill_lv, false)) bflag |= BDMG_CRIT;
|
||||
if (!skill_id && sc && sc->getSCE(SC_CHANGE)) bflag |= BDMG_MAGIC;
|
||||
#ifdef RENEWAL
|
||||
if (sd)
|
||||
battle_calc_damage_parts(wd, src, target, skill_id, skill_lv);
|
||||
@@ -4190,24 +4190,26 @@ static void battle_calc_skill_base_damage(struct Damage* wd, struct block_list *
|
||||
}
|
||||
#else
|
||||
// Pre-renewal exclusive flags
|
||||
if (is_skill_using_arrow(src, skill_id)) bflag |= BDMG_ARROW;
|
||||
if (skill_id == HW_MAGICCRASHER) bflag |= BDMG_MAGIC;
|
||||
if (sc && sc->getSCE(SC_WEAPONPERFECTION)) bflag |= BDMG_NOSIZE;
|
||||
if (is_skill_using_arrow(src, skill_id) && sd) {
|
||||
switch(sd->status.weapon) {
|
||||
case W_BOW:
|
||||
bflag |= BDMG_ARROW;
|
||||
break;
|
||||
case W_REVOLVER:
|
||||
case W_RIFLE:
|
||||
case W_GATLING:
|
||||
case W_SHOTGUN:
|
||||
case W_GRENADE:
|
||||
if (bflag & BDMG_CRIT) {
|
||||
bflag &= ~(BDMG_ARROW); // Criticals with any guns are calculated like melee criticals
|
||||
// Criticals with any guns are calculated like melee criticals
|
||||
if (!(bflag & BDMG_CRIT)) {
|
||||
bflag |= BDMG_ARROW;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
bflag |= BDMG_THROW; // for ex. shuriken must not be influenced by DEX
|
||||
// Attacks that use ammo are calculated like melee attacks as long as no ranged weapon is equipped
|
||||
// Some skills manually add arrow_atk as mastery bonus later (e.g. Throw Shuriken, Throw Kunai)
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -4440,7 +4442,7 @@ static void battle_calc_multi_attack(struct Damage* wd, struct block_list *src,s
|
||||
*/
|
||||
static unsigned short battle_get_atkpercent(struct block_list& bl, uint16 skill_id, status_change& sc)
|
||||
{
|
||||
if (!battle_skill_stacks_masteries_vvs(bl, skill_id, BCHK_ALL))
|
||||
if (bl.type == BL_PC && !battle_skill_stacks_masteries_vvs(skill_id, BCHK_ALL))
|
||||
return 100;
|
||||
|
||||
int atkpercent = 100;
|
||||
@@ -4467,10 +4469,11 @@ static unsigned short battle_get_atkpercent(struct block_list& bl, uint16 skill_
|
||||
atkpercent += sc.getSCE(SC_BLOODLUST)->val2;
|
||||
if (sc.getSCE(SC_FLEET))
|
||||
atkpercent += sc.getSCE(SC_FLEET)->val3;
|
||||
if (sc.getSCE(SC_INVINCIBLE))
|
||||
atkpercent += sc.getSCE(SC_INVINCIBLE)->val2;
|
||||
|
||||
/* Only few selected skills should use this function, DO NOT ADD any that are not caused by the skills listed below
|
||||
* TODO:
|
||||
* NPC_INVINCIBLE (+100)
|
||||
* GD_GUARDUP (2*skLevel+8)
|
||||
* EL_WATERBARRIER (-3)
|
||||
* SC_ENERVATION (-30/-40/-50)
|
||||
@@ -6280,9 +6283,6 @@ static int64 battle_calc_skill_constant_addition(struct Damage* wd, struct block
|
||||
else
|
||||
atk = sstatus->matk_min;
|
||||
break;
|
||||
case NJ_SYURIKEN:
|
||||
atk = 4 * skill_lv;
|
||||
break;
|
||||
#endif
|
||||
#ifdef RENEWAL
|
||||
case HT_FREEZINGTRAP:
|
||||
@@ -6593,7 +6593,7 @@ static void battle_calc_defense_reduction(struct Damage* wd, struct block_list *
|
||||
#ifndef RENEWAL
|
||||
//Damage reduction: [VIT*0.3] + RND(0, [VIT^2/150] - [VIT*0.3] - 1) + [VIT*0.5]
|
||||
vit_def = ((3 * def2) / 10);
|
||||
vit_def += rnd_value(0, (def2 * def2) / 150 - ((3 * def2) / 10) - 1);
|
||||
vit_def += rnd_value(0, max(0, (def2 * def2) / 150 - ((3 * def2) / 10) - 1));
|
||||
vit_def += (def2 / 2);
|
||||
#else
|
||||
vit_def = def2;
|
||||
@@ -6635,7 +6635,9 @@ static void battle_calc_defense_reduction(struct Damage* wd, struct block_list *
|
||||
return;
|
||||
if (is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_R) || is_attack_piercing(wd, src, target, skill_id, skill_lv, EQI_HAND_L))
|
||||
return;
|
||||
|
||||
[[fallthrough]];
|
||||
case CR_GRANDCROSS: // Grand Cross is marked as "IgnoreDefense" in renewal as it's applied at the end after already combining ATK and MATK
|
||||
case NPC_GRANDDARKNESS:
|
||||
// Defense reduction by flat value.
|
||||
// This completely bypasses the normal RE DEF Reduction formula.
|
||||
wd->damage -= (def1 + vit_def);
|
||||
@@ -6693,7 +6695,7 @@ static void battle_calc_attack_post_defense(struct Damage* wd, struct block_list
|
||||
#ifndef RENEWAL
|
||||
//Refine bonus
|
||||
if (sd) {
|
||||
if (battle_skill_stacks_masteries_vvs(*src, skill_id, BCHK_REFINE)) {
|
||||
if (battle_skill_stacks_masteries_vvs(skill_id, BCHK_REFINE)) {
|
||||
ATK_ADD2(wd->damage, wd->damage2, sstatus->rhw.atk2, sstatus->lhw.atk2);
|
||||
}
|
||||
wd->basedamage += sstatus->rhw.atk2;
|
||||
@@ -6814,18 +6816,16 @@ static void battle_calc_attack_left_right_hands(struct Damage* wd, struct block_
|
||||
if (sd) {
|
||||
int skill;
|
||||
|
||||
if (!is_attack_right_handed(src, skill_id) && is_attack_left_handed(src, skill_id)) {
|
||||
wd->damage = wd->damage2;
|
||||
wd->damage2 = 0;
|
||||
} else if(sd->status.weapon == W_KATAR && !skill_id) { //Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2)
|
||||
if(sd->status.weapon == W_KATAR && !skill_id) { //Katars (offhand damage only applies to normal attacks, tested on Aegis 10.2)
|
||||
skill = pc_checkskill(sd,TF_DOUBLE);
|
||||
wd->damage2 = (int64)wd->damage * (1 + (skill * 2))/100;
|
||||
#ifdef RENEWAL
|
||||
} else if(is_attack_right_handed(src, skill_id) && is_attack_left_handed(src, skill_id) && sd->status.weapon != W_KATAR) { //Dual-wield
|
||||
} else if(is_attack_left_handed(src, skill_id) && sd->status.weapon != W_KATAR) { //Dual-wield
|
||||
#else
|
||||
} else if(is_attack_right_handed(src, skill_id) && is_attack_left_handed(src, skill_id)) { //Dual-wield
|
||||
} else if(is_attack_left_handed(src, skill_id)) { //Dual-wield
|
||||
#endif
|
||||
if (wd->damage) {
|
||||
// If you only have a weapon in the left hand, then your main hand damage will be identical to an unarmed attack
|
||||
if (is_attack_right_handed(src, skill_id) && wd->damage) {
|
||||
if( (sd->class_&MAPID_BASEMASK) == MAPID_THIEF ) {
|
||||
skill = pc_checkskill(sd,AS_RIGHT);
|
||||
ATK_RATER(wd->damage, 50 + (skill * 10))
|
||||
@@ -6837,6 +6837,7 @@ static void battle_calc_attack_left_right_hands(struct Damage* wd, struct block_
|
||||
if(wd->damage < 1)
|
||||
wd->damage = 1;
|
||||
}
|
||||
// Left hand damage will always be adjusted, even if you don't have a weapon in the main hand
|
||||
if (wd->damage2) {
|
||||
if( (sd->class_&MAPID_BASEMASK) == MAPID_THIEF) {
|
||||
skill = pc_checkskill(sd,AS_LEFT);
|
||||
@@ -6969,7 +6970,7 @@ static void battle_calc_weapon_final_atk_modifiers(struct Damage* wd, struct blo
|
||||
{
|
||||
ATK_RATER(wd->damage, 50)
|
||||
clif_skill_nodamage(target,target,ST_REJECTSWORD, tsc->getSCE(SC_REJECTSWORD)->val1,1);
|
||||
status_fix_damage(target,src,wd->damage,clif_damage(target,src,gettick(),0,0,wd->damage,0,DMG_NORMAL,0,false),ST_REJECTSWORD);
|
||||
battle_fix_damage(target,src,wd->damage,clif_damage(target,src,gettick(),0,0,wd->damage,0,DMG_NORMAL,0,false),ST_REJECTSWORD);
|
||||
if (status_isdead(target))
|
||||
return;
|
||||
if( --(tsc->getSCE(SC_REJECTSWORD)->val3) <= 0 )
|
||||
@@ -6987,7 +6988,7 @@ static void battle_calc_weapon_final_atk_modifiers(struct Damage* wd, struct blo
|
||||
clif_skill_damage(target, src, gettick(), status_get_amotion(src), 0, rdamage,
|
||||
1, SR_CRESCENTELBOW_AUTOSPELL, tsc->getSCE(SC_CRESCENTELBOW)->val1, DMG_SINGLE); // This is how official does
|
||||
clif_damage(src, target, gettick(), status_get_amotion(src)+1000, 0, rdamage/10, 1, DMG_NORMAL, 0, false);
|
||||
status_damage(target, src, rdamage, 0, 0, 0, 0);
|
||||
battle_fix_damage(target, src, rdamage, 0, SR_CRESCENTELBOW);
|
||||
status_damage(src, target, rdamage/10, 0, 0, 1, 0);
|
||||
status_change_end(target, SC_CRESCENTELBOW);
|
||||
}
|
||||
@@ -7066,10 +7067,12 @@ static struct Damage initialize_weapon_data(struct block_list *src, struct block
|
||||
wd.flag = BF_WEAPON; //Initial Flag
|
||||
wd.flag |= (skill_id||wd.miscflag)?BF_SKILL:BF_NORMAL; // Baphomet card's splash damage is counted as a skill. [Inkfish]
|
||||
wd.isspdamage = false;
|
||||
wd.damage = wd.damage2 = wd.basedamage =
|
||||
wd.damage = wd.damage2 =
|
||||
#ifdef RENEWAL
|
||||
wd.statusAtk = wd.statusAtk2 = wd.equipAtk = wd.equipAtk2 = wd.weaponAtk = wd.weaponAtk2 = wd.masteryAtk = wd.masteryAtk2 =
|
||||
wd.percentAtk = wd.percentAtk2 =
|
||||
#else
|
||||
wd.basedamage =
|
||||
#endif
|
||||
0;
|
||||
|
||||
@@ -7347,11 +7350,13 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
wd.dmg_lv = ATK_FLEE;
|
||||
else if(!(infdef = is_infinite_defense(target, wd.flag))) { //no need for math against plants
|
||||
|
||||
#ifndef RENEWAL
|
||||
// First call function with skill_id 0 to get base damage of a normal attack
|
||||
battle_calc_skill_base_damage(&wd, src, target, 0, 0); // base damage
|
||||
wd.basedamage = wd.damage;
|
||||
// Now get actual skill damage
|
||||
if (skill_id != 0)
|
||||
#endif
|
||||
battle_calc_skill_base_damage(&wd, src, target, skill_id, skill_lv); // base skill damage
|
||||
|
||||
int64 ratio = 0;
|
||||
@@ -7541,9 +7546,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
|
||||
battle_calc_element_damage(&wd, src, target, skill_id, skill_lv);
|
||||
|
||||
if(skill_id == CR_GRANDCROSS || skill_id == NPC_GRANDDARKNESS)
|
||||
return wd; //Enough, rest is not needed.
|
||||
|
||||
#ifdef RENEWAL
|
||||
if (is_attack_critical(&wd, src, target, skill_id, skill_lv, false)) {
|
||||
if (sd) { //Check for player so we don't crash out, monsters don't have bonus crit rates [helvetica]
|
||||
@@ -7559,11 +7561,6 @@ static struct Damage battle_calc_weapon_attack(struct block_list *src, struct bl
|
||||
#endif
|
||||
|
||||
switch (skill_id) {
|
||||
#ifndef RENEWAL
|
||||
case NJ_KUNAI:
|
||||
ATK_ADD(wd.damage, wd.damage2, 90);
|
||||
break;
|
||||
#endif
|
||||
case TK_DOWNKICK:
|
||||
case TK_STORMKICK:
|
||||
case TK_TURNKICK:
|
||||
@@ -7719,7 +7716,7 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
return ad;
|
||||
}
|
||||
//Initial Values
|
||||
ad.damage = 1;
|
||||
ad.damage = 0;
|
||||
ad.div_ = skill_get_num(skill_id,skill_lv);
|
||||
ad.amotion = (skill_get_inf(skill_id)&INF_GROUND_SKILL ? 0 : sstatus->amotion); //Amotion should be 0 for ground skills.
|
||||
ad.dmotion = tstatus->dmotion;
|
||||
@@ -8821,6 +8818,46 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
ad.damage = ad.damage * (100-mdef)/100 - mdef2;
|
||||
#endif
|
||||
}
|
||||
|
||||
//Apply the physical part of the skill's damage. [Skotlex]
|
||||
switch (skill_id) {
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS: {
|
||||
// Pre-re ATK = Take atk, apply def reduction and add refine bonus
|
||||
// Final Damage = (ATK+MATK)*RATIO
|
||||
// Renewal ATK = Take total atk
|
||||
// Final Damage = ((ATK+MATK)/2)*RATIO - (tDEF + tMDEF)
|
||||
// No need to go through the whole physical damage code
|
||||
struct Damage wd = initialize_weapon_data(src, target, skill_id, skill_lv, mflag);
|
||||
battle_calc_skill_base_damage(&wd, src, target, skill_id, skill_lv);
|
||||
// Calculate ATK
|
||||
#ifdef RENEWAL
|
||||
if (sd)
|
||||
wd.damage = wd.statusAtk + wd.weaponAtk + wd.equipAtk + wd.percentAtk;
|
||||
#else
|
||||
battle_calc_defense_reduction(&wd, src, target, skill_id, skill_lv);
|
||||
if (sd) {
|
||||
wd.damage += sstatus->rhw.atk2;
|
||||
}
|
||||
#endif
|
||||
// Combine ATK and MATK
|
||||
#ifdef RENEWAL
|
||||
ad.damage = (wd.damage + ad.damage) / 2;
|
||||
#else
|
||||
ad.damage = std::max((int64)1, wd.damage + ad.damage);
|
||||
#endif
|
||||
// Ratio
|
||||
skillratio += 40 * skill_lv;
|
||||
MATK_RATE(skillratio);
|
||||
#ifdef RENEWAL
|
||||
// Total defense reduction (renewal only)
|
||||
battle_calc_defense_reduction(&ad, src, target, skill_id, skill_lv);
|
||||
ad.damage -= (tstatus->mdef + tstatus->mdef2);
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if(ad.damage<1)
|
||||
ad.damage=1;
|
||||
else if(sc) { //only applies when hit
|
||||
@@ -8851,26 +8888,26 @@ struct Damage battle_calc_magic_attack(struct block_list *src,struct block_list
|
||||
if (!nk[NK_IGNOREELEMENT])
|
||||
ad.damage = battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
|
||||
|
||||
//Apply the physical part of the skill's damage. [Skotlex]
|
||||
switch(skill_id) {
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS: {
|
||||
struct Damage wd = battle_calc_weapon_attack(src,target,skill_id,skill_lv,mflag);
|
||||
|
||||
ad.damage = battle_attr_fix(src, target, wd.damage + ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv) * (100 + 40 * skill_lv) / 100;
|
||||
if(src == target) {
|
||||
if(src->type == BL_PC)
|
||||
ad.damage = ad.damage / 2;
|
||||
else
|
||||
ad.damage = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
#ifndef RENEWAL
|
||||
ad.damage += battle_calc_cardfix(BF_MAGIC, src, target, nk, s_ele, 0, ad.damage, 0, ad.flag);
|
||||
#endif
|
||||
|
||||
switch (skill_id) {
|
||||
case CR_GRANDCROSS:
|
||||
case NPC_GRANDDARKNESS:
|
||||
if (src == target) {
|
||||
// Grand Cross on self first applies attr_fix, then cardfix and finally halves the damage
|
||||
if (src->type == BL_PC)
|
||||
ad.damage = ad.damage / 2;
|
||||
else
|
||||
ad.damage = 0;
|
||||
}
|
||||
else
|
||||
// Grand Cross on target applies attr_fix, then cardfix and then attr_fix a second time
|
||||
ad.damage = battle_attr_fix(src, target, ad.damage, s_ele, tstatus->def_ele, tstatus->ele_lv);
|
||||
break;
|
||||
}
|
||||
|
||||
} //Hint: Against plants damage will still be 1 at this point
|
||||
|
||||
//Apply DAMAGE_DIV_FIX and check for min damage
|
||||
@@ -8949,7 +8986,10 @@ struct Damage battle_calc_misc_attack(struct block_list *src,struct block_list *
|
||||
|
||||
switch (skill_id) {
|
||||
case TF_THROWSTONE:
|
||||
md.damage = 50;
|
||||
if (sd)
|
||||
md.damage = 50;
|
||||
else
|
||||
md.damage = 30;
|
||||
md.flag |= BF_WEAPON;
|
||||
break;
|
||||
case NPC_KILLING_AURA:
|
||||
@@ -9489,6 +9529,36 @@ int64 battle_calc_return_damage(struct block_list* tbl, struct block_list *src,
|
||||
return cap_value(rdamage, 1, status_get_max_hp(tbl));
|
||||
}
|
||||
|
||||
/** Check for Coma damage
|
||||
* @param sd: Source player
|
||||
* @param bl: Target
|
||||
* @param attack_type: Attack type
|
||||
* @return True if Coma applies, false if Coma does not apply
|
||||
*/
|
||||
bool battle_check_coma(map_session_data& sd, struct block_list& target, e_battle_flag attack_type)
|
||||
{
|
||||
struct status_data* tstatus = status_get_status_data(&target);
|
||||
mob_data* dstmd = BL_CAST(BL_MOB, &target);
|
||||
|
||||
// Coma
|
||||
if (sd.special_state.bonus_coma && (!dstmd || (!util::vector_exists(status_get_race2(&dstmd->bl), RC2_GVG) && status_get_class(&dstmd->bl) != CLASS_BATTLEFIELD))) {
|
||||
int rate = 0;
|
||||
rate += sd.indexed_bonus.coma_class[tstatus->class_] + sd.indexed_bonus.coma_class[CLASS_ALL];
|
||||
if(!status_bl_has_mode(&target, MD_STATUSIMMUNE))
|
||||
rate += sd.indexed_bonus.coma_race[tstatus->race] + sd.indexed_bonus.coma_race[RC_ALL];
|
||||
if (attack_type&BF_WEAPON) {
|
||||
rate += sd.indexed_bonus.weapon_coma_class[tstatus->class_] + sd.indexed_bonus.weapon_coma_class[CLASS_ALL];
|
||||
if (!status_bl_has_mode(&target, MD_STATUSIMMUNE)) {
|
||||
rate += sd.indexed_bonus.weapon_coma_ele[tstatus->def_ele] + sd.indexed_bonus.weapon_coma_ele[ELE_ALL];
|
||||
rate += sd.indexed_bonus.weapon_coma_race[tstatus->race] + sd.indexed_bonus.weapon_coma_race[RC_ALL];
|
||||
}
|
||||
}
|
||||
if (rate > 0 && rnd_chance(rate, 10000))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculate Vellum damage on a target
|
||||
* @param sd: Player with vanish item
|
||||
@@ -9623,7 +9693,7 @@ int battle_damage_area(struct block_list *bl, va_list ap) {
|
||||
if( amotion )
|
||||
battle_delay_damage(tick, amotion,src,bl,0,CR_REFLECTSHIELD,0,damage,ATK_DEF,0,true,false);
|
||||
else
|
||||
status_fix_damage(src,bl,damage,0,LG_REFLECTDAMAGE);
|
||||
battle_fix_damage(src,bl,damage,0,LG_REFLECTDAMAGE);
|
||||
clif_damage(bl,bl,tick,amotion,dmotion,damage,1,DMG_ENDURE,0,false);
|
||||
skill_additional_effect(src, bl, CR_REFLECTSHIELD, 1, BF_WEAPON|BF_SHORT|BF_NORMAL,ATK_DEF,tick);
|
||||
map_freeblock_unlock();
|
||||
@@ -9716,7 +9786,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
short index = sd->equip_index[EQI_AMMO];
|
||||
if (index < 0) {
|
||||
if (sd->weapontype1 > W_KATAR && sd->weapontype1 < W_HUUMA)
|
||||
clif_skill_fail(sd,0,USESKILL_FAIL_NEED_MORE_BULLET,0);
|
||||
clif_skill_fail( *sd, 0, USESKILL_FAIL_NEED_MORE_BULLET );
|
||||
else
|
||||
clif_arrow_fail(sd,0);
|
||||
return ATK_NONE;
|
||||
@@ -9735,7 +9805,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
case W_GATLING:
|
||||
case W_SHOTGUN:
|
||||
if (sd->inventory_data[index]->subtype != AMMO_BULLET) {
|
||||
clif_skill_fail(sd,0,USESKILL_FAIL_NEED_MORE_BULLET,0);
|
||||
clif_skill_fail( *sd, 0, USESKILL_FAIL_NEED_MORE_BULLET );
|
||||
return ATK_NONE;
|
||||
}
|
||||
break;
|
||||
@@ -9746,7 +9816,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
#else
|
||||
AMMO_GRENADE) {
|
||||
#endif
|
||||
clif_skill_fail(sd,0,USESKILL_FAIL_NEED_MORE_BULLET,0);
|
||||
clif_skill_fail( *sd, 0, USESKILL_FAIL_NEED_MORE_BULLET );
|
||||
return ATK_NONE;
|
||||
}
|
||||
break;
|
||||
@@ -9990,7 +10060,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
devotion_damage -= devotion_damage * d_sc->getSCE(SC_REBOUND_S)->val2 / 100;
|
||||
|
||||
clif_damage(d_bl, d_bl, gettick(), wd.amotion, wd.dmotion, devotion_damage, 1, DMG_NORMAL, 0, false);
|
||||
status_fix_damage(NULL, d_bl, devotion_damage, 0, CR_DEVOTION);
|
||||
battle_fix_damage(src, d_bl, devotion_damage, 0, CR_DEVOTION);
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -10009,7 +10079,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
|
||||
if (e_bl && !status_isdead(e_bl)) {
|
||||
clif_damage(e_bl, e_bl, tick, 0, 0, damage, wd.div_, DMG_NORMAL, 0, false);
|
||||
status_fix_damage(NULL, e_bl, damage, 0, EL_WATER_SCREEN);
|
||||
battle_fix_damage(src, e_bl, damage, 0, EL_WATER_SCREEN);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10081,7 +10151,7 @@ enum damage_lv battle_weapon_attack(struct block_list* src, struct block_list* t
|
||||
}
|
||||
|
||||
if( type != CAST_GROUND ){
|
||||
clif_skill_fail(sd,r_skill,USESKILL_FAIL_LEVEL,0);
|
||||
clif_skill_fail( *sd, r_skill );
|
||||
map_freeblock_unlock();
|
||||
return wd.dmg_lv;
|
||||
}
|
||||
@@ -11077,7 +11147,7 @@ static const struct _battle_data {
|
||||
{ "skill_steal_random_options", &battle_config.skill_steal_random_options, 0, 0, 1, },
|
||||
{ "motd_type", &battle_config.motd_type, 0, 0, 1, },
|
||||
{ "finding_ore_rate", &battle_config.finding_ore_rate, 100, 0, INT_MAX, },
|
||||
{ "exp_calc_type", &battle_config.exp_calc_type, 0, 0, 1, },
|
||||
{ "exp_calc_type", &battle_config.exp_calc_type, 0, 0, 2, },
|
||||
{ "exp_bonus_attacker", &battle_config.exp_bonus_attacker, 25, 0, INT_MAX, },
|
||||
{ "exp_bonus_max_attacker", &battle_config.exp_bonus_max_attacker, 12, 2, INT_MAX, },
|
||||
{ "min_skill_delay_limit", &battle_config.min_skill_delay_limit, 100, 10, INT_MAX, },
|
||||
@@ -11135,8 +11205,8 @@ static const struct _battle_data {
|
||||
{ "day_duration", &battle_config.day_duration, 0, 0, INT_MAX, },
|
||||
{ "night_duration", &battle_config.night_duration, 0, 0, INT_MAX, },
|
||||
{ "mob_remove_delay", &battle_config.mob_remove_delay, 60000, 1000, INT_MAX, },
|
||||
{ "mob_active_time", &battle_config.mob_active_time, 0, 0, INT_MAX, },
|
||||
{ "boss_active_time", &battle_config.boss_active_time, 0, 0, INT_MAX, },
|
||||
{ "mob_active_time", &battle_config.mob_active_time, 5000, 0, INT_MAX, },
|
||||
{ "boss_active_time", &battle_config.boss_active_time, 5000, 0, INT_MAX, },
|
||||
{ "sg_miracle_skill_duration", &battle_config.sg_miracle_skill_duration, 3600000, 0, INT_MAX, },
|
||||
{ "hvan_explosion_intimate", &battle_config.hvan_explosion_intimate, 45000, 0, 100000, },
|
||||
{ "quest_exp_rate", &battle_config.quest_exp_rate, 100, 0, INT_MAX, },
|
||||
@@ -11386,6 +11456,7 @@ static const struct _battle_data {
|
||||
{ "feature.dynamicnpc_direction", &battle_config.feature_dynamicnpc_direction, 0, 0, 1, },
|
||||
|
||||
{ "mob_respawn_time", &battle_config.mob_respawn_time, 1000, 1000, INT_MAX, },
|
||||
{ "mob_unlock_time", &battle_config.mob_unlock_time, 2000, 0, INT_MAX, },
|
||||
|
||||
{ "feature.stylist", &battle_config.feature_stylist, 1, 0, 1, },
|
||||
{ "feature.banking_state_enforce", &battle_config.feature_banking_state_enforce, 0, 0, 1, },
|
||||
|
||||
@@ -37,7 +37,6 @@ enum e_base_damage_flag : uint16 {
|
||||
BDMG_ARROW = 0x0002, /// Add arrow attack and use ranged damage formula
|
||||
BDMG_MAGIC = 0x0004, /// Use MATK for base damage (e.g. Magic Crasher)
|
||||
BDMG_NOSIZE = 0x0008, /// Skip target size adjustment (e.g. Weapon Perfection)
|
||||
BDMG_THROW = 0x0010, /// Arrow attack should use melee damage formula (e.g., shuriken, kunai and venom knives)
|
||||
};
|
||||
|
||||
/// Flag of the final calculation
|
||||
@@ -90,10 +89,11 @@ enum e_bonus_chk_flag : uint8 {
|
||||
struct Damage {
|
||||
#ifdef RENEWAL
|
||||
int64 statusAtk, statusAtk2, weaponAtk, weaponAtk2, equipAtk, equipAtk2, masteryAtk, masteryAtk2, percentAtk, percentAtk2;
|
||||
#else
|
||||
int64 basedamage; /// Right hand damage that a normal attack would deal
|
||||
#endif
|
||||
int64 damage, /// Right hand damage
|
||||
damage2, /// Left hand damage
|
||||
basedamage; /// Right hand damage that a normal attack would deal
|
||||
damage2; /// Left hand damage
|
||||
enum e_damage_type type; /// Check clif_damage for type
|
||||
short div_; /// Number of hit
|
||||
int amotion,
|
||||
@@ -122,8 +122,9 @@ int64 battle_calc_gvg_damage(struct block_list *src,struct block_list *bl,int64
|
||||
int64 battle_calc_bg_damage(struct block_list *src,struct block_list *bl,int64 damage,uint16 skill_id,int flag);
|
||||
int64 battle_calc_pk_damage(block_list &src, block_list &bl, int64 damage, uint16 skill_id, int flag);
|
||||
|
||||
void battle_damage(struct block_list *src, struct block_list *target, int64 damage, t_tick delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, t_tick tick, bool spdamage);
|
||||
int battle_damage(struct block_list *src, struct block_list *target, int64 damage, t_tick delay, uint16 skill_lv, uint16 skill_id, enum damage_lv dmg_lv, unsigned short attack_type, bool additional_effects, t_tick tick, bool spdamage);
|
||||
int battle_delay_damage (t_tick tick, int amotion, struct block_list *src, struct block_list *target, int attack_type, uint16 skill_id, uint16 skill_lv, int64 damage, enum damage_lv dmg_lv, t_tick ddelay, bool additional_effects, bool spdamage);
|
||||
int battle_fix_damage(struct block_list* src, struct block_list* target, int64 damage, t_tick walkdelay, uint16 skill_id);
|
||||
|
||||
int battle_calc_chorusbonus(map_session_data *sd);
|
||||
|
||||
@@ -140,6 +141,7 @@ uint16 battle_getcurrentskill(struct block_list *bl);
|
||||
int battle_check_undead(int race,int element);
|
||||
int battle_check_target(struct block_list *src, struct block_list *target,int flag);
|
||||
bool battle_check_range(struct block_list *src,struct block_list *bl,int range);
|
||||
bool battle_check_coma(map_session_data& sd, struct block_list& target, e_battle_flag attack_type);
|
||||
|
||||
void battle_consume_ammo(map_session_data* sd, int skill, int lv);
|
||||
|
||||
@@ -746,6 +748,7 @@ struct Battle_Config
|
||||
int feature_dynamicnpc_direction;
|
||||
|
||||
int mob_respawn_time;
|
||||
int mob_unlock_time;
|
||||
|
||||
int feature_stylist;
|
||||
int feature_banking_state_enforce;
|
||||
|
||||
@@ -720,7 +720,7 @@ int bg_team_get_id(struct block_list *bl)
|
||||
* @param mes: Message
|
||||
* @param len: Message length
|
||||
*/
|
||||
void bg_send_message(map_session_data *sd, const char *mes, int len)
|
||||
void bg_send_message(map_session_data *sd, const char *mes, size_t len)
|
||||
{
|
||||
nullpo_retv(sd);
|
||||
|
||||
|
||||
@@ -153,7 +153,7 @@ bool bg_queue_on_ready(const char *name, std::shared_ptr<s_battleground_queue> q
|
||||
void bg_queue_on_accept_invite(map_session_data *sd);
|
||||
void bg_queue_start_battleground(std::shared_ptr<s_battleground_queue> queue);
|
||||
bool bg_member_respawn(map_session_data *sd);
|
||||
void bg_send_message(map_session_data *sd, const char *mes, int len);
|
||||
void bg_send_message(map_session_data *sd, const char *mes, size_t len);
|
||||
|
||||
void do_init_battleground(void);
|
||||
void do_final_battleground(void);
|
||||
|
||||
916
src/map/clif.cpp
916
src/map/clif.cpp
File diff suppressed because it is too large
Load Diff
@@ -702,7 +702,7 @@ void clif_divorced(map_session_data* sd, const char* name);
|
||||
void clif_callpartner(map_session_data& sd);
|
||||
void clif_playBGM( map_session_data& sd, const char* name );
|
||||
void clif_soundeffect( struct block_list& bl, const char* name, int type, enum send_target target );
|
||||
void clif_parse_ActionRequest_sub(map_session_data *sd, int action_type, int target_id, t_tick tick);
|
||||
void clif_parse_ActionRequest_sub( map_session_data& sd, int action_type, int target_id, t_tick tick );
|
||||
void clif_parse_LoadEndAck(int fd,map_session_data *sd);
|
||||
void clif_hotkeys_send(map_session_data *sd, int tab);
|
||||
|
||||
@@ -738,7 +738,7 @@ void clif_deleteskill(map_session_data *sd, int skill_id, bool skip_infoblock =
|
||||
|
||||
void clif_skillcasting(struct block_list* bl, int src_id, int dst_id, int dst_x, int dst_y, uint16 skill_id, uint16 skill_lv, int property, int casttime);
|
||||
void clif_skillcastcancel(struct block_list* bl);
|
||||
void clif_skill_fail(map_session_data *sd,uint16 skill_id,enum useskill_fail_cause cause,int btype, t_itemid itemId = 0);
|
||||
void clif_skill_fail( map_session_data& sd, uint16 skill_id, enum useskill_fail_cause cause = USESKILL_FAIL_LEVEL, int btype = 0, t_itemid itemId = 0 );
|
||||
void clif_skill_cooldown(map_session_data *sd, uint16 skill_id, t_tick tick);
|
||||
int clif_skill_damage(struct block_list *src,struct block_list *dst,t_tick tick,int sdelay,int ddelay,int64 sdamage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type);
|
||||
//int clif_skill_damage2(struct block_list *src,struct block_list *dst,t_tick tick,int sdelay,int ddelay,int damage,int div,uint16 skill_id,uint16 skill_lv,enum e_damage_type type);
|
||||
@@ -774,7 +774,7 @@ void clif_status_change(struct block_list *bl, int type, int flag, t_tick tick,
|
||||
void clif_efst_status_change(struct block_list *bl, int tid, enum send_target target, int type, t_tick tick, int val1, int val2, int val3);
|
||||
void clif_efst_status_change_sub(struct block_list *tbl, struct block_list *bl, enum send_target target);
|
||||
|
||||
void clif_wis_message(map_session_data* sd, const char* nick, const char* mes, int mes_len, int gmlvl);
|
||||
void clif_wis_message(map_session_data* sd, const char* nick, const char* mes, size_t mes_len, int gmlvl);
|
||||
void clif_wis_end(int fd, int result);
|
||||
|
||||
void clif_solved_charname(int fd, int charid, const char* name);
|
||||
@@ -796,7 +796,7 @@ void clif_clearcart(int fd);
|
||||
|
||||
void clif_item_identify_list(map_session_data *sd);
|
||||
void clif_item_identified(map_session_data *sd,int idx,int flag);
|
||||
void clif_item_repair_list(map_session_data *sd, map_session_data *dstsd, int lv);
|
||||
void clif_item_repair_list( map_session_data& sd, map_session_data& dstsd, uint16 lv );
|
||||
void clif_item_repaireffect(map_session_data *sd, int idx, int flag);
|
||||
void clif_item_damaged(map_session_data* sd, unsigned short position);
|
||||
void clif_item_refine_list(map_session_data *sd);
|
||||
@@ -830,7 +830,7 @@ void clif_party_invite( map_session_data& sd, map_session_data& tsd );
|
||||
void clif_party_invite_reply( map_session_data& sd, const char* nick, enum e_party_invite_reply reply );
|
||||
void clif_party_option(struct party_data *p,map_session_data *sd,int flag);
|
||||
void clif_party_withdraw( map_session_data& sd, uint32 account_id, const char* name, enum e_party_member_withdraw result, enum send_target target );
|
||||
void clif_party_message( struct party_data& party, uint32 account_id, const char* mes, int len );
|
||||
void clif_party_message( struct party_data& party, uint32 account_id, const char* mes, size_t len );
|
||||
void clif_party_xy( map_session_data& sd );
|
||||
void clif_party_xy_single( map_session_data& sd, map_session_data& tsd );
|
||||
void clif_party_hp( map_session_data& sd );
|
||||
@@ -874,7 +874,7 @@ void clif_guild_castle_teleport_res(map_session_data& sd, enum e_siege_teleport_
|
||||
void clif_bg_hp(map_session_data *sd);
|
||||
void clif_bg_xy(map_session_data *sd);
|
||||
void clif_bg_xy_remove(map_session_data *sd);
|
||||
void clif_bg_message(struct s_battleground_data *bg, int src_id, const char *name, const char *mes, int len);
|
||||
void clif_bg_message(struct s_battleground_data *bg, int src_id, const char *name, const char *mes, size_t len);
|
||||
void clif_bg_updatescore(int16 m);
|
||||
void clif_bg_updatescore_single(map_session_data *sd);
|
||||
void clif_sendbgemblem_area(map_session_data *sd);
|
||||
@@ -900,9 +900,9 @@ void clif_font(map_session_data *sd);
|
||||
|
||||
// atcommand
|
||||
void clif_displaymessage(const int fd, const char* mes);
|
||||
void clif_disp_message(struct block_list* src, const char* mes, int len, enum send_target target);
|
||||
void clif_broadcast(struct block_list* bl, const char* mes, int len, int type, enum send_target target);
|
||||
void clif_broadcast2(struct block_list* bl, const char* mes, int len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target);
|
||||
void clif_disp_message(struct block_list* src, const char* mes, size_t len, enum send_target target);
|
||||
void clif_broadcast(struct block_list* bl, const char* mes, size_t len, int type, enum send_target target);
|
||||
void clif_broadcast2(struct block_list* bl, const char* mes, size_t len, unsigned long fontColor, short fontType, short fontSize, short fontAlign, short fontY, enum send_target target);
|
||||
void clif_heal(int fd,int type,int val);
|
||||
void clif_resurrection(struct block_list *bl,int type);
|
||||
void clif_map_property(struct block_list *bl, enum map_property property, enum send_target t);
|
||||
@@ -1094,11 +1094,11 @@ void clif_elementalconverter_list(map_session_data *sd);
|
||||
|
||||
void clif_millenniumshield(struct block_list *bl, short shields);
|
||||
|
||||
void clif_magicdecoy_list(map_session_data *sd, uint16 skill_lv, short x, short y);
|
||||
void clif_magicdecoy_list( map_session_data& sd, uint16 skill_lv, short x, short y );
|
||||
|
||||
void clif_poison_list(map_session_data *sd, uint16 skill_lv);
|
||||
void clif_poison_list( map_session_data& sd, uint16 skill_lv );
|
||||
|
||||
int clif_autoshadowspell_list(map_session_data *sd);
|
||||
void clif_autoshadowspell_list( map_session_data& sd );
|
||||
|
||||
int clif_skill_itemlistwindow( map_session_data *sd, uint16 skill_id, uint16 skill_lv );
|
||||
void clif_elemental_info(map_session_data *sd);
|
||||
|
||||
@@ -57,7 +57,6 @@
|
||||
packet(0x0093,2);
|
||||
parseable_packet(0x0094,6,clif_parse_GetCharNameRequest,2);
|
||||
parseable_packet(0x0096,-1,clif_parse_WisMessage,2,4,28);
|
||||
packet(0x0097,-1);
|
||||
packet(0x0098,3);
|
||||
parseable_packet(0x0099,-1,clif_parse_Broadcast,2,4);
|
||||
packet(0x009a,-1);
|
||||
@@ -1334,7 +1333,6 @@
|
||||
|
||||
// 2008-12-10aSakexe
|
||||
#if PACKETVER >= 20081210
|
||||
packet(0x0442,-1);
|
||||
parseable_packet(0x0443,8,clif_parse_SkillSelectMenu,2,6);
|
||||
#endif
|
||||
|
||||
@@ -1412,7 +1410,6 @@
|
||||
packet(0x01a2,37);
|
||||
//packet(0x0440,10);
|
||||
//packet(0x0441,4);
|
||||
//packet(0x0442,8);
|
||||
//packet(0x0443,8);
|
||||
#endif
|
||||
|
||||
@@ -2041,11 +2038,11 @@
|
||||
|
||||
// 2013-07-17Ragexe
|
||||
#if PACKETVER >= 20130717
|
||||
parseable_packet(0x09A7,10,clif_parse_BankDeposit,2,6);
|
||||
parseable_packet(0x09A9,10,clif_parse_BankWithdraw,2,6);
|
||||
parseable_packet(0x09AB,6,clif_parse_BankCheck,2);
|
||||
parseable_packet(0x09B6,6,clif_parse_BankOpen,2);
|
||||
parseable_packet(0x09B8,6,clif_parse_BankClose,2);
|
||||
parseable_packet( HEADER_CZ_REQ_BANKING_DEPOSIT, sizeof( PACKET_CZ_REQ_BANKING_DEPOSIT ), clif_parse_BankDeposit, 0 );
|
||||
parseable_packet( HEADER_CZ_REQ_BANKING_WITHDRAW, sizeof( PACKET_CZ_REQ_BANKING_WITHDRAW ), clif_parse_BankWithdraw, 0 );
|
||||
parseable_packet( HEADER_CZ_REQ_BANKING_CHECK, sizeof( PACKET_CZ_REQ_BANKING_CHECK ), clif_parse_BankCheck, 0 );
|
||||
parseable_packet( HEADER_CZ_REQ_OPEN_BANKING, sizeof( PACKET_CZ_REQ_OPEN_BANKING ), clif_parse_BankOpen, 0 );
|
||||
parseable_packet( HEADER_CZ_REQ_CLOSE_BANKING, sizeof( PACKET_CZ_REQ_CLOSE_BANKING ), clif_parse_BankClose, 0 );
|
||||
#endif
|
||||
|
||||
// 2013-07-31cRagexe
|
||||
|
||||
@@ -316,7 +316,7 @@ int elemental_action(s_elemental_data *ed, block_list *bl, t_tick tick) {
|
||||
uint16 skill_id = skill->id;
|
||||
uint16 skill_lv = skill->lv;
|
||||
|
||||
if( elemental_skillnotok(skill_id, ed) )
|
||||
if( elemental_skillnotok(skill_id, *ed) )
|
||||
return 0;
|
||||
|
||||
if( ed->ud.skilltimer != INVALID_TIMER )
|
||||
@@ -389,7 +389,7 @@ int elemental_change_mode_ack(s_elemental_data *ed, e_elemental_skillmode skill_
|
||||
uint16 skill_id = skill->id;
|
||||
uint16 skill_lv = skill->lv;
|
||||
|
||||
if( elemental_skillnotok(skill_id, ed) )
|
||||
if( elemental_skillnotok(skill_id, *ed) )
|
||||
return 0;
|
||||
|
||||
if( ed->ud.skilltimer != INVALID_TIMER )
|
||||
@@ -460,10 +460,19 @@ int elemental_unlocktarget(s_elemental_data *ed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool elemental_skillnotok(uint16 skill_id, s_elemental_data *ed) {
|
||||
bool elemental_skillnotok( uint16 skill_id, s_elemental_data& ed ){
|
||||
uint16 idx = skill_get_index(skill_id);
|
||||
nullpo_retr(1,ed);
|
||||
return idx == 0 ? false : skill_isNotOk(skill_id,ed->master); // return false or check if it,s ok for master as well
|
||||
|
||||
if( idx == 0 ){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if it's ok for master as well
|
||||
if( ed.master != nullptr ){
|
||||
return skill_isNotOk( skill_id, *ed.master );
|
||||
}else{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
struct s_skill_condition elemental_skill_get_requirements(uint16 skill_id, uint16 skill_lv){
|
||||
|
||||
@@ -123,7 +123,7 @@ void elemental_summon_stop(s_elemental_data *ed);
|
||||
t_tick elemental_get_lifetime(s_elemental_data *ed);
|
||||
|
||||
int elemental_unlocktarget(s_elemental_data *ed);
|
||||
bool elemental_skillnotok(uint16 skill_id, s_elemental_data *ed);
|
||||
bool elemental_skillnotok( uint16 skill_id, s_elemental_data& ed );
|
||||
int elemental_set_target( map_session_data *sd, block_list *bl );
|
||||
int elemental_clean_effect(s_elemental_data *ed);
|
||||
int elemental_action(s_elemental_data *ed, block_list *bl, t_tick tick);
|
||||
|
||||
@@ -1370,7 +1370,7 @@ int guild_recv_memberinfoshort(int guild_id,uint32 account_id,uint32 char_id,int
|
||||
/*====================================================
|
||||
* Send a message to whole guild
|
||||
*---------------------------------------------------*/
|
||||
int guild_send_message(map_session_data *sd,const char *mes,int len) {
|
||||
int guild_send_message(map_session_data *sd, const char *mes, size_t len) {
|
||||
nullpo_ret(sd);
|
||||
|
||||
if(sd->status.guild_id==0)
|
||||
@@ -1481,13 +1481,11 @@ int guild_notice_changed(int guild_id,const char *mes1,const char *mes2) {
|
||||
/*====================================================
|
||||
* Check condition for changing guild emblem
|
||||
*---------------------------------------------------*/
|
||||
bool guild_check_emblem_change_condition(map_session_data *sd)
|
||||
{
|
||||
nullpo_ret(sd);
|
||||
auto &g = sd->guild;
|
||||
bool guild_check_emblem_change_condition( map_session_data& sd ){
|
||||
auto &g = sd.guild;
|
||||
|
||||
if (battle_config.require_glory_guild && g != nullptr && guild_checkskill(g->guild, GD_GLORYGUILD) > 0) {
|
||||
clif_skill_fail(sd, GD_GLORYGUILD, USESKILL_FAIL_LEVEL, 0);
|
||||
clif_skill_fail( sd, GD_GLORYGUILD );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1497,28 +1495,23 @@ bool guild_check_emblem_change_condition(map_session_data *sd)
|
||||
/*====================================================
|
||||
* Change guild emblem
|
||||
*---------------------------------------------------*/
|
||||
int guild_change_emblem(map_session_data *sd,int len,const char *data) {
|
||||
nullpo_ret(sd);
|
||||
|
||||
int guild_change_emblem( map_session_data& sd, int len, const char* data ){
|
||||
if (!guild_check_emblem_change_condition(sd)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return intif_guild_emblem(sd->status.guild_id,len,data);
|
||||
return intif_guild_emblem( sd.status.guild_id, len, data );
|
||||
}
|
||||
|
||||
/*====================================================
|
||||
* Change guild emblem version
|
||||
*---------------------------------------------------*/
|
||||
int guild_change_emblem_version(map_session_data* sd, int version)
|
||||
{
|
||||
nullpo_ret(sd);
|
||||
|
||||
int guild_change_emblem_version( map_session_data& sd, int version ){
|
||||
if (!guild_check_emblem_change_condition(sd)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
return intif_guild_emblem_version(sd->status.guild_id, version);
|
||||
return intif_guild_emblem_version( sd.status.guild_id, version );
|
||||
}
|
||||
|
||||
/*====================================================
|
||||
|
||||
@@ -87,10 +87,10 @@ int guild_change_position(int guild_id,int idx,int mode,int exp_mode,const char
|
||||
int guild_position_changed(int guild_id,int idx,struct guild_position *p);
|
||||
int guild_change_notice(map_session_data *sd,int guild_id,const char *mes1,const char *mes2);
|
||||
int guild_notice_changed(int guild_id,const char *mes1,const char *mes2);
|
||||
int guild_change_emblem(map_session_data *sd,int len,const char *data);
|
||||
int guild_change_emblem_version(map_session_data* sd, int version);
|
||||
int guild_change_emblem( map_session_data& sd, int len, const char* data );
|
||||
int guild_change_emblem_version( map_session_data& sd, int version );
|
||||
int guild_emblem_changed(int len,int guild_id,int emblem_id,const char *data);
|
||||
int guild_send_message(map_session_data *sd,const char *mes,int len);
|
||||
int guild_send_message(map_session_data *sd, const char *mes, size_t len);
|
||||
int guild_recv_message(int guild_id,uint32 account_id,const char *mes,int len);
|
||||
int guild_send_dot_remove(map_session_data *sd);
|
||||
int guild_skillupack(int guild_id,uint16 skill_id,uint32 account_id);
|
||||
|
||||
@@ -310,7 +310,7 @@ int intif_main_message(map_session_data* sd, const char* message)
|
||||
* @param mes_len : Size of message
|
||||
* @return 0=Message not send, 1=Message send
|
||||
*/
|
||||
int intif_wis_message(map_session_data *sd, char *nick, char *mes, int mes_len)
|
||||
int intif_wis_message(map_session_data *sd, char *nick, char *mes, size_t mes_len)
|
||||
{
|
||||
int headersize = 8 + 2 * NAME_LENGTH;
|
||||
|
||||
@@ -326,7 +326,7 @@ int intif_wis_message(map_session_data *sd, char *nick, char *mes, int mes_len)
|
||||
|
||||
WFIFOHEAD(inter_fd,mes_len + headersize);
|
||||
WFIFOW(inter_fd,0) = 0x3001;
|
||||
WFIFOW(inter_fd,2) = mes_len + headersize;
|
||||
WFIFOW(inter_fd,2) = static_cast<int16>( mes_len + headersize);
|
||||
WFIFOL(inter_fd,4) = pc_get_group_level(sd);
|
||||
safestrncpy(WFIFOCP(inter_fd,8), sd->status.name, NAME_LENGTH);
|
||||
safestrncpy(WFIFOCP(inter_fd,8+NAME_LENGTH), nick, NAME_LENGTH);
|
||||
@@ -748,7 +748,7 @@ int intif_break_party(int party_id)
|
||||
* @param len : Size of the message
|
||||
* @return 0=error, 1=msg sent
|
||||
*/
|
||||
int intif_party_message(int party_id,uint32 account_id,const char *mes,int len)
|
||||
int intif_party_message(int party_id, uint32 account_id, const char *mes, size_t len)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
@@ -758,7 +758,7 @@ int intif_party_message(int party_id,uint32 account_id,const char *mes,int len)
|
||||
|
||||
WFIFOHEAD(inter_fd,len + 12);
|
||||
WFIFOW(inter_fd,0)=0x3027;
|
||||
WFIFOW(inter_fd,2)=len+12;
|
||||
WFIFOW(inter_fd,2)=static_cast<int16>( len + 12 );
|
||||
WFIFOL(inter_fd,4)=party_id;
|
||||
WFIFOL(inter_fd,8)=account_id;
|
||||
safestrncpy(WFIFOCP(inter_fd,12),mes,len);
|
||||
@@ -954,7 +954,7 @@ int intif_guild_break(int guild_id)
|
||||
* @param len : Size of the message
|
||||
* @return 0=error, 1=msg_sent
|
||||
*/
|
||||
int intif_guild_message(int guild_id,uint32 account_id,const char *mes,int len)
|
||||
int intif_guild_message(int guild_id, uint32 account_id, const char *mes, size_t len)
|
||||
{
|
||||
if (CheckForCharServer())
|
||||
return 0;
|
||||
@@ -964,7 +964,7 @@ int intif_guild_message(int guild_id,uint32 account_id,const char *mes,int len)
|
||||
|
||||
WFIFOHEAD(inter_fd, len + 12);
|
||||
WFIFOW(inter_fd,0)=0x3037;
|
||||
WFIFOW(inter_fd,2)=len+12;
|
||||
WFIFOW(inter_fd,2)=static_cast<int16>( len + 12 );
|
||||
WFIFOL(inter_fd,4)=guild_id;
|
||||
WFIFOL(inter_fd,8)=account_id;
|
||||
safestrncpy(WFIFOCP(inter_fd,12),mes,len);
|
||||
|
||||
@@ -29,7 +29,7 @@ int intif_broadcast_obtain_special_item(map_session_data *sd, t_itemid nameid, u
|
||||
int intif_broadcast_obtain_special_item_npc(map_session_data *sd, t_itemid nameid);
|
||||
int intif_main_message(map_session_data* sd, const char* message);
|
||||
|
||||
int intif_wis_message(map_session_data *sd,char *nick,char *mes,int mes_len);
|
||||
int intif_wis_message(map_session_data *sd, char *nick, char *mes, size_t mes_len);
|
||||
int intif_wis_message_to_gm(char *Wisp_name, int permission, char *mes);
|
||||
|
||||
int intif_saveregistry(map_session_data *sd);
|
||||
@@ -46,7 +46,7 @@ int intif_party_changeoption(int party_id, uint32 account_id, int exp, int item)
|
||||
int intif_party_leave(int party_id, uint32 account_id, uint32 char_id, const char *name, enum e_party_member_withdraw type);
|
||||
int intif_party_changemap(map_session_data *sd, int online);
|
||||
int intif_break_party(int party_id);
|
||||
int intif_party_message(int party_id, uint32 account_id, const char *mes,int len);
|
||||
int intif_party_message(int party_id, uint32 account_id, const char *mes, size_t len);
|
||||
int intif_party_leaderchange(int party_id,uint32 account_id,uint32 char_id);
|
||||
int intif_party_sharelvlupdate(unsigned int share_lvl);
|
||||
|
||||
@@ -56,7 +56,7 @@ int intif_guild_addmember(int guild_id, struct guild_member *m);
|
||||
int intif_guild_leave(int guild_id, uint32 account_id, uint32 char_id, int flag, const char *mes);
|
||||
int intif_guild_memberinfoshort(int guild_id, uint32 account_id, uint32 char_id, int online, int lv, int class_);
|
||||
int intif_guild_break(int guild_id);
|
||||
int intif_guild_message(int guild_id, uint32 account_id, const char *mes, int len);
|
||||
int intif_guild_message(int guild_id, uint32 account_id, const char *mes, size_t len);
|
||||
int intif_guild_change_gm(int guild_id, const char* name, int len);
|
||||
int intif_guild_change_basicinfo(int guild_id, int type, const void *data, int len);
|
||||
int intif_guild_change_memberinfo(int guild_id, uint32 account_id, uint32 char_id, int type, const void *data, int len);
|
||||
|
||||
@@ -366,12 +366,11 @@
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_item_ratio.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_item_ratio.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_skill_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_skill_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\pet_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\pet_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\produce_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\produce_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\produce_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\produce_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\quest_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\quest_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\refine.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\refine.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\reputation.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\reputation.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\size_fix.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\size_fix.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_changematerial_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_changematerial_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_damage_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_damage_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_nocast_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_nocast_db.txt')" />
|
||||
|
||||
@@ -1164,6 +1164,7 @@ int mob_spawn (struct mob_data *md)
|
||||
md->last_linktime = tick;
|
||||
md->dmgtick = tick - 5000;
|
||||
md->last_pcneartime = 0;
|
||||
md->last_canmove = tick;
|
||||
|
||||
t_tick c = tick - MOB_MAX_DELAY;
|
||||
|
||||
@@ -1720,6 +1721,8 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick)
|
||||
mode = status_get_mode(&md->bl);
|
||||
|
||||
can_move = (mode&MD_CANMOVE) && unit_can_move(&md->bl);
|
||||
if (can_move)
|
||||
md->last_canmove = tick;
|
||||
|
||||
if (md->target_id)
|
||||
{ //Check validity of current target. [Skotlex]
|
||||
@@ -1956,13 +1959,21 @@ static bool mob_ai_sub_hard(struct mob_data *md, t_tick tick)
|
||||
&& mob_is_chasing(md->state.skillstate))
|
||||
return true;
|
||||
|
||||
//Out of range...
|
||||
if (!(mode&MD_CANMOVE) || (!can_move && DIFF_TICK(tick, md->ud.canmove_tick) > 0))
|
||||
{ //Can't chase. Immobile and trapped mobs should unlock target and use an idle skill.
|
||||
// Out of range
|
||||
if (!(mode&MD_CANMOVE) || (!can_move && (md->sc.cant.move || DIFF_TICK(tick, md->ud.canmove_tick) > 0)))
|
||||
{ // Can't chase. Immobile and trapped mobs will use idle skills and unlock their target after a while
|
||||
if (md->ud.attacktimer == INVALID_TIMER)
|
||||
{ //Only unlock target if no more attack delay left
|
||||
//This handles triggering idle/walk skill.
|
||||
mob_unlocktarget(md,tick);
|
||||
{ // Only switch mode if no more attack delay left
|
||||
if (DIFF_TICK(tick, md->last_canmove) > battle_config.mob_unlock_time) {
|
||||
// Unlock target or use idle/walk skill
|
||||
mob_unlocktarget(md, tick);
|
||||
}
|
||||
else {
|
||||
// Use idle skill but keep target for now
|
||||
md->state.skillstate = MSS_IDLE;
|
||||
if (!(++md->ud.walk_count%IDLE_SKILL_INTERVAL))
|
||||
mobskill_use(md, tick, -1);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -2620,8 +2631,7 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
// determines if the monster was killed by mercenary damage only
|
||||
merckillonly = (bool)((dmgbltypes & BL_MER) && !(dmgbltypes & ~BL_MER));
|
||||
|
||||
if(!battle_config.exp_calc_type && count > 1) { //Apply first-attacker 200% exp share bonus
|
||||
//TODO: Determine if this should go before calculating the MVP player instead of after.
|
||||
if(battle_config.exp_calc_type == 2 && count > 1) { //Apply first-attacker 200% exp share bonus
|
||||
if (UINT_MAX - md->dmglog[0].dmg > md->tdmg) {
|
||||
md->tdmg += md->dmglog[0].dmg;
|
||||
md->dmglog[0].dmg *= 2;
|
||||
@@ -2664,14 +2674,16 @@ int mob_dead(struct mob_data *md, struct block_list *src, int type)
|
||||
|
||||
if (!tmpsd[i]) continue;
|
||||
|
||||
if (!battle_config.exp_calc_type && md->tdmg)
|
||||
//jAthena's exp formula based on total damage.
|
||||
per = (double)md->dmglog[i].dmg/(double)md->tdmg;
|
||||
else {
|
||||
//eAthena's exp formula based on max hp.
|
||||
per = (double)md->dmglog[i].dmg/(double)status->max_hp;
|
||||
if (per > 2) per = 2; // prevents unlimited exp gain
|
||||
if (battle_config.exp_calc_type == 1 || md->tdmg == 0) {
|
||||
// eAthena's exp formula based on max hp
|
||||
per = (double)md->dmglog[i].dmg / (double)status->max_hp;
|
||||
}
|
||||
else {
|
||||
// Aegis's exp formula based on total damage
|
||||
per = (double)md->dmglog[i].dmg / (double)md->tdmg;
|
||||
}
|
||||
// To prevent exploits
|
||||
if (per > 1) per = 1;
|
||||
|
||||
//Exclude rebirth tap from this calculation
|
||||
count -= md->state.rebirth;
|
||||
@@ -4106,7 +4118,7 @@ int mob_clone_spawn(map_session_data *sd, int16 m, int16 x, int16 y, const char
|
||||
/**
|
||||
* The clone should be able to cast the skill (e.g. have the required weapon) bugreport:5299)
|
||||
**/
|
||||
if( !skill_check_condition_castbegin(sd,skill_id,sd->status.skill[sk_idx].lv) )
|
||||
if( !skill_check_condition_castbegin(*sd,skill_id,sd->status.skill[sk_idx].lv) )
|
||||
continue;
|
||||
|
||||
std::shared_ptr<s_mob_skill> ms = std::make_shared<s_mob_skill>();
|
||||
@@ -4581,7 +4593,7 @@ uint64 MobDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
if (!this->asUInt16(node, "Str", stat))
|
||||
return 0;
|
||||
|
||||
mob->status.str = max(1, stat);
|
||||
mob->status.str = max(0, stat);
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Agi")) {
|
||||
@@ -4590,7 +4602,7 @@ uint64 MobDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
if (!this->asUInt16(node, "Agi", stat))
|
||||
return 0;
|
||||
|
||||
mob->status.agi = max(1, stat);
|
||||
mob->status.agi = max(0, stat);
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Vit")) {
|
||||
@@ -4599,7 +4611,7 @@ uint64 MobDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
if (!this->asUInt16(node, "Vit", stat))
|
||||
return 0;
|
||||
|
||||
mob->status.vit = max(1, stat);
|
||||
mob->status.vit = max(0, stat);
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Int")) {
|
||||
@@ -4608,7 +4620,7 @@ uint64 MobDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
if (!this->asUInt16(node, "Int", stat))
|
||||
return 0;
|
||||
|
||||
mob->status.int_ = max(1, stat);
|
||||
mob->status.int_ = max(0, stat);
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Dex")) {
|
||||
@@ -4617,7 +4629,7 @@ uint64 MobDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
if (!this->asUInt16(node, "Dex", stat))
|
||||
return 0;
|
||||
|
||||
mob->status.dex = max(1, stat);
|
||||
mob->status.dex = max(0, stat);
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Luk")) {
|
||||
@@ -4626,7 +4638,7 @@ uint64 MobDatabase::parseBodyNode(const ryml::NodeRef& node) {
|
||||
if (!this->asUInt16(node, "Luk", stat))
|
||||
return 0;
|
||||
|
||||
mob->status.luk = max(1, stat);
|
||||
mob->status.luk = max(0, stat);
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "AttackRange")) {
|
||||
|
||||
@@ -359,7 +359,7 @@ struct mob_data {
|
||||
int areanpc_id; //Required in OnTouchNPC (to avoid multiple area touchs)
|
||||
int bg_id; // BattleGround System
|
||||
|
||||
t_tick next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick;
|
||||
t_tick next_walktime,last_thinktime,last_linktime,last_pcneartime,dmgtick,last_canmove;
|
||||
short move_fail_count;
|
||||
short lootitem_count;
|
||||
short min_chase;
|
||||
|
||||
@@ -3161,7 +3161,7 @@ e_purchase_result npc_barter_purchase( map_session_data& sd, std::shared_ptr<s_n
|
||||
}
|
||||
|
||||
// Server is configured to hide favorite items on selling
|
||||
if( battle_config.hide_fav_sell && sd.inventory.u.items_inventory[j].favorite ){
|
||||
if( battle_config.hide_fav_sell && sd.inventory.u.items_inventory[j].favorite != 0 ){
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3205,7 +3205,7 @@ e_purchase_result npc_barter_purchase( map_session_data& sd, std::shared_ptr<s_n
|
||||
}
|
||||
|
||||
// Server is configured to hide favorite items on selling
|
||||
if( battle_config.hide_fav_sell && sd.inventory.u.items_inventory[j].favorite ){
|
||||
if( battle_config.hide_fav_sell && sd.inventory.u.items_inventory[j].favorite != 0 ){
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -3250,7 +3250,7 @@ e_purchase_result npc_barter_purchase( map_session_data& sd, std::shared_ptr<s_n
|
||||
}
|
||||
|
||||
// Server is configured to hide favorite items on selling
|
||||
if( battle_config.hide_fav_sell && sd.inventory.u.items_inventory[j].favorite ){
|
||||
if( battle_config.hide_fav_sell && sd.inventory.u.items_inventory[j].favorite != 0 ){
|
||||
continue;
|
||||
}
|
||||
|
||||
|
||||
@@ -427,6 +427,44 @@ struct PACKET_ZC_INVENTORY_TAB{
|
||||
bool favorite;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_ZC_SKILL_SELECT_REQUEST_sub{
|
||||
int16 skill_id;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_ZC_SKILL_SELECT_REQUEST{
|
||||
int16 packetType;
|
||||
int16 packetLength;
|
||||
int32 why;
|
||||
struct PACKET_ZC_SKILL_SELECT_REQUEST_sub skills[];
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_REQ_OPEN_BANKING{
|
||||
int16 packetType;
|
||||
uint32 AID;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_REQ_CLOSE_BANKING{
|
||||
int16 packetType;
|
||||
uint32 AID;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_REQ_BANKING_CHECK{
|
||||
int16 packetType;
|
||||
uint32 AID;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_REQ_BANKING_DEPOSIT{
|
||||
int16 packetType;
|
||||
uint32 AID;
|
||||
int32 zeny;
|
||||
} __attribute__((packed));
|
||||
|
||||
struct PACKET_CZ_REQ_BANKING_WITHDRAW{
|
||||
int16 packetType;
|
||||
uint32 AID;
|
||||
int32 zeny;
|
||||
} __attribute__((packed));
|
||||
|
||||
// NetBSD 5 and Solaris don't like pragma pack but accept the packed attribute
|
||||
#if !defined( sun ) && ( !defined( __NETBSD__ ) || __NetBSD_Version__ >= 600000000 )
|
||||
#pragma pack( pop )
|
||||
@@ -458,6 +496,7 @@ DEFINE_PACKET_HEADER(ZC_BOSS_INFO, 0x293)
|
||||
DEFINE_PACKET_HEADER(ZC_CASH_TIME_COUNTER, 0x298)
|
||||
DEFINE_PACKET_HEADER(ZC_CASH_ITEM_DELETE, 0x299)
|
||||
DEFINE_PACKET_HEADER(ZC_NOTIFY_BIND_ON_EQUIP, 0x2d3)
|
||||
DEFINE_PACKET_HEADER(ZC_SKILL_SELECT_REQUEST, 0x442)
|
||||
DEFINE_PACKET_HEADER(ZC_FAILED_TRADE_BUYING_STORE_TO_SELLER, 0x824)
|
||||
DEFINE_PACKET_HEADER(CZ_SSILIST_ITEM_CLICK, 0x83c)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_SE_CASH_TAB_CODE, 0x846)
|
||||
@@ -469,15 +508,20 @@ DEFINE_PACKET_HEADER(ZC_INVENTORY_TAB, 0x908)
|
||||
DEFINE_PACKET_HEADER(ZC_ENTRY_QUEUE_INIT, 0x90e)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_MERGE_ITEM, 0x96e)
|
||||
DEFINE_PACKET_HEADER(ZC_BANKING_CHECK, 0x9a6)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_BANKING_DEPOSIT, 0x9a7)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_BANKING_DEPOSIT, 0x9a8)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_BANKING_WITHDRAW, 0x9a9)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_BANKING_WITHDRAW, 0x9aa)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_BANKING_CHECK, 0x9ab)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_CASH_BARGAIN_SALE_ITEM_INFO, 0x9ac)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_CASH_BARGAIN_SALE_ITEM_INFO, 0x9ad)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_APPLY_BARGAIN_SALE_ITEM, 0x9ae)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_REMOVE_BARGAIN_SALE_ITEM, 0x9b0)
|
||||
DEFINE_PACKET_HEADER(ZC_NOTIFY_BARGAIN_SALE_SELLING, 0x9b2)
|
||||
DEFINE_PACKET_HEADER(ZC_NOTIFY_BARGAIN_SALE_CLOSE, 0x9b3)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_OPEN_BANKING, 0x9b6)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_OPEN_BANKING, 0x9b7)
|
||||
DEFINE_PACKET_HEADER(CZ_REQ_CLOSE_BANKING, 0x9b8)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_CLOSE_BANKING, 0x9b9)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_COUNT_BARGAIN_SALE_ITEM, 0x9c4)
|
||||
DEFINE_PACKET_HEADER(ZC_ACK_GUILDSTORAGE_LOG, 0x9da)
|
||||
|
||||
@@ -1039,7 +1039,7 @@ int party_send_logout(map_session_data *sd)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int party_send_message(map_session_data *sd,const char *mes,int len)
|
||||
int party_send_message(map_session_data *sd,const char *mes, size_t len)
|
||||
{
|
||||
if(sd->status.party_id == 0)
|
||||
return 0;
|
||||
|
||||
@@ -88,7 +88,7 @@ int party_changeleader(map_session_data *sd, map_session_data *t_sd, struct part
|
||||
void party_send_movemap(map_session_data *sd);
|
||||
void party_send_levelup(map_session_data *sd);
|
||||
int party_send_logout(map_session_data *sd);
|
||||
int party_send_message(map_session_data *sd,const char *mes,int len);
|
||||
int party_send_message(map_session_data *sd,const char *mes, size_t len);
|
||||
int party_recv_message(int party_id,uint32 account_id,const char *mes,int len);
|
||||
int party_skill_check(map_session_data *sd, int party_id, uint16 skill_id, uint16 skill_lv);
|
||||
int party_send_xy_clear(struct party_data *p);
|
||||
|
||||
@@ -1207,7 +1207,7 @@ bool pc_can_sell_item(map_session_data *sd, struct item *item, enum npc_subtype
|
||||
if (item->equip > 0 || item->amount < 0)
|
||||
return false;
|
||||
|
||||
if (battle_config.hide_fav_sell && item->favorite)
|
||||
if (battle_config.hide_fav_sell && item->favorite != 0)
|
||||
return false; //Cannot sell favs (optional config)
|
||||
|
||||
if (!battle_config.rental_transaction && item->expire_time)
|
||||
@@ -5934,7 +5934,7 @@ enum e_additem_result pc_additem(map_session_data *sd,struct item *item,int amou
|
||||
// clear equip and favorite fields first, just in case
|
||||
if( item->equip )
|
||||
sd->inventory.u.items_inventory[i].equip = 0;
|
||||
if( item->favorite )
|
||||
if( item->favorite != 0 )
|
||||
sd->inventory.u.items_inventory[i].favorite = 0;
|
||||
if( item->equipSwitch )
|
||||
sd->inventory.u.items_inventory[i].equipSwitch = 0;
|
||||
@@ -14598,7 +14598,7 @@ TIMER_FUNC(pc_autotrade_timer){
|
||||
sd->autotrade_tid = INVALID_TIMER;
|
||||
|
||||
if (sd->state.autotrade&2)
|
||||
vending_reopen(sd);
|
||||
vending_reopen(*sd);
|
||||
if (sd->state.autotrade&4)
|
||||
buyingstore_reopen(sd);
|
||||
|
||||
|
||||
@@ -19867,7 +19867,7 @@ BUILDIN_FUNC(unitattack)
|
||||
case BL_PC: {
|
||||
map_session_data* sd = (map_session_data*)unit_bl;
|
||||
|
||||
clif_parse_ActionRequest_sub(sd, actiontype > 0 ? 0x07 : 0x00, target_bl->id, gettick());
|
||||
clif_parse_ActionRequest_sub( *sd, actiontype > 0 ? 0x07 : 0x00, target_bl->id, gettick() );
|
||||
script_pushint(st, sd->ud.target == target_bl->id);
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -1258,7 +1258,7 @@
|
||||
//export_constant(SC_IGNOREDEF);
|
||||
export_constant(SC_HELLPOWER);
|
||||
export_constant(SC_INVINCIBLE);
|
||||
export_constant(SC_INVINCIBLEOFF);
|
||||
//export_constant(SC_INVINCIBLEOFF);
|
||||
export_constant(SC_MANU_ATK);
|
||||
export_constant(SC_MANU_DEF);
|
||||
export_constant(SC_SPL_ATK);
|
||||
|
||||
2491
src/map/skill.cpp
2491
src/map/skill.cpp
File diff suppressed because it is too large
Load Diff
@@ -28,8 +28,6 @@ struct s_skill_unit_group;
|
||||
struct status_change_entry;
|
||||
class status_change;
|
||||
|
||||
#define MAX_SKILL_PRODUCE_DB 300 /// Max Produce DB
|
||||
#define MAX_PRODUCE_RESOURCE 12 /// Max Produce requirements
|
||||
#define MAX_SKILL_LEVEL 13 /// Max Skill Level (for skill_db storage)
|
||||
#define MAX_MOBSKILL_LEVEL 100 /// Max monster skill level (on skill usage)
|
||||
#define MAX_SKILL_CRIMSON_MARKER 3 /// Max Crimson Marker targets (RL_C_MARKER)
|
||||
@@ -444,15 +442,39 @@ enum e_skill_blown {
|
||||
};
|
||||
|
||||
/// Create Database item
|
||||
struct s_skill_produce_db {
|
||||
struct s_skill_produce_db_entry {
|
||||
t_itemid nameid; /// Product ID
|
||||
unsigned short req_skill; /// Required Skill
|
||||
unsigned char req_skill_lv, /// Required Skill Level
|
||||
uint16 req_skill; /// Required Skill
|
||||
uint16 req_skill_lv, /// Required Skill Level
|
||||
itemlv; /// Item Level
|
||||
t_itemid mat_id[MAX_PRODUCE_RESOURCE]; /// Materials needed
|
||||
unsigned short mat_amount[MAX_PRODUCE_RESOURCE]; /// Amount of each materials
|
||||
std::unordered_map<t_itemid, uint16> materials;
|
||||
|
||||
// additional rates/quantity data for skill_changematerial
|
||||
uint16 baserate;
|
||||
std::unordered_map<uint16, uint16> qty;
|
||||
};
|
||||
extern struct s_skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB];
|
||||
|
||||
struct s_skill_produce_db {
|
||||
uint16 itemlv; /// Item Level
|
||||
std::unordered_map<t_itemid, std::shared_ptr<s_skill_produce_db_entry>> data; /// item, entry
|
||||
};
|
||||
|
||||
class SkillProduceDatabase : public TypesafeYamlDatabase<uint16, s_skill_produce_db> {
|
||||
private:
|
||||
uint16 total_id = 0;
|
||||
|
||||
public:
|
||||
SkillProduceDatabase() : TypesafeYamlDatabase("PRODUCE_DB", 1) {
|
||||
|
||||
}
|
||||
|
||||
const std::string getDefaultLocation() override;
|
||||
uint64 parseBodyNode(const ryml::NodeRef& node) override;
|
||||
bool addItemConsumed(const ryml::NodeRef& node, std::shared_ptr<s_skill_produce_db_entry> &entry, bool isConsumed);
|
||||
void loadingFinished() override;
|
||||
};
|
||||
|
||||
extern SkillProduceDatabase skill_produce_db;
|
||||
|
||||
/// Creating database arrow
|
||||
struct s_skill_arrow_db {
|
||||
@@ -596,8 +618,8 @@ void skill_toggle_magicpower(struct block_list *bl, uint16 skill_id);
|
||||
int skill_check_bl_sc(struct block_list *target, va_list ap);
|
||||
|
||||
// Skill conditions check and remove [Inkfish]
|
||||
bool skill_check_condition_castbegin(map_session_data *sd, uint16 skill_id, uint16 skill_lv);
|
||||
bool skill_check_condition_castend(map_session_data *sd, uint16 skill_id, uint16 skill_lv);
|
||||
bool skill_check_condition_castbegin( map_session_data& sd, uint16 skill_id, uint16 skill_lv );
|
||||
bool skill_check_condition_castend( map_session_data& sd, uint16 skill_id, uint16 skill_lv );
|
||||
int skill_check_condition_char_sub (struct block_list *bl, va_list ap);
|
||||
void skill_consume_requirement(map_session_data *sd, uint16 skill_id, uint16 skill_lv, short type);
|
||||
struct s_skill_condition skill_get_requirement(map_session_data *sd, uint16 skill_id, uint16 skill_lv);
|
||||
@@ -610,9 +632,9 @@ void skill_unit_move_unit_group( std::shared_ptr<s_skill_unit_group> group, int1
|
||||
void skill_unit_move_unit(struct block_list *bl, int dx, int dy);
|
||||
|
||||
int skill_sit(map_session_data *sd, bool sitting);
|
||||
void skill_repairweapon(map_session_data *sd, int idx);
|
||||
void skill_repairweapon( map_session_data& sd, int idx );
|
||||
void skill_identify(map_session_data *sd,int idx);
|
||||
void skill_weaponrefine(map_session_data *sd,int idx); // [Celest]
|
||||
void skill_weaponrefine( map_session_data& sd, int idx ); // [Celest]
|
||||
int skill_autospell(map_session_data *md,uint16 skill_id);
|
||||
|
||||
int skill_calc_heal(struct block_list *src, struct block_list *target, uint16 skill_id, uint16 skill_lv, bool heal);
|
||||
@@ -621,15 +643,15 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
|
||||
int8 skill_isCopyable(map_session_data *sd, uint16 skill_id);
|
||||
|
||||
// Abnormal status
|
||||
bool skill_isNotOk(uint16 skill_id, map_session_data *sd);
|
||||
bool skill_isNotOk( uint16 skill_id, map_session_data& sd );
|
||||
bool skill_isNotOk_hom(struct homun_data *hd, uint16 skill_id, uint16 skill_lv);
|
||||
bool skill_isNotOk_mercenary(uint16 skill_id, s_mercenary_data *md);
|
||||
bool skill_isNotOk_mercenary( uint16 skill_id, s_mercenary_data& md);
|
||||
|
||||
bool skill_isNotOk_npcRange(struct block_list *src, uint16 skill_id, uint16 skill_lv, int pos_x, int pos_y);
|
||||
|
||||
// Item creation
|
||||
short skill_can_produce_mix( map_session_data *sd, t_itemid nameid, int trigger, int qty);
|
||||
bool skill_produce_mix( map_session_data *sd, uint16 skill_id, t_itemid nameid, int slot1, int slot2, int slot3, int qty, short produce_idx );
|
||||
std::shared_ptr<s_skill_produce_db_entry> skill_can_produce_mix(map_session_data *sd, t_itemid nameid, int trigger, int qty);
|
||||
bool skill_produce_mix( map_session_data *sd, uint16 skill_id, t_itemid nameid, int slot1, int slot2, int slot3, int qty, std::shared_ptr<s_skill_produce_db_entry> produce = nullptr );
|
||||
|
||||
bool skill_arrow_create( map_session_data *sd, t_itemid nameid);
|
||||
|
||||
@@ -2775,19 +2797,19 @@ bool skill_check_camouflage(struct block_list *bl, struct status_change_entry *s
|
||||
/**
|
||||
* Mechanic
|
||||
**/
|
||||
int skill_magicdecoy(map_session_data *sd, t_itemid nameid);
|
||||
void skill_magicdecoy( map_session_data& sd, t_itemid nameid );
|
||||
|
||||
/**
|
||||
* Guiltoine Cross
|
||||
**/
|
||||
int skill_poisoningweapon( map_session_data *sd, t_itemid nameid);
|
||||
void skill_poisoningweapon( map_session_data& sd, t_itemid nameid );
|
||||
|
||||
/**
|
||||
* Auto Shadow Spell (Shadow Chaser)
|
||||
**/
|
||||
int skill_select_menu(map_session_data *sd,uint16 skill_id);
|
||||
void skill_select_menu( map_session_data& sd, uint16 skill_id );
|
||||
|
||||
int skill_elementalanalysis(map_session_data *sd, int n, uint16 skill_lv, unsigned short *item_list); // Sorcerer Four Elemental Analisys.
|
||||
int skill_elementalanalysis( map_session_data& sd, int n, uint16 skill_lv, unsigned short *item_list ); // Sorcerer Four Elemental Analisys.
|
||||
int skill_changematerial(map_session_data *sd, int n, unsigned short *item_list); // Genetic Change Material.
|
||||
int skill_get_elemental_type(uint16 skill_id, uint16 skill_lv);
|
||||
|
||||
|
||||
@@ -1408,6 +1408,7 @@ int64 status_charge(struct block_list* bl, int64 hp, int64 sp)
|
||||
* flag&2: Fail if there is not enough to subtract
|
||||
* flag&4: Mob does not give EXP/Loot if killed
|
||||
* flag&8: Used to damage SP of a dead character
|
||||
* flag&16: Coma damage - Log it as normal damage, but actually set HP/SP to 1
|
||||
* @return hp+sp+ap
|
||||
* Note: HP/SP/AP are integer values, not percentages. Values should be
|
||||
* calculated either within function call or before
|
||||
@@ -1475,7 +1476,7 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in
|
||||
flag |= 8;
|
||||
|
||||
sc = status_get_sc(target);
|
||||
if( hp && battle_config.invincible_nodamage && src && sc && sc->getSCE(SC_INVINCIBLE) && !sc->getSCE(SC_INVINCIBLEOFF) )
|
||||
if (hp && battle_config.invincible_nodamage && src && sc && sc->getSCE(SC_INVINCIBLE))
|
||||
hp = 1;
|
||||
|
||||
if( hp && !(flag&1) ) {
|
||||
@@ -1527,10 +1528,25 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in
|
||||
unit_skillcastcancel(target, 2);
|
||||
}
|
||||
|
||||
// We need to log the real damage on exp_calc_type 1
|
||||
if (battle_config.exp_calc_type == 1) {
|
||||
dhp = hp;
|
||||
// Coma real damage
|
||||
if (flag&16)
|
||||
dhp = status->hp - 1;
|
||||
}
|
||||
|
||||
status->hp-= hp;
|
||||
status->sp-= sp;
|
||||
status->ap-= ap;
|
||||
|
||||
// Coma
|
||||
if (flag&16) {
|
||||
status->hp = 1;
|
||||
status->sp = 1;
|
||||
if (!sp) sp = 1; // To make sure the status bar is updated
|
||||
}
|
||||
|
||||
if (sc && hp && status->hp) {
|
||||
if (sc->getSCE(SC_AUTOBERSERK) &&
|
||||
(!sc->getSCE(SC_PROVOKE) || !sc->getSCE(SC_PROVOKE)->val4) &&
|
||||
@@ -1544,9 +1560,11 @@ int status_damage(struct block_list *src,struct block_list *target,int64 dhp, in
|
||||
status_change_end(target, SC_SATURDAYNIGHTFEVER);
|
||||
}
|
||||
|
||||
// Need to pass original HP damage for the mob damage log
|
||||
dhp = cap_value(dhp, INT_MIN, INT_MAX);
|
||||
switch (target->type) {
|
||||
case BL_PC: pc_damage((TBL_PC*)target,src,hp,sp,ap); break;
|
||||
case BL_MOB: mob_damage((TBL_MOB*)target, src, hp); break;
|
||||
case BL_MOB: mob_damage((TBL_MOB*)target, src, (int)dhp); break;
|
||||
case BL_HOM: hom_damage((TBL_HOM*)target); break;
|
||||
case BL_MER: mercenary_heal((TBL_MER*)target,hp,sp); break;
|
||||
case BL_ELEM: elemental_heal((TBL_ELEM*)target,hp,sp); break;
|
||||
@@ -1983,7 +2001,7 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
||||
(sc->getSCE(SC_KYOMU) && rnd()%100 < 25) // Kyomu has a 25% chance of causing skills fail.
|
||||
)) {
|
||||
if (src->type == BL_PC)
|
||||
clif_skill_fail((TBL_PC*)src,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
clif_skill_fail( *((map_session_data*)src), skill_id );
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -2110,12 +2128,6 @@ bool status_check_skilluse(struct block_list *src, struct block_list *target, ui
|
||||
return true;
|
||||
|
||||
if (tsc && tsc->count) {
|
||||
/**
|
||||
* Attacks in invincible are capped to 1 damage and handled in battle.cpp.
|
||||
* Allow spell break and eske for sealed shrine GDB when in INVINCIBLE state.
|
||||
**/
|
||||
if( tsc->getSCE(SC_INVINCIBLE) && !tsc->getSCE(SC_INVINCIBLEOFF) && skill_id && !(skill_id&(SA_SPELLBREAKER|SL_SKE)) )
|
||||
return false;
|
||||
if(!skill_id && tsc->getSCE(SC_TRICKDEAD))
|
||||
return false;
|
||||
if((skill_id == WZ_STORMGUST || skill_id == WZ_FROSTNOVA || skill_id == NJ_HYOUSYOURAKU || skill_id == NPC_STORMGUST2)
|
||||
@@ -8036,8 +8048,8 @@ static unsigned short status_calc_speed(struct block_list *bl, status_change *sc
|
||||
val = max( val, 55 );
|
||||
if( sc->getSCE(SC_AVOID) )
|
||||
val = max( val, 10 * sc->getSCE(SC_AVOID)->val1 );
|
||||
if( sc->getSCE(SC_INVINCIBLE) && !sc->getSCE(SC_INVINCIBLEOFF) )
|
||||
val = max( val, 75 );
|
||||
if (sc->getSCE(SC_INVINCIBLE))
|
||||
val = max(val, sc->getSCE(SC_INVINCIBLE)->val3);
|
||||
if( sc->getSCE(SC_CLOAKINGEXCEED) )
|
||||
val = max( val, sc->getSCE(SC_CLOAKINGEXCEED)->val3);
|
||||
if (sc->getSCE(SC_PARALYSE) && sc->getSCE(SC_PARALYSE)->val3 == 0)
|
||||
@@ -8309,66 +8321,68 @@ static short status_calc_aspd_rate(struct block_list *bl, status_change *sc, int
|
||||
if(!sc || !sc->count)
|
||||
return cap_value(aspd_rate,0,SHRT_MAX);
|
||||
|
||||
if( !sc->getSCE(SC_QUAGMIRE) ) {
|
||||
int max = 0;
|
||||
if(sc->getSCE(SC_STAR_COMFORT))
|
||||
max = sc->getSCE(SC_STAR_COMFORT)->val2;
|
||||
int max = 0;
|
||||
if (sc->getSCE(SC_STAR_COMFORT))
|
||||
max = sc->getSCE(SC_STAR_COMFORT)->val2;
|
||||
|
||||
if(sc->getSCE(SC_TWOHANDQUICKEN) &&
|
||||
max < sc->getSCE(SC_TWOHANDQUICKEN)->val2)
|
||||
max = sc->getSCE(SC_TWOHANDQUICKEN)->val2;
|
||||
if (sc->getSCE(SC_TWOHANDQUICKEN) &&
|
||||
max < sc->getSCE(SC_TWOHANDQUICKEN)->val2)
|
||||
max = sc->getSCE(SC_TWOHANDQUICKEN)->val2;
|
||||
|
||||
if(sc->getSCE(SC_ONEHAND) &&
|
||||
max < sc->getSCE(SC_ONEHAND)->val2)
|
||||
max = sc->getSCE(SC_ONEHAND)->val2;
|
||||
if (sc->getSCE(SC_ONEHAND) &&
|
||||
max < sc->getSCE(SC_ONEHAND)->val2)
|
||||
max = sc->getSCE(SC_ONEHAND)->val2;
|
||||
|
||||
if(sc->getSCE(SC_MERC_QUICKEN) &&
|
||||
max < sc->getSCE(SC_MERC_QUICKEN)->val2)
|
||||
max = sc->getSCE(SC_MERC_QUICKEN)->val2;
|
||||
if (sc->getSCE(SC_MERC_QUICKEN) &&
|
||||
max < sc->getSCE(SC_MERC_QUICKEN)->val2)
|
||||
max = sc->getSCE(SC_MERC_QUICKEN)->val2;
|
||||
|
||||
if(sc->getSCE(SC_ADRENALINE2) &&
|
||||
max < sc->getSCE(SC_ADRENALINE2)->val3)
|
||||
max = sc->getSCE(SC_ADRENALINE2)->val3;
|
||||
if (sc->getSCE(SC_ADRENALINE2) &&
|
||||
max < sc->getSCE(SC_ADRENALINE2)->val3)
|
||||
max = sc->getSCE(SC_ADRENALINE2)->val3;
|
||||
|
||||
if(sc->getSCE(SC_ADRENALINE) &&
|
||||
max < sc->getSCE(SC_ADRENALINE)->val3)
|
||||
max = sc->getSCE(SC_ADRENALINE)->val3;
|
||||
if (sc->getSCE(SC_ADRENALINE) &&
|
||||
max < sc->getSCE(SC_ADRENALINE)->val3)
|
||||
max = sc->getSCE(SC_ADRENALINE)->val3;
|
||||
|
||||
if(sc->getSCE(SC_SPEARQUICKEN) &&
|
||||
max < sc->getSCE(SC_SPEARQUICKEN)->val2)
|
||||
max = sc->getSCE(SC_SPEARQUICKEN)->val2;
|
||||
if (sc->getSCE(SC_SPEARQUICKEN) &&
|
||||
max < sc->getSCE(SC_SPEARQUICKEN)->val2)
|
||||
max = sc->getSCE(SC_SPEARQUICKEN)->val2;
|
||||
|
||||
if(sc->getSCE(SC_GATLINGFEVER) &&
|
||||
max < sc->getSCE(SC_GATLINGFEVER)->val2)
|
||||
max = sc->getSCE(SC_GATLINGFEVER)->val2;
|
||||
if (sc->getSCE(SC_GATLINGFEVER) &&
|
||||
max < sc->getSCE(SC_GATLINGFEVER)->val2)
|
||||
max = sc->getSCE(SC_GATLINGFEVER)->val2;
|
||||
|
||||
if(sc->getSCE(SC_FLEET) &&
|
||||
max < sc->getSCE(SC_FLEET)->val2)
|
||||
max = sc->getSCE(SC_FLEET)->val2;
|
||||
if (sc->getSCE(SC_FLEET) &&
|
||||
max < sc->getSCE(SC_FLEET)->val2)
|
||||
max = sc->getSCE(SC_FLEET)->val2;
|
||||
|
||||
if(sc->getSCE(SC_ASSNCROS) && max < sc->getSCE(SC_ASSNCROS)->val2) {
|
||||
if (bl->type!=BL_PC)
|
||||
max = sc->getSCE(SC_ASSNCROS)->val2;
|
||||
else
|
||||
switch(((TBL_PC*)bl)->status.weapon) {
|
||||
case W_BOW:
|
||||
case W_REVOLVER:
|
||||
case W_RIFLE:
|
||||
case W_GATLING:
|
||||
case W_SHOTGUN:
|
||||
case W_GRENADE:
|
||||
break;
|
||||
default:
|
||||
max = sc->getSCE(SC_ASSNCROS)->val2;
|
||||
if (sc->getSCE(SC_INVINCIBLE) &&
|
||||
max < sc->getSCE(SC_INVINCIBLE)->val4)
|
||||
max = sc->getSCE(SC_INVINCIBLE)->val4;
|
||||
|
||||
if (sc->getSCE(SC_ASSNCROS) && max < sc->getSCE(SC_ASSNCROS)->val2) {
|
||||
if (bl->type != BL_PC)
|
||||
max = sc->getSCE(SC_ASSNCROS)->val2;
|
||||
else
|
||||
switch (((TBL_PC*)bl)->status.weapon) {
|
||||
case W_BOW:
|
||||
case W_REVOLVER:
|
||||
case W_RIFLE:
|
||||
case W_GATLING:
|
||||
case W_SHOTGUN:
|
||||
case W_GRENADE:
|
||||
break;
|
||||
default:
|
||||
max = sc->getSCE(SC_ASSNCROS)->val2;
|
||||
}
|
||||
}
|
||||
aspd_rate -= max;
|
||||
|
||||
if(sc->getSCE(SC_BERSERK))
|
||||
aspd_rate -= 300;
|
||||
else if(sc->getSCE(SC_MADNESSCANCEL))
|
||||
aspd_rate -= 200;
|
||||
}
|
||||
aspd_rate -= max;
|
||||
|
||||
if (sc->getSCE(SC_BERSERK))
|
||||
aspd_rate -= 300;
|
||||
else if (sc->getSCE(SC_MADNESSCANCEL))
|
||||
aspd_rate -= 200;
|
||||
|
||||
if( sc->getSCE(i=SC_ASPDPOTION3) ||
|
||||
sc->getSCE(i=SC_ASPDPOTION2) ||
|
||||
@@ -9609,11 +9623,6 @@ t_tick status_get_sc_def(struct block_list *src, struct block_list *bl, enum sc_
|
||||
tick /= 2; // Half duration for players.
|
||||
sc_def2 = status->mdef*100;
|
||||
break;
|
||||
case SC_ANKLE:
|
||||
if(status_has_mode(status,MD_STATUSIMMUNE)) // Lasts 5 times less on bosses
|
||||
tick /= 5;
|
||||
sc_def = status->agi*50;
|
||||
break;
|
||||
case SC_JOINTBEAT:
|
||||
tick_def2 = 1000 * ((status->luk / 2 + status->agi / 5) / 2); // (50 * LUK / 100 + 20 * AGI / 100) / 2
|
||||
break;
|
||||
@@ -11235,7 +11244,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
}
|
||||
|
||||
case SC_COMA: // Coma. Sends a char to 1HP. If val2, do not zap sp
|
||||
status_zap(bl, status->hp-1, val2?0:status->sp);
|
||||
status_zap(bl, status->hp-1, val2?0:status->sp-1);
|
||||
return 1;
|
||||
break;
|
||||
case SC_CLOSECONFINE2:
|
||||
@@ -11570,6 +11579,11 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
case SC_REBIRTH:
|
||||
val2 = 20*val1; // % of life to be revived with
|
||||
break;
|
||||
case SC_INVINCIBLE:
|
||||
val2 = 100; // ATKpercent increase
|
||||
val3 = 50; // Speed increase
|
||||
val4 = 700; // ASPD increase
|
||||
break;
|
||||
|
||||
case SC_MANU_DEF:
|
||||
case SC_MANU_ATK:
|
||||
@@ -11584,7 +11598,7 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
|
||||
/* General */
|
||||
case SC_FEAR:
|
||||
status_change_start(src,bl,SC_ANKLE,10000,val1,0,0,0,2000,SCSTART_NOAVOID|SCSTART_NOTICKDEF|SCSTART_NORATEDEF);
|
||||
sc_start(src, bl, SC_ANKLE, 100, 0, 2000);
|
||||
break;
|
||||
|
||||
/* Rune Knight */
|
||||
@@ -12848,10 +12862,6 @@ int status_change_start(struct block_list* src, struct block_list* bl,enum sc_ty
|
||||
//SC that make stop walking
|
||||
if (scdb->flag[SCF_STOPWALKING]) {
|
||||
switch (type) {
|
||||
case SC_ANKLE:
|
||||
if (battle_config.skill_trap_type || !map_flag_gvg(bl->m))
|
||||
unit_stop_walking(bl, 1);
|
||||
break;
|
||||
case SC__MANHOLE:
|
||||
if (bl->type == BL_PC || !unit_blown_immune(bl,0x1))
|
||||
unit_stop_walking(bl,1);
|
||||
|
||||
@@ -499,8 +499,8 @@ enum sc_type : int16 {
|
||||
//SC_IGNOREDEF,
|
||||
SC_HELLPOWER = 294,
|
||||
SC_INVINCIBLE, //295
|
||||
SC_INVINCIBLEOFF,
|
||||
SC_MANU_ATK,
|
||||
//SC_INVINCIBLEOFF,
|
||||
SC_MANU_ATK = 297,
|
||||
SC_MANU_DEF,
|
||||
SC_SPL_ATK,
|
||||
SC_SPL_DEF, //300
|
||||
|
||||
@@ -1646,7 +1646,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
if (sc && sc->getSCE(SC_COMBO) &&
|
||||
skill_is_combo(skill_id) &&
|
||||
(sc->getSCE(SC_COMBO)->val1 == skill_id ||
|
||||
(sd?skill_check_condition_castbegin(sd,skill_id,skill_lv):0) )) {
|
||||
(sd?skill_check_condition_castbegin(*sd,skill_id,skill_lv):0) )) {
|
||||
if (skill_is_combo(skill_id) == 2 && target_id == src->id && ud->target > 0)
|
||||
target_id = ud->target;
|
||||
else if (sc->getSCE(SC_COMBO)->val2)
|
||||
@@ -1665,7 +1665,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
|
||||
if (sd) {
|
||||
// Target_id checking.
|
||||
if(skill_isNotOk(skill_id, sd))
|
||||
if(skill_isNotOk(skill_id, *sd))
|
||||
return 0;
|
||||
|
||||
switch(skill_id) { // Check for skills that auto-select target
|
||||
@@ -1697,7 +1697,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
target = (struct block_list*)map_charid2sd(sd->status.partner_id);
|
||||
|
||||
if (!target) {
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@@ -1754,7 +1754,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
// Fail if the targetted skill is near NPC [Cydh]
|
||||
if(skill->inf2[INF2_DISABLENEARNPC] && !ignore_range && skill_isNotOk_npcRange(src,skill_id,skill_lv,target->x,target->y)) {
|
||||
if (sd)
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1773,7 +1773,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
case BD_ENCORE:
|
||||
// Prevent using the dance skill if you no longer have the skill in your tree.
|
||||
if(!sd->skill_id_dance || pc_checkskill(sd,sd->skill_id_dance)<=0) {
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1781,7 +1781,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
break;
|
||||
case WL_WHITEIMPRISON:
|
||||
if( battle_check_target(src,target,BCT_SELF|BCT_ENEMY) < 0 ) {
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_TOTARGET,0);
|
||||
clif_skill_fail( *sd, skill_id, USESKILL_FAIL_TOTARGET );
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
@@ -1799,7 +1799,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
if (i == count) {
|
||||
ARR_FIND(0, count, i, sd->devotion[i] == 0);
|
||||
if (i == count) { // No free slots, skill Fail
|
||||
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1812,7 +1812,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
if (i == MAX_SKILL_CRIMSON_MARKER) {
|
||||
ARR_FIND(0, MAX_SKILL_CRIMSON_MARKER, i, sd->c_marker[i] == 0);
|
||||
if (i == MAX_SKILL_CRIMSON_MARKER) { // No free slots, skill Fail
|
||||
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1832,7 +1832,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
|
||||
// No free slots
|
||||
if( i == count ){
|
||||
clif_skill_fail( sd, skill_id, USESKILL_FAIL_LEVEL, 0 );
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -1840,7 +1840,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
case TR_RETROSPECTION:
|
||||
// Prevent using the song skill if you no longer have the skill in your tree.
|
||||
if (!sd->skill_id_song || pc_checkskill(sd, sd->skill_id_song) <= 0) {
|
||||
clif_skill_fail(sd, skill_id, USESKILL_FAIL_LEVEL, 0);
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1848,7 +1848,7 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
break;
|
||||
}
|
||||
|
||||
if (!skill_check_condition_castbegin(sd, skill_id, skill_lv))
|
||||
if (!skill_check_condition_castbegin(*sd, skill_id, skill_lv))
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1968,7 +1968,8 @@ int unit_skilluse_id2(struct block_list *src, int target_id, uint16 skill_id, ui
|
||||
|
||||
// Only allow to attack if the enemy has a sign mark given by the caster.
|
||||
if( tsc == nullptr || tsc->getSCE(SC_SERVANT_SIGN) == nullptr || tsc->getSCE(SC_SERVANT_SIGN)->val1 != src->id ){
|
||||
clif_skill_fail(sd, skill_id, USESKILL_FAIL, 0);
|
||||
if (sd)
|
||||
clif_skill_fail( *sd, skill_id, USESKILL_FAIL );
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
@@ -2160,14 +2161,15 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
|
||||
return 0;
|
||||
|
||||
if( sd ) {
|
||||
if( skill_isNotOk(skill_id, sd) || !skill_check_condition_castbegin(sd, skill_id, skill_lv) )
|
||||
if( skill_isNotOk(skill_id, *sd) || !skill_check_condition_castbegin(*sd, skill_id, skill_lv) )
|
||||
return 0;
|
||||
if (skill_id == MG_FIREWALL && !skill_pos_maxcount_check(src, skill_x, skill_y, skill_id, skill_lv, BL_PC, true))
|
||||
return 0; // Special check for Firewall only
|
||||
}
|
||||
|
||||
if( (skill_id >= SC_MANHOLE && skill_id <= SC_FEINTBOMB) && map_getcell(src->m, skill_x, skill_y, CELL_CHKMAELSTROM) ) {
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
if (sd)
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -2177,7 +2179,7 @@ int unit_skilluse_pos2( struct block_list *src, short skill_x, short skill_y, ui
|
||||
// Fail if the targetted skill is near NPC [Cydh]
|
||||
if(skill_get_inf2(skill_id, INF2_DISABLENEARNPC) && !ignore_range && skill_isNotOk_npcRange(src,skill_id,skill_lv,skill_x,skill_y)) {
|
||||
if (sd)
|
||||
clif_skill_fail(sd,skill_id,USESKILL_FAIL_LEVEL,0);
|
||||
clif_skill_fail( *sd, skill_id );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -2724,7 +2726,7 @@ static int unit_attack_timer_sub(struct block_list* src, int tid, t_tick tick)
|
||||
// Attacking when under cast delay has restrictions:
|
||||
if( tid == INVALID_TIMER ) { // Requested attack.
|
||||
if(sd)
|
||||
clif_skill_fail(sd,1,USESKILL_FAIL_SKILLINTERVAL,0);
|
||||
clif_skill_fail( *sd, 1, USESKILL_FAIL_SKILLINTERVAL );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -295,35 +295,32 @@ void vending_purchasereq(map_session_data* sd, int aid, int uid, const uint8* da
|
||||
* @param at Autotrader info, or NULL if requetsed not from autotrade persistance
|
||||
* @return 0 If success, 1 - Cannot open (die, not state.prevend, trading), 2 - No cart, 3 - Count issue, 4 - Cart data isn't saved yet, 5 - No valid item found
|
||||
*/
|
||||
int8 vending_openvending(map_session_data* sd, const char* message, const uint8* data, int count, struct s_autotrader *at)
|
||||
{
|
||||
int8 vending_openvending( map_session_data& sd, const char* message, const uint8* data, int count, struct s_autotrader *at ){
|
||||
int i, j;
|
||||
int vending_skill_lvl;
|
||||
char message_sql[MESSAGE_SIZE*2];
|
||||
StringBuf buf;
|
||||
|
||||
nullpo_retr(false,sd);
|
||||
|
||||
if ( pc_isdead(sd) || !sd->state.prevend || pc_istrading(sd)) {
|
||||
if ( pc_isdead(&sd) || !sd.state.prevend || pc_istrading(&sd)) {
|
||||
return 1; // can't open vendings lying dead || didn't use via the skill (wpe/hack) || can't have 2 shops at once
|
||||
}
|
||||
|
||||
vending_skill_lvl = pc_checkskill(sd, MC_VENDING);
|
||||
vending_skill_lvl = pc_checkskill(&sd, MC_VENDING);
|
||||
|
||||
// skill level and cart check
|
||||
if( !vending_skill_lvl || !pc_iscarton(sd) ) {
|
||||
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
|
||||
if( !vending_skill_lvl || !pc_iscarton(&sd) ) {
|
||||
clif_skill_fail( sd, MC_VENDING );
|
||||
return 2;
|
||||
}
|
||||
|
||||
// check number of items in shop
|
||||
if( count < 1 || count > MAX_VENDING || count > 2 + vending_skill_lvl ) { // invalid item count
|
||||
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0);
|
||||
clif_skill_fail( sd, MC_VENDING );
|
||||
return 3;
|
||||
}
|
||||
|
||||
if (save_settings&CHARSAVE_VENDING) // Avoid invalid data from saving
|
||||
chrif_save(sd, CSAVE_INVENTORY|CSAVE_CART);
|
||||
chrif_save(&sd, CSAVE_INVENTORY|CSAVE_CART);
|
||||
|
||||
// filter out invalid items
|
||||
i = 0;
|
||||
@@ -335,51 +332,51 @@ int8 vending_openvending(map_session_data* sd, const char* message, const uint8*
|
||||
index -= 2; // offset adjustment (client says that the first cart position is 2)
|
||||
|
||||
if( index < 0 || index >= MAX_CART // invalid position
|
||||
|| pc_cartitem_amount(sd, index, amount) < 0 // invalid item or insufficient quantity
|
||||
|| pc_cartitem_amount(&sd, index, amount) < 0 // invalid item or insufficient quantity
|
||||
//NOTE: official server does not do any of the following checks!
|
||||
|| !sd->cart.u.items_cart[index].identify // unidentified item
|
||||
|| sd->cart.u.items_cart[index].attribute == 1 // broken item
|
||||
|| sd->cart.u.items_cart[index].expire_time // It should not be in the cart but just in case
|
||||
|| (sd->cart.u.items_cart[index].bound && !pc_can_give_bounded_items(sd)) // can't trade account bound items and has no permission
|
||||
|| !itemdb_cantrade(&sd->cart.u.items_cart[index], pc_get_group_level(sd), pc_get_group_level(sd)) ) // untradeable item
|
||||
|| !sd.cart.u.items_cart[index].identify // unidentified item
|
||||
|| sd.cart.u.items_cart[index].attribute == 1 // broken item
|
||||
|| sd.cart.u.items_cart[index].expire_time // It should not be in the cart but just in case
|
||||
|| (sd.cart.u.items_cart[index].bound && !pc_can_give_bounded_items(&sd)) // can't trade account bound items and has no permission
|
||||
|| !itemdb_cantrade(&sd.cart.u.items_cart[index], pc_get_group_level(&sd), pc_get_group_level(&sd)) ) // untradeable item
|
||||
continue;
|
||||
|
||||
sd->vending[i].index = index;
|
||||
sd->vending[i].amount = amount;
|
||||
sd->vending[i].value = min(value, (unsigned int)battle_config.vending_max_value);
|
||||
sd.vending[i].index = index;
|
||||
sd.vending[i].amount = amount;
|
||||
sd.vending[i].value = min(value, (unsigned int)battle_config.vending_max_value);
|
||||
i++; // item successfully added
|
||||
}
|
||||
|
||||
if (i != j) {
|
||||
clif_displaymessage(sd->fd, msg_txt(sd, 266)); //"Some of your items cannot be vended and were removed from the shop."
|
||||
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
|
||||
clif_displaymessage(sd.fd, msg_txt(&sd, 266)); //"Some of your items cannot be vended and were removed from the shop."
|
||||
clif_skill_fail( sd, MC_VENDING ); // custom reply packet
|
||||
return 5;
|
||||
}
|
||||
|
||||
if( i == 0 ) { // no valid item found
|
||||
clif_skill_fail(sd, MC_VENDING, USESKILL_FAIL_LEVEL, 0); // custom reply packet
|
||||
clif_skill_fail( sd, MC_VENDING ); // custom reply packet
|
||||
return 5;
|
||||
}
|
||||
|
||||
sd->state.prevend = 0;
|
||||
sd->state.vending = true;
|
||||
sd->state.workinprogress = WIP_DISABLE_NONE;
|
||||
sd->vender_id = vending_getuid();
|
||||
sd->vend_num = i;
|
||||
safestrncpy(sd->message, message, MESSAGE_SIZE);
|
||||
sd.state.prevend = 0;
|
||||
sd.state.vending = true;
|
||||
sd.state.workinprogress = WIP_DISABLE_NONE;
|
||||
sd.vender_id = vending_getuid();
|
||||
sd.vend_num = i;
|
||||
safestrncpy(sd.message, message, MESSAGE_SIZE);
|
||||
|
||||
Sql_EscapeString( mmysql_handle, message_sql, sd->message );
|
||||
Sql_EscapeString( mmysql_handle, message_sql, sd.message );
|
||||
|
||||
if( Sql_Query( mmysql_handle, "INSERT INTO `%s`(`id`, `account_id`, `char_id`, `sex`, `map`, `x`, `y`, `title`, `autotrade`, `body_direction`, `head_direction`, `sit`) "
|
||||
"VALUES( %d, %d, %d, '%c', '%s', %d, %d, '%s', %d, '%d', '%d', '%d' );",
|
||||
vendings_table, sd->vender_id, sd->status.account_id, sd->status.char_id, sd->status.sex == SEX_FEMALE ? 'F' : 'M', map_getmapdata(sd->bl.m)->name, sd->bl.x, sd->bl.y, message_sql, sd->state.autotrade, at ? at->dir : sd->ud.dir, at ? at->head_dir : sd->head_dir, at ? at->sit : pc_issit(sd) ) != SQL_SUCCESS ) {
|
||||
vendings_table, sd.vender_id, sd.status.account_id, sd.status.char_id, sd.status.sex == SEX_FEMALE ? 'F' : 'M', map_getmapdata(sd.bl.m)->name, sd.bl.x, sd.bl.y, message_sql, sd.state.autotrade, at ? at->dir : sd.ud.dir, at ? at->head_dir : sd.head_dir, at ? at->sit : pc_issit(&sd) ) != SQL_SUCCESS ) {
|
||||
Sql_ShowDebug(mmysql_handle);
|
||||
}
|
||||
|
||||
StringBuf_Init(&buf);
|
||||
StringBuf_Printf(&buf, "INSERT INTO `%s`(`vending_id`,`index`,`cartinventory_id`,`amount`,`price`) VALUES", vending_items_table);
|
||||
for (j = 0; j < i; j++) {
|
||||
StringBuf_Printf(&buf, "(%d,%d,%d,%d,%d)", sd->vender_id, j, sd->cart.u.items_cart[sd->vending[j].index].id, sd->vending[j].amount, sd->vending[j].value);
|
||||
StringBuf_Printf(&buf, "(%d,%d,%d,%d,%d)", sd.vender_id, j, sd.cart.u.items_cart[sd.vending[j].index].id, sd.vending[j].amount, sd.vending[j].value);
|
||||
if (j < i-1)
|
||||
StringBuf_AppendStr(&buf, ",");
|
||||
}
|
||||
@@ -387,10 +384,10 @@ int8 vending_openvending(map_session_data* sd, const char* message, const uint8*
|
||||
Sql_ShowDebug(mmysql_handle);
|
||||
StringBuf_Destroy(&buf);
|
||||
|
||||
clif_openvending(sd,sd->bl.id,sd->vending);
|
||||
clif_showvendingboard( *sd );
|
||||
clif_openvending(&sd,sd.bl.id,sd.vending);
|
||||
clif_showvendingboard( sd );
|
||||
|
||||
idb_put(vending_db, sd->status.char_id, sd);
|
||||
idb_put(vending_db, sd.status.char_id, &sd);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -494,15 +491,13 @@ bool vending_searchall(map_session_data* sd, const struct s_search_store_search*
|
||||
* Open vending for Autotrader
|
||||
* @param sd Player as autotrader
|
||||
*/
|
||||
void vending_reopen( map_session_data* sd )
|
||||
void vending_reopen( map_session_data& sd )
|
||||
{
|
||||
struct s_autotrader *at = NULL;
|
||||
int8 fail = -1;
|
||||
|
||||
nullpo_retv(sd);
|
||||
|
||||
// Open vending for this autotrader
|
||||
if ((at = (struct s_autotrader *)uidb_get(vending_autotrader_db, sd->status.char_id)) && at->count && at->entries) {
|
||||
if ((at = (struct s_autotrader *)uidb_get(vending_autotrader_db, sd.status.char_id)) && at->count && at->entries) {
|
||||
uint8 *data, *p;
|
||||
uint16 j, count;
|
||||
|
||||
@@ -516,7 +511,7 @@ void vending_reopen( map_session_data* sd )
|
||||
uint32 *value = (uint32*)(p + 4);
|
||||
|
||||
// Find item position in cart
|
||||
ARR_FIND(0, MAX_CART, entry->index, sd->cart.u.items_cart[entry->index].id == entry->cartinventory_id);
|
||||
ARR_FIND(0, MAX_CART, entry->index, sd.cart.u.items_cart[entry->index].id == entry->cartinventory_id);
|
||||
|
||||
if (entry->index == MAX_CART) {
|
||||
count--;
|
||||
@@ -524,35 +519,35 @@ void vending_reopen( map_session_data* sd )
|
||||
}
|
||||
|
||||
*index = entry->index + 2;
|
||||
*amount = itemdb_isstackable(sd->cart.u.items_cart[entry->index].nameid) ? entry->amount : 1;
|
||||
*amount = itemdb_isstackable(sd.cart.u.items_cart[entry->index].nameid) ? entry->amount : 1;
|
||||
*value = entry->price;
|
||||
|
||||
p += 8;
|
||||
}
|
||||
|
||||
sd->state.prevend = 1; // Set him into a hacked prevend state
|
||||
sd->state.autotrade = 1;
|
||||
sd.state.prevend = 1; // Set him into a hacked prevend state
|
||||
sd.state.autotrade = 1;
|
||||
|
||||
// Make sure abort all NPCs
|
||||
npc_event_dequeue(sd);
|
||||
pc_cleareventtimer(sd);
|
||||
npc_event_dequeue(&sd);
|
||||
pc_cleareventtimer(&sd);
|
||||
|
||||
// Open the vending again
|
||||
if( (fail = vending_openvending(sd, at->title, data, count, at)) == 0 ) {
|
||||
// Make vendor look perfect
|
||||
pc_setdir(sd, at->dir, at->head_dir);
|
||||
clif_changed_dir(&sd->bl, AREA_WOS);
|
||||
pc_setdir(&sd, at->dir, at->head_dir);
|
||||
clif_changed_dir(&sd.bl, AREA_WOS);
|
||||
if( at->sit ) {
|
||||
pc_setsit(sd);
|
||||
skill_sit(sd, 1);
|
||||
clif_sitting(&sd->bl);
|
||||
pc_setsit(&sd);
|
||||
skill_sit(&sd, 1);
|
||||
clif_sitting(&sd.bl);
|
||||
}
|
||||
|
||||
// Immediate save
|
||||
chrif_save(sd, CSAVE_AUTOTRADE);
|
||||
chrif_save(&sd, CSAVE_AUTOTRADE);
|
||||
|
||||
ShowInfo("Vending loaded for '" CL_WHITE "%s" CL_RESET "' with '" CL_WHITE "%d" CL_RESET "' items at " CL_WHITE "%s (%d,%d)" CL_RESET "\n",
|
||||
sd->status.name, count, mapindex_id2name(sd->mapindex), sd->bl.x, sd->bl.y);
|
||||
sd.status.name, count, mapindex_id2name(sd.mapindex), sd.bl.x, sd.bl.y);
|
||||
}
|
||||
aFree(data);
|
||||
}
|
||||
@@ -564,8 +559,8 @@ void vending_reopen( map_session_data* sd )
|
||||
}
|
||||
|
||||
if (fail != 0) {
|
||||
ShowError("vending_reopen: (Error:%d) Load failed for autotrader '" CL_WHITE "%s" CL_RESET "' (CID=%d/AID=%d)\n", fail, sd->status.name, sd->status.char_id, sd->status.account_id);
|
||||
map_quit(sd);
|
||||
ShowError("vending_reopen: (Error:%d) Load failed for autotrader '" CL_WHITE "%s" CL_RESET "' (CID=%d/AID=%d)\n", fail, sd.status.name, sd.status.char_id, sd.status.account_id);
|
||||
map_quit(&sd);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -23,9 +23,9 @@ void do_final_vending(void);
|
||||
void do_init_vending(void);
|
||||
void do_init_vending_autotrade( void );
|
||||
|
||||
void vending_reopen( map_session_data* sd );
|
||||
void vending_reopen( map_session_data& sd );
|
||||
void vending_closevending(map_session_data* sd);
|
||||
int8 vending_openvending(map_session_data* sd, const char* message, const uint8* data, int count, struct s_autotrader *at);
|
||||
int8 vending_openvending( map_session_data& sd, const char* message, const uint8* data, int count, struct s_autotrader *at );
|
||||
void vending_vendinglistreq(map_session_data* sd, int id);
|
||||
void vending_purchasereq(map_session_data* sd, int aid, int uid, const uint8* data, int count);
|
||||
bool vending_search(map_session_data* sd, t_itemid nameid);
|
||||
|
||||
@@ -156,6 +156,16 @@ static void skilltree_txt_data(const std::string &modePath, const std::string &f
|
||||
sv_readdb(modePath.c_str(), "skill_tree.txt", ',', 3 + MAX_PC_SKILL_REQUIRE * 2, 5 + MAX_PC_SKILL_REQUIRE * 2, -1, pc_readdb_skilltree, false);
|
||||
}
|
||||
|
||||
// Produce database data to memory
|
||||
static void produce_txt_data(const std::string &modePath, const std::string &fixedPath) {
|
||||
skill_produce.clear();
|
||||
|
||||
if (fileExists(modePath + "/produce_db.txt"))
|
||||
sv_readdb(modePath.c_str(), "produce_db.txt", ',', 5, 5 + 2 * MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill_parse_row_producedb, false);
|
||||
if (fileExists(fixedPath + "/skill_changematerial_db.txt"))
|
||||
sv_readdb(fixedPath.c_str(), "skill_changematerial_db.txt", ',', 5, 5 + 2 * MAX_SKILL_CHANGEMATERIAL_SET, MAX_SKILL_CHANGEMATERIAL_DB, skill_parse_row_changematerialdb, false);
|
||||
}
|
||||
|
||||
template<typename Func>
|
||||
bool process( const std::string& type, uint32 version, const std::vector<std::string>& paths, const std::string& name, Func lambda, const std::string& rename = "" ){
|
||||
for( const std::string& path : paths ){
|
||||
@@ -241,6 +251,9 @@ bool Csv2YamlTool::initialize( int argc, char* argv[] ){
|
||||
#define export_constant_npc(a) export_constant(a)
|
||||
init_random_option_constants();
|
||||
#include <map/script_constants.hpp>
|
||||
// Constants that are deprecated but still needed for conversion
|
||||
script_set_constant(QUOTE(RC2_GUARDIAN), RC2_GUARDIAN, false, false);
|
||||
script_set_constant(QUOTE(RC2_BATTLEFIELD), RC2_BATTLEFIELD, false, false);
|
||||
|
||||
std::vector<std::string> root_paths = {
|
||||
path_db,
|
||||
@@ -560,13 +573,28 @@ bool Csv2YamlTool::initialize( int argc, char* argv[] ){
|
||||
})) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
produce_txt_data(path_db_mode, path_db);
|
||||
if (!process("PRODUCE_DB", 1, { path_db_mode }, "produce_db", [](const std::string &path, const std::string &name_ext) -> bool {
|
||||
return skill_producedb_yaml();
|
||||
})) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
produce_txt_data(path_db_import, path_db_import);
|
||||
if (!process("PRODUCE_DB", 1, { path_db_import }, "produce_db", [](const std::string &path, const std::string &name_ext) -> bool {
|
||||
return skill_producedb_yaml();
|
||||
})) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: add implementations ;-)
|
||||
|
||||
homunculus_txt_data(path_db_import, path_db_import);
|
||||
if (!process("HOMUNCULUS_DB", 1, { path_db_import }, "homunculus_db", [](const std::string& path, const std::string& name_ext) -> bool {
|
||||
return sv_readdb(path.c_str(), name_ext.c_str(), ',', 50, 50, MAX_HOMUNCULUS_CLASS, read_homunculusdb, false);
|
||||
})) {
|
||||
return 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
// TODO: add implementations ;-)
|
||||
|
||||
@@ -3367,17 +3395,17 @@ static bool mob_readdb_sub( char *fields[], size_t columns, size_t current ){
|
||||
body << YAML::Key << "Defense" << YAML::Value << cap_value(std::stoi(fields[12]), DEFTYPE_MIN, DEFTYPE_MAX);
|
||||
if (strtol(fields[13], nullptr, 10) > 0)
|
||||
body << YAML::Key << "MagicDefense" << YAML::Value << cap_value(std::stoi(fields[13]), DEFTYPE_MIN, DEFTYPE_MAX);
|
||||
if (strtol(fields[14], nullptr, 10) > 1)
|
||||
if (strtol(fields[14], nullptr, 10) != 1)
|
||||
body << YAML::Key << "Str" << YAML::Value << fields[14];
|
||||
if (strtol(fields[15], nullptr, 10) > 1)
|
||||
if (strtol(fields[15], nullptr, 10) != 1)
|
||||
body << YAML::Key << "Agi" << YAML::Value << fields[15];
|
||||
if (strtol(fields[16], nullptr, 10) > 1)
|
||||
if (strtol(fields[16], nullptr, 10) != 1)
|
||||
body << YAML::Key << "Vit" << YAML::Value << fields[16];
|
||||
if (strtol(fields[17], nullptr, 10) > 1)
|
||||
if (strtol(fields[17], nullptr, 10) != 1)
|
||||
body << YAML::Key << "Int" << YAML::Value << fields[17];
|
||||
if (strtol(fields[18], nullptr, 10) > 1)
|
||||
if (strtol(fields[18], nullptr, 10) != 1)
|
||||
body << YAML::Key << "Dex" << YAML::Value << fields[18];
|
||||
if (strtol(fields[19], nullptr, 10) > 1)
|
||||
if (strtol(fields[19], nullptr, 10) != 1)
|
||||
body << YAML::Key << "Luk" << YAML::Value << fields[19];
|
||||
if (strtol(fields[9], nullptr, 10) > 0)
|
||||
body << YAML::Key << "AttackRange" << YAML::Value << fields[9];
|
||||
@@ -5268,6 +5296,169 @@ static bool read_homunculusdb( char* str[], size_t columns, size_t current ){
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copied and adjusted from skill.cpp
|
||||
static bool skill_parse_row_producedb(char* split[], size_t columns, size_t current) {
|
||||
t_itemid nameid = static_cast<t_itemid>(strtoul(split[1], nullptr, 10));
|
||||
|
||||
if (nameid == 0) {
|
||||
ShowError("skill_parse_row_producedb: Removing an item for this DB must be done manually. Skipping.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string *item_name = util::umap_find(aegis_itemnames, nameid);
|
||||
|
||||
if (!item_name) {
|
||||
ShowError("skill_parse_row_producedb: Invalid item %u.\n", nameid);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16 skill_id = static_cast<uint16>(strtoul(split[3], nullptr, 10));
|
||||
std::string* skill_name = util::umap_find( aegis_skillnames, skill_id );
|
||||
|
||||
if (skill_id != 0 && skill_name == nullptr) {
|
||||
ShowError( "Skill name for skill id %hu is not known.\n", skill_id );
|
||||
return false;
|
||||
}
|
||||
|
||||
s_skill_produce_db_csv entry = {};
|
||||
|
||||
uint32 skill_lv = strtoul(split[4], nullptr, 10);
|
||||
uint32 itemlv = strtoul(split[2], nullptr, 10);
|
||||
|
||||
entry.produced_name = *item_name;
|
||||
if (skill_name != nullptr) {
|
||||
entry.req_skill_name = *skill_name;
|
||||
entry.req_skill_lv = skill_lv;
|
||||
}
|
||||
|
||||
for (size_t x = 5; x+1 < columns && split[x] && split[x+1]; x += 2) {
|
||||
nameid = static_cast<t_itemid>(strtoul(split[x], nullptr, 10));
|
||||
item_name = util::umap_find(aegis_itemnames, nameid);
|
||||
|
||||
if (!item_name) {
|
||||
ShowError("skill_parse_row_producedb: Invalid item %u.\n", nameid);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32 amount = strtoul(split[x+1], nullptr, 10);
|
||||
if (amount == 0)
|
||||
entry.item_notconsumed.push_back(*item_name);
|
||||
else
|
||||
entry.item_consumed[ *item_name ] = amount;
|
||||
}
|
||||
|
||||
const auto &exists = skill_produce.find(itemlv);
|
||||
|
||||
if (exists != skill_produce.end())
|
||||
exists->second.push_back(entry);
|
||||
else {
|
||||
std::vector<s_skill_produce_db_csv> produce;
|
||||
|
||||
produce.push_back(entry);
|
||||
skill_produce.insert({ itemlv, produce });
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copied and adjusted from skill.cpp
|
||||
static bool skill_parse_row_changematerialdb(char* split[], size_t columns, size_t current)
|
||||
{
|
||||
t_itemid nameid = static_cast<t_itemid>(strtoul(split[1], nullptr, 10));
|
||||
|
||||
// Import just for clearing/disabling from original data
|
||||
// NOTE: If import for disabling, better disable list from produce_db instead of here, or creation just failed with deleting requirements.
|
||||
if (nameid == 0) {
|
||||
ShowError("skill_parse_row_changematerialdb: Removing an item for this DB must be done manually. Skipping.\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string *produced_name = util::umap_find(aegis_itemnames, nameid);
|
||||
|
||||
if (!produced_name) {
|
||||
ShowError("skill_parse_row_changematerialdb: Invalid item %u.\n", nameid);
|
||||
return false;
|
||||
}
|
||||
|
||||
s_skill_changematerial_db_csv item = {};
|
||||
|
||||
item.baserate = static_cast<uint16>(strtoul(split[2], nullptr, 10));
|
||||
for (size_t x = 3; x+1 < columns && split[x] && split[x+1]; x += 2) {
|
||||
item.qty.insert({ static_cast<uint16>(strtoul(split[x], nullptr, 10)), static_cast<uint16>(strtoul(split[x+1], nullptr, 10)) });
|
||||
}
|
||||
|
||||
skill_changematerial_db.insert({ *produced_name, item });
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool skill_producedb_yaml(void) {
|
||||
for (const auto &produceit : skill_produce) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "ItemLevel" << YAML::Value << produceit.first;
|
||||
body << YAML::Key << "Recipe";
|
||||
body << YAML::BeginSeq;
|
||||
|
||||
for (const auto &it : produceit.second) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Product" << YAML::Value << it.produced_name;
|
||||
|
||||
// additional lines from skill_changematerial_db (which uses ItemLV 26)
|
||||
if (produceit.first == 26) {
|
||||
s_skill_changematerial_db_csv* changematerial = util::umap_find( skill_changematerial_db, it.produced_name );
|
||||
if (changematerial != nullptr) {
|
||||
if (changematerial->baserate != 1000)
|
||||
body << YAML::Key << "BaseRate" << YAML::Value << changematerial->baserate;
|
||||
if (!changematerial->qty.empty()) {
|
||||
body << YAML::Key << "Make";
|
||||
body << YAML::BeginSeq;
|
||||
for (const auto &qit : changematerial->qty) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Amount" << YAML::Value << qit.first;
|
||||
if (qit.second != 1000)
|
||||
body << YAML::Key << "Rate" << YAML::Value << qit.second;
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
body << YAML::EndSeq;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (it.req_skill_lv > 0) {
|
||||
body << YAML::Key << "SkillName" << YAML::Value << it.req_skill_name;
|
||||
body << YAML::Key << "SkillLevel" << YAML::Value << it.req_skill_lv;
|
||||
}
|
||||
|
||||
if (!it.item_consumed.empty()) {
|
||||
body << YAML::Key << "Consumed";
|
||||
body << YAML::BeginSeq;
|
||||
for (const auto &itemit : it.item_consumed) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Item" << YAML::Value << itemit.first;
|
||||
body << YAML::Key << "Amount" << YAML::Value << itemit.second;
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
body << YAML::EndSeq;
|
||||
}
|
||||
|
||||
if (!it.item_notconsumed.empty()) {
|
||||
body << YAML::Key << "NotConsumed";
|
||||
body << YAML::BeginSeq;
|
||||
for (const auto &itemit : it.item_notconsumed) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Item" << YAML::Value << itemit;
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
body << YAML::EndSeq;
|
||||
}
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
body << YAML::EndSeq;
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
int main( int argc, char *argv[] ){
|
||||
return main_core<Csv2YamlTool>( argc, argv );
|
||||
}
|
||||
|
||||
@@ -42,6 +42,10 @@ namespace rathena{
|
||||
///Maximum amount of items a combo may require
|
||||
#define MAX_ITEMS_PER_COMBO 6
|
||||
#define MAX_HOM_SKILL_REQUIRE 5
|
||||
#define MAX_SKILL_CHANGEMATERIAL_DB 75
|
||||
#define MAX_SKILL_CHANGEMATERIAL_SET 3
|
||||
#define MAX_SKILL_PRODUCE_DB 300 /// Max Produce DB
|
||||
#define MAX_PRODUCE_RESOURCE 12 /// Max Produce requirements
|
||||
|
||||
struct s_skill_tree_entry_csv {
|
||||
std::string skill_name;
|
||||
@@ -65,6 +69,23 @@ std::unordered_map<uint16, s_skill_db> skill_nearnpc;
|
||||
|
||||
std::unordered_map<int32, std::vector<s_homun_skill_tree_entry>> hom_skill_tree;
|
||||
|
||||
struct s_skill_produce_db_csv {
|
||||
std::string produced_name,
|
||||
req_skill_name;
|
||||
uint32 req_skill_lv,
|
||||
itemlv;
|
||||
std::map<std::string, uint32> item_consumed;
|
||||
std::vector<std::string> item_notconsumed;
|
||||
};
|
||||
|
||||
std::map<uint32, std::vector<s_skill_produce_db_csv>> skill_produce;
|
||||
|
||||
struct s_skill_changematerial_db_csv {
|
||||
uint16 baserate;
|
||||
std::map<uint16, uint16> qty;
|
||||
};
|
||||
std::unordered_map<std::string, s_skill_changematerial_db_csv> skill_changematerial_db;
|
||||
|
||||
static unsigned int level_penalty[3][CLASS_MAX][MAX_LEVEL * 2 + 1];
|
||||
|
||||
struct s_item_flag_csv2yaml {
|
||||
@@ -536,5 +557,9 @@ static bool itemdb_read_combos(const char* file);
|
||||
static bool cashshop_parse_dbrow( char* fields[], size_t columns, size_t current );
|
||||
static bool read_homunculus_skilldb( char* split[], size_t columns, size_t current );
|
||||
static bool read_homunculusdb( char* str[], size_t columns, size_t current );
|
||||
static bool skill_parse_row_producedb(char* fields[], size_t columns, size_t current);
|
||||
static bool skill_producedb_yaml();
|
||||
static bool skill_parse_row_producedb(char *split[], size_t columns, size_t current);
|
||||
static bool skill_parse_row_changematerialdb(char* fields[], size_t columns, size_t current);
|
||||
|
||||
#endif /* CSV2YAML_HPP */
|
||||
|
||||
Reference in New Issue
Block a user