Converted mercenary_db to YAML format (#6101)
* Converts the Mercenary Tables file into YAML. * Includes CSV2YAML converter. * Fixed mercenary name not properly displayed after moving Co-authored-by: Aleos <aleos89@users.noreply.github.com> Co-authored-by: Lemongrass3110 <lemongrass@kstp.at>
This commit is contained in:
parent
9b05754071
commit
4a778815a3
@ -1,5 +0,0 @@
|
||||
// Mercenary Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// ID,Sprite_Name,Name,LV,HP,SP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Speed,aDelay,aMotion,dMotion
|
||||
|
59
db/import-tmpl/mercenary_db.yml
Normal file
59
db/import-tmpl/mercenary_db.yml
Normal file
@ -0,0 +1,59 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2021 rAthena Development Team
|
||||
# https://rathena.org - https://github.com/rathena
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Mercenary Database
|
||||
###########################################################################
|
||||
#
|
||||
# Mercenary Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Id Mercenary ID.
|
||||
# AegisName Server name to reference the mercenary in scripts and lookups, should use no spaces.
|
||||
# Name Name in English.
|
||||
# Level Level. (Default: 1)
|
||||
# Hp Total HP. (Default: 1)
|
||||
# Sp Total SP. (Default: 1)
|
||||
# Attack Minimum attack. (Default: 0)
|
||||
# Attack2 Maximum attack. (Default: 0)
|
||||
# Defense Physical defense of the mercenary, reduces melee and ranged physical attack/skill damage. (Default: 0)
|
||||
# MagicDefense Magic defense of the mercenary, reduces magical skill damage. (Default: 0)
|
||||
# Str Strength which affects attack. (Default: 1)
|
||||
# Agi Agility which affects flee. (Default: 1)
|
||||
# Vit Vitality which affects defense. (Default: 1)
|
||||
# Int Intelligence which affects magic attack. (Default: 1)
|
||||
# Dex Dexterity which affects hit rate. (Default: 1)
|
||||
# Luk Luck which affects perfect dodge/lucky flee/perfect flee/lucky dodge rate. (Default: 1)
|
||||
# AttackRange Attack range. (Default: 0)
|
||||
# SkillRange Skill cast range. (Default: 0)
|
||||
# ChaseRange Chase range. (Default: 0)
|
||||
# Size Size. (Default: Small)
|
||||
# Race Race. (Default: Formless)
|
||||
# Element Element. (Default: Neutral)
|
||||
# ElementLevel Level of element. (Default: 1)
|
||||
# WalkSpeed Walk speed. (Default: DEFAULT_WALK_SPEED)
|
||||
# AttackDelay Attack speed. (Default: 4000)
|
||||
# AttackMotion Attack animation speed. (Default: 2000)
|
||||
# DamageMotion Damage animation speed. (Default: 0)
|
||||
# Skills: List of mercenary skills. (Optional)
|
||||
# - Name Skill name.
|
||||
# MaxLevel Max skill level.
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: MERCENARY_DB
|
||||
Version: 1
|
@ -1,5 +0,0 @@
|
||||
// Mercenary Skill Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// MercenryID,SkillID,SkillLevel
|
||||
|
@ -1,71 +0,0 @@
|
||||
// Mercenary Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// ID,Sprite_Name,Name,LV,HP,SP,Range1,ATK1,ATK2,DEF,MDEF,STR,AGI,VIT,INT,DEX,LUK,Range2,Range3,Scale,Race,Element,Speed,aDelay,aMotion,dMotion
|
||||
|
||||
// Monster Mercenaries
|
||||
1191,MIMIC,Mimic,51,6120,187,2,150,900,10,40,44,121,1,60,75,110,10,12,1,0,60,100,972,500,288
|
||||
1506,DISGUISE,Disguise,55,7543,180,2,279,546,18,29,0,72,45,35,48,65,10,12,1,6,82,147,516,768,384
|
||||
1275,ALICE,Alice,62,10000,221,2,550,700,5,5,64,64,42,85,100,130,10,12,1,7,60,200,502,2304,480
|
||||
1965,M_WILD_ROSE,Wild Rose,38,2980,130,2,315,360,0,15,65,85,15,35,65,80,10,12,0,2,24,100,964,864,288
|
||||
1966,M_DOPPELGANGER,Doppelganger,72,7800,200,2,1340,1590,60,35,88,90,30,35,125,65,10,12,1,6,67,100,480,480,288
|
||||
1967,M_YGNIZEM,Egnigem Cenia,58,11200,320,2,823,1212,35,8,60,35,52,18,79,20,10,12,1,7,43,145,576,432,288
|
||||
2000,M_GAMEMASTER,Male Game Master,50,7000,250,2,100,50,6,17,1,109,1,60,215,111,10,0,0,7,20,150,450,432,300
|
||||
2001,F_GAMEMASTER,Female Game Master,50,7000,250,2,100,50,6,17,1,109,1,60,215,111,10,0,0,7,20,150,450,432,300
|
||||
2034,M_DESERT_WOLF_B,Baby Desert Wolf,9,164,15,1,500,600,0,0,1,9,9,5,40,40,10,12,0,2,23,100,1600,900,240
|
||||
2037,VALKYRIE_A,Valkyrie Randgris,90,5000,15,1,10,160,10,20,1,20,40,0,20,20,10,12,1,8,66,100,576,576,480
|
||||
2038,VALKYRIE_B,Valkyrie Randgris,90,10000,15,1,300,450,10,40,1,20,80,0,80,20,10,12,1,8,66,100,576,576,480
|
||||
2058,M_MIMIC,Mimic,51,6120,182,1,800,950,10,40,44,121,1,60,75,110,10,12,1,0,60,100,972,500,288
|
||||
2059,M_DISGUISE,Disguise,55,7543,180,2,526,693,18,29,0,72,45,35,48,65,10,12,1,6,82,147,516,768,384
|
||||
2060,M_ALICE,Alice,62,10000,221,1,700,850,5,5,64,64,42,85,100,130,10,12,1,7,60,200,502,1999,480
|
||||
2213,M_WANDER_MAN,Wander Man,81,8614,220,2,1100,1300,60,20,80,110,63,51,85,90,10,12,1,6,24,100,672,500,192
|
||||
2214,M_WICKED_NYMPH,Wicked Nymph,85,6157,256,2,420,620,30,45,40,50,40,92,60,110,10,12,1,6,67,200,637,1008,360
|
||||
2215,M_KASA,Kasa,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,2,0,63,150,800,600,288
|
||||
2216,M_SALAMANDER,Salamander,87,9517,260,2,900,1100,60,68,90,80,65,45,87,95,10,12,2,0,63,160,140,384,288
|
||||
2217,M_TEDDY_BEAR,Teddy Bear,85,14493,243,1,600,800,100,70,60,20,85,50,75,130,10,12,0,0,60,200,512,780,504
|
||||
2325,M_BAPHOMET_,Baphomet,57,7510,204,1,810,955,70,40,52,60,36,17,57,25,10,12,0,6,27,100,868,480,120
|
||||
2326,M_GALAPAGO,Galapago,45,7513,201,1,760,915,70,40,30,28,29,18,30,16,10,12,0,2,22,165,1430,1080,1080
|
||||
2342,MER_DIABOLIC,Diabolic,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2344,MER_WISH_MAIDEN,Wish Maiden,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2345,MER_ZHERLTHSH,Zherlthsh,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2346,MER_KTULLANUX,Ktullanux,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2347,MER_EDDGA,Eddga,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2348,MER_CIVIL_SERVANT,Civil Servant,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2349,MER_LOLI_RURI,Loli Ruri,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2350,MER_SEDORA,Sedora,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2351,MER_CHEPET,Chepet,83,9815,234,2,1100,1300,60,60,85,90,71,43,85,105,10,12,0,6,47,150,1080,780,180
|
||||
2378,MER_ANTLER_SCARABA,Antler Scaraba,136,30000,1,1,1418,1828,155,102,23,99,59,129,137,45,10,12,1,4,42,200,504,624,360
|
||||
2937,M_LOKI,Loki's Shadow,145,1215600,1,2,1835,2279,15,89,76,66,90,55,189,22,10,12,1,7,20,175,800,750,300
|
||||
3087,M_NYDHOG,Guardian's Alter Ego,160,215000,1,2,1835,444,15,89,76,66,90,55,189,22,10,12,1,7,20,175,800,750,300
|
||||
|
||||
// Normal Mercenaries
|
||||
6017,MER_ARCHER01,Mina,20,256,200,10,170,85,7,5,1,16,5,1,28,8,10,0,0,7,20,150,700,432,300
|
||||
6018,MER_ARCHER02,Dororu,30,457,70,10,228,114,11,7,1,18,8,1,40,11,10,0,0,7,20,150,700,432,300
|
||||
6019,MER_ARCHER03,Nami,40,732,93,10,260,130,15,9,3,21,12,4,52,17,10,0,0,7,20,150,700,432,300
|
||||
6020,MER_ARCHER04,Elfin,50,1092,116,10,310,155,18,11,5,33,17,6,60,23,10,0,0,7,20,150,575,432,300
|
||||
6021,MER_ARCHER05,Clara,60,2212,280,10,360,180,20,13,5,41,17,12,75,30,10,0,0,7,20,150,575,432,300
|
||||
6022,MER_ARCHER06,Dali,70,3098,353,10,424,212,21,15,11,46,24,22,83,37,10,0,0,7,20,150,575,432,300
|
||||
6023,MER_ARCHER07,Karaya,80,4051,415,10,468,234,22,16,14,55,27,26,91,44,10,0,0,7,20,150,450,432,300
|
||||
6024,MER_ARCHER08,Hiyori,90,5039,469,10,482,241,24,18,19,65,27,27,103,49,10,0,0,7,20,150,450,432,300
|
||||
6025,MER_ARCHER09,Kero,95,5572,499,10,500,250,25,20,20,71,27,28,110,51,10,0,0,7,20,150,450,432,300
|
||||
6026,MER_ARCHER10,Sukye,99,7381,642,10,816,308,49,49,21,83,27,28,123,52,10,0,0,7,20,150,450,432,300
|
||||
6027,MER_LANCER01,Rodin,22,2071,100,2,168,84,30,1,27,1,4,1,30,2,10,0,0,7,20,150,700,432,300
|
||||
6028,MER_LANCER02,Lancer,34,2523,131,2,208,104,33,1,37,1,4,1,37,4,10,0,0,7,20,150,700,432,300
|
||||
6029,MER_LANCER03,Nathan,41,3397,161,2,248,124,36,5,45,1,22,1,40,6,10,0,0,7,20,150,700,432,300
|
||||
6030,MER_LANCER04,Roan,55,4580,191,2,300,150,39,5,55,2,35,1,50,8,10,0,0,7,20,150,575,432,300
|
||||
6031,MER_LANCER05,Orizaro,60,5899,221,2,350,160,42,10,65,2,39,1,60,10,10,0,0,7,20,150,575,432,300
|
||||
6032,MER_LANCER06,Thyla,72,7874,252,2,370,185,46,10,75,3,15,77,61,12,10,0,0,7,20,150,575,432,300
|
||||
6033,MER_LANCER07,Ben,81,10260,330,2,380,190,50,15,85,3,63,20,61,14,10,0,0,7,20,150,450,432,300
|
||||
6034,MER_LANCER08,Pinaka,90,13167,366,2,400,200,55,20,95,20,74,20,63,16,10,0,0,7,20,150,450,432,300
|
||||
6035,MER_LANCER09,Kuhlmann,95,14648,398,2,440,220,60,25,100,25,77,25,63,18,10,0,0,7,20,150,450,432,300
|
||||
6036,MER_LANCER10,Roux,99,18000,413,2,700,250,70,30,120,30,90,30,70,30,10,0,0,7,20,150,450,432,300
|
||||
6037,MER_SWORDMAN01,David,20,502,70,2,174,87,26,0,21,27,5,1,30,3,10,0,0,7,20,150,700,432,300
|
||||
6038,MER_SWORDMAN02,Ellen,30,979,99,2,258,129,31,0,26,38,6,1,35,3,10,0,0,7,20,150,700,432,300
|
||||
6039,MER_SWORDMAN03,Luise,40,1555,134,2,326,163,36,3,31,45,7,6,40,6,10,0,0,7,20,150,700,432,300
|
||||
6040,MER_SWORDMAN04,Frank,50,2397,162,2,382,191,39,5,37,59,8,6,40,6,10,0,0,7,20,150,575,432,300
|
||||
6041,MER_SWORDMAN05,Ryan,60,3387,195,2,406,203,42,7,48,68,9,6,45,9,10,0,0,7,20,150,575,432,300
|
||||
6042,MER_SWORDMAN06,Paolo,70,4495,241,2,436,218,45,12,53,79,10,12,50,9,10,0,0,7,20,150,575,432,300
|
||||
6043,MER_SWORDMAN07,Jens,80,5889,279,2,468,234,47,15,59,88,11,12,55,12,10,0,0,7,20,150,450,432,300
|
||||
6044,MER_SWORDMAN08,Thierry,90,7520,325,2,500,250,49,18,70,95,12,18,60,15,10,0,0,7,20,150,450,432,300
|
||||
6045,MER_SWORDMAN09,Steven,95,9052,348,2,524,262,51,22,80,95,18,18,60,15,10,0,0,7,20,150,450,432,300
|
||||
6046,MER_SWORDMAN10,Wayne,99,12355,451,2,760,280,64,30,99,105,30,30,60,30,10,0,0,7,20,150,450,432,300
|
1438
db/mercenary_db.yml
Normal file
1438
db/mercenary_db.yml
Normal file
File diff suppressed because it is too large
Load Diff
@ -1,219 +0,0 @@
|
||||
// Mercenary Skill Database
|
||||
//
|
||||
// Structure of Database:
|
||||
// MercenryID,SkillID,SkillLevel
|
||||
|
||||
// Archer Mercenaries Level 1-10.
|
||||
// MER_ARCHER01
|
||||
6017,8207,2 //MA_DOUBLE
|
||||
6017,8233,1 //MER_AUTOBERSERK
|
||||
// MER_ARCHER02
|
||||
6018,8208,2 //MA_SHOWER
|
||||
6018,8224,1 //MER_SIGHT
|
||||
// MER_ARCHER03
|
||||
6019,8214,1 //MA_CHARGEARROW
|
||||
6019,8223,1 //MER_QUICKEN
|
||||
// MER_ARCHER04
|
||||
6020,8237,1 //MER_ESTIMATION
|
||||
6020,8222,1 //MER_MAGNIFICAT
|
||||
6020,8227,1 //MER_TENDER
|
||||
// MER_ARCHER05
|
||||
6021,8207,5 //MA_DOUBLE
|
||||
6021,8232,1 //MER_PROVOKE
|
||||
6021,8213,1 //MA_REMOVETRAP
|
||||
// MER_ARCHER06
|
||||
6022,8207,7 //MA_DOUBLE
|
||||
6022,8209,3 //MA_SKIDTRAP
|
||||
6022,8234,1 //MER_DECAGI
|
||||
// MER_ARCHER07
|
||||
6023,8208,10 //MA_SHOWER
|
||||
6023,8230,1 //MER_MENTALCURE
|
||||
6023,8212,2 //MA_FREEZINGTRAP
|
||||
// MER_ARCHER08
|
||||
6024,8223,2 //MER_QUICKEN
|
||||
6024,8232,3 //MER_PROVOKE
|
||||
6024,8211,3 //MA_SANDMAN
|
||||
// MER_ARCHER09
|
||||
6025,8207,10 //MA_DOUBLE
|
||||
6025,8214,1 //MA_CHARGEARROW
|
||||
6025,8210,5 //MA_LANDMINE
|
||||
// MER_ARCHER10
|
||||
6026,8214,1 //MA_CHARGEARROW
|
||||
6026,8215,5 //MA_SHARPSHOOTING
|
||||
6026,8223,5 //MER_QUICKEN
|
||||
6026,8233,1 //MER_AUTOBERSERK
|
||||
|
||||
// Lancer Mercenaries Level 1-10.
|
||||
// MER_LANCER01
|
||||
6027,8216,1 //ML_PIERCE
|
||||
6027,8226,1 //MER_REGAIN
|
||||
// MER_LANCER02
|
||||
6028,8217,2 //ML_BRANDISH
|
||||
6028,8236,1 //MER_LEXDIVINA
|
||||
// MER_LANCER03
|
||||
6029,8216,2 //ML_PIERCE
|
||||
6029,8221,1 //ML_DEVOTION
|
||||
6029,8229,1 //MER_RECUPERATE
|
||||
// MER_LANCER04
|
||||
6030,8219,1 //ML_DEFENDER
|
||||
6030,8225,4 //MER_CRASH
|
||||
// MER_LANCER05
|
||||
6031,8216,5 //ML_PIERCE
|
||||
6031,8220,3 //ML_AUTOGUARD
|
||||
// MER_LANCER06
|
||||
6032,8223,2 //MER_QUICKEN
|
||||
6032,8217,5 //ML_BRANDISH
|
||||
// MER_LANCER07
|
||||
6033,8221,1 //ML_DEVOTION
|
||||
6033,8233,1 //MER_AUTOBERSERK
|
||||
// MER_LANCER08
|
||||
6034,8235,1 //MER_SCAPEGOAT
|
||||
6034,8216,10 //ML_PIERCE
|
||||
6034,8232,5 //MER_PROVOKE
|
||||
// MER_LANCER09
|
||||
6035,8217,10 //ML_BRANDISH
|
||||
6035,8220,7 //ML_AUTOGUARD
|
||||
6035,8219,3 //ML_DEFENDER
|
||||
// MER_LANCER10
|
||||
6036,8223,5 //MER_QUICKEN
|
||||
6036,8220,10 //ML_AUTOGUARD
|
||||
6036,8221,3 //ML_DEVOTION
|
||||
6036,8218,5 //ML_SPIRALPIERCE
|
||||
|
||||
// Swordman Mercenaries Level 1-10.
|
||||
// MER_SWORDMAN01
|
||||
6037,8201,1 //MS_BASH
|
||||
6037,8234,1 //MER_DECAGI
|
||||
// MER_SWORDMAN02
|
||||
6038,8232,5 //MER_PROVOKE
|
||||
6038,8202,3 //MS_MAGNUM
|
||||
// MER_SWORDMAN03
|
||||
6039,8223,1 //MER_QUICKEN
|
||||
6039,8228,1 //MER_BENEDICTION
|
||||
// MER_SWORDMAN04
|
||||
6040,8225,1 //MER_CRASH
|
||||
6040,8202,5 //MS_MAGNUM
|
||||
// MER_SWORDMAN05
|
||||
6041,8201,5 //MS_BASH
|
||||
6041,8225,4 //MER_CRASH
|
||||
6041,8228,1 //MER_BENEDICTION
|
||||
// MER_SWORDMAN06
|
||||
6042,8223,5 //MER_QUICKEN
|
||||
6042,8237,1 //MER_ESTIMATION
|
||||
6042,8234,3 //MER_DECAGI
|
||||
// MER_SWORDMAN07
|
||||
6043,8201,10 //MS_BASH
|
||||
6043,8233,1 //MER_AUTOBERSERK
|
||||
6043,8235,1 //MER_SCAPEGOAT
|
||||
// MER_SWORDMAN08
|
||||
6044,8223,10 //MER_QUICKEN
|
||||
6044,8203,5 //MS_BOWLINGABASH
|
||||
6044,8231,1 //MER_COMPRESS
|
||||
6044,8204,4 //MS_PARRYING
|
||||
// MER_SWORDMAN09
|
||||
6045,8203,8 //MS_BOWLINGABASH
|
||||
6045,8225,3 //MER_CRASH
|
||||
6045,8205,5 //MS_REFLECTSHIELD
|
||||
// MER_SWORDMAN10
|
||||
6046,8223,10 //MER_QUICKEN
|
||||
6046,8203,10 //MS_BOWLINGABASH
|
||||
6046,8201,10 //MS_BASH
|
||||
6046,8206,1 //MS_BERSERK
|
||||
|
||||
// Monster Mercenaries
|
||||
// MIMIC
|
||||
1191,8233,1 //MER_AUTOBERSERK
|
||||
1191,8220,5 //ML_AUTOGUARD
|
||||
1191,8201,5 //MS_BASH
|
||||
// DISGUISE
|
||||
1506,8223,2 //MER_QUICKEN
|
||||
1506,8225,5 //MER_CRASH
|
||||
1506,8236,3 //MER_LEXDIVINA
|
||||
// ALICE
|
||||
1275,8232,5 //MER_PROVOKE
|
||||
1275,8202,5 //MS_MAGNUM
|
||||
1275,8217,5 //ML_BRANDISH
|
||||
1275,8226,1 //MER_REGAIN
|
||||
// M_WILD_ROSE
|
||||
1965,8201,5 //MS_BASH
|
||||
// M_DOPPELGANGER
|
||||
1966,8223,5 //MER_QUICKEN
|
||||
1966,8201,5 //MS_BASH
|
||||
1966,8221,3 //ML_DEVOTION
|
||||
// M_YGNIZEM
|
||||
1967,8223,5 //MER_QUICKEN
|
||||
1967,8201,5 //MS_BASH
|
||||
1967,8221,3 //ML_DEVOTION
|
||||
// M_GAMEMASTER
|
||||
2000,8226,1 //MER_REGAIN
|
||||
2000,8227,1 //MER_TENDER
|
||||
2000,8238,5 //MER_KYRIE
|
||||
2000,8239,5 //MER_BLESSING
|
||||
2000,8240,5 //MER_INCAGI
|
||||
// F_GAMEMASTER
|
||||
2001,8226,1 //MER_REGAIN
|
||||
2001,8227,1 //MER_TENDER
|
||||
2001,8238,5 //MER_KYRIE
|
||||
2001,8239,5 //MER_BLESSING
|
||||
2001,8240,5 //MER_INCAGI
|
||||
// M_MIMIC
|
||||
2058,8233,1 //MER_AUTOBERSERK
|
||||
2058,8220,5 //ML_AUTOGUARD
|
||||
2058,8201,5 //MS_BASH
|
||||
// M_DISGUISE
|
||||
2059,8223,2 //MER_QUICKEN
|
||||
2059,8225,5 //MER_CRASH
|
||||
2059,8236,3 //MER_LEXDIVINA
|
||||
// M_ALICE
|
||||
2060,8232,5 //MER_PROVOKE
|
||||
2060,8202,5 //MS_MAGNUM
|
||||
2060,8217,5 //ML_BRANDISH
|
||||
2060,8226,1 //MER_REGAIN
|
||||
// M_WANDER_MAN
|
||||
2213,8223,10 //MER_QUICKEN
|
||||
2213,8204,4 //MS_PARRYING
|
||||
2213,8233,1 //MER_AUTOBERSERK
|
||||
2213,8203,5 //MS_BOWLINGBASH
|
||||
// M_WICKED_NYMPH
|
||||
2214,8236,3 //MER_LEXDIVINA
|
||||
2214,8239,5 //MER_BLESSING
|
||||
2214,8227,1 //MER_TENDER
|
||||
2214,8222,1 //MER_MAGNIFICAT
|
||||
// M_KASA
|
||||
2215,8225,5 //MER_CRASH
|
||||
2215,8202,5 //MS_MAGNUM
|
||||
2215,8226,1 //MER_REGAIN
|
||||
2215,8233,1 //MER_AUTOBERSERK
|
||||
// M_SALAMANDER
|
||||
2216,8201,5 //MS_BASH
|
||||
2216,8217,5 //ML_BRANDISH
|
||||
2216,8233,1 //MER_AUTOBERSERK
|
||||
2216,8228,1 //MER_BENEDICTION
|
||||
// M_TEDDY_BEAR
|
||||
2217,8221,3 //ML_DEVOTION
|
||||
2217,8226,1 //MER_REGAIN
|
||||
2217,8219,1 //ML_DEFENDER
|
||||
2217,8235,1 //MER_SCAPEGOAT
|
||||
// M_BAPHOMET_
|
||||
2325,8201,5 //MS_BASH
|
||||
2325,8223,10 //MER_QUICKEN
|
||||
// M_GALAPAGO
|
||||
2326,8239,5 //MER_BLESSING
|
||||
//2326,28,5 //AL_HEAL
|
||||
// MER_DIABOLIC
|
||||
2342,8225,5 //MER_CRASH
|
||||
2342,8202,5 //MS_MAGNUM
|
||||
2342,8226,1 //MER_REGAIN
|
||||
2342,8233,1 //MER_AUTOBERSERK
|
||||
// MER_ZHERLTHSH
|
||||
2345,8225,5 //MER_CRASH
|
||||
2345,8202,5 //MS_MAGNUM
|
||||
2345,8226,1 //MER_REGAIN
|
||||
2345,8233,1 //MER_AUTOBERSERK
|
||||
// MER_EDDGA
|
||||
2347,8225,5 //MER_CRASH
|
||||
2347,8202,5 //MS_MAGNUM
|
||||
2347,8226,1 //MER_REGAIN
|
||||
2347,8233,1 //MER_AUTOBERSERK
|
||||
// M_LOKI
|
||||
2937,8241,1 //MER_INVINCIBLEOFF2
|
59
db/pre-re/mercenary_db.yml
Normal file
59
db/pre-re/mercenary_db.yml
Normal file
@ -0,0 +1,59 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2021 rAthena Development Team
|
||||
# https://rathena.org - https://github.com/rathena
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Mercenary Database
|
||||
###########################################################################
|
||||
#
|
||||
# Mercenary Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Id Mercenary ID.
|
||||
# AegisName Server name to reference the mercenary in scripts and lookups, should use no spaces.
|
||||
# Name Name in English.
|
||||
# Level Level. (Default: 1)
|
||||
# Hp Total HP. (Default: 1)
|
||||
# Sp Total SP. (Default: 1)
|
||||
# Attack Minimum attack. (Default: 0)
|
||||
# Attack2 Maximum attack. (Default: 0)
|
||||
# Defense Physical defense of the mercenary, reduces melee and ranged physical attack/skill damage. (Default: 0)
|
||||
# MagicDefense Magic defense of the mercenary, reduces magical skill damage. (Default: 0)
|
||||
# Str Strength which affects attack. (Default: 1)
|
||||
# Agi Agility which affects flee. (Default: 1)
|
||||
# Vit Vitality which affects defense. (Default: 1)
|
||||
# Int Intelligence which affects magic attack. (Default: 1)
|
||||
# Dex Dexterity which affects hit rate. (Default: 1)
|
||||
# Luk Luck which affects perfect dodge/lucky flee/perfect flee/lucky dodge rate. (Default: 1)
|
||||
# AttackRange Attack range. (Default: 0)
|
||||
# SkillRange Skill cast range. (Default: 0)
|
||||
# ChaseRange Chase range. (Default: 0)
|
||||
# Size Size. (Default: Small)
|
||||
# Race Race. (Default: Formless)
|
||||
# Element Element. (Default: Neutral)
|
||||
# ElementLevel Level of element. (Default: 1)
|
||||
# WalkSpeed Walk speed. (Default: DEFAULT_WALK_SPEED)
|
||||
# AttackDelay Attack speed. (Default: 4000)
|
||||
# AttackMotion Attack animation speed. (Default: 2000)
|
||||
# DamageMotion Damage animation speed. (Default: 0)
|
||||
# Skills: List of mercenary skills. (Optional)
|
||||
# - Name Skill name.
|
||||
# MaxLevel Max skill level.
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: MERCENARY_DB
|
||||
Version: 1
|
613
db/re/mercenary_db.yml
Normal file
613
db/re/mercenary_db.yml
Normal file
@ -0,0 +1,613 @@
|
||||
# This file is a part of rAthena.
|
||||
# Copyright(C) 2021 rAthena Development Team
|
||||
# https://rathena.org - https://github.com/rathena
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
#
|
||||
###########################################################################
|
||||
# Mercenary Database
|
||||
###########################################################################
|
||||
#
|
||||
# Mercenary Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Id Mercenary ID.
|
||||
# AegisName Server name to reference the mercenary in scripts and lookups, should use no spaces.
|
||||
# Name Name in English.
|
||||
# Level Level. (Default: 1)
|
||||
# Hp Total HP. (Default: 1)
|
||||
# Sp Total SP. (Default: 1)
|
||||
# Attack Minimum attack. (Default: 0)
|
||||
# Attack2 Maximum attack. (Default: 0)
|
||||
# Defense Physical defense of the mercenary, reduces melee and ranged physical attack/skill damage. (Default: 0)
|
||||
# MagicDefense Magic defense of the mercenary, reduces magical skill damage. (Default: 0)
|
||||
# Str Strength which affects attack. (Default: 1)
|
||||
# Agi Agility which affects flee. (Default: 1)
|
||||
# Vit Vitality which affects defense. (Default: 1)
|
||||
# Int Intelligence which affects magic attack. (Default: 1)
|
||||
# Dex Dexterity which affects hit rate. (Default: 1)
|
||||
# Luk Luck which affects perfect dodge/lucky flee/perfect flee/lucky dodge rate. (Default: 1)
|
||||
# AttackRange Attack range. (Default: 0)
|
||||
# SkillRange Skill cast range. (Default: 0)
|
||||
# ChaseRange Chase range. (Default: 0)
|
||||
# Size Size. (Default: Small)
|
||||
# Race Race. (Default: Formless)
|
||||
# Element Element. (Default: Neutral)
|
||||
# ElementLevel Level of element. (Default: 1)
|
||||
# WalkSpeed Walk speed. (Default: DEFAULT_WALK_SPEED)
|
||||
# AttackDelay Attack speed. (Default: 4000)
|
||||
# AttackMotion Attack animation speed. (Default: 2000)
|
||||
# DamageMotion Damage animation speed. (Default: 0)
|
||||
# Skills: List of mercenary skills. (Optional)
|
||||
# - Name Skill name.
|
||||
# MaxLevel Max skill level.
|
||||
###########################################################################
|
||||
|
||||
Header:
|
||||
Type: MERCENARY_DB
|
||||
Version: 1
|
||||
|
||||
Body:
|
||||
- Id: 2213
|
||||
AegisName: M_WANDER_MAN
|
||||
Name: Wander Man
|
||||
Level: 81
|
||||
Hp: 8614
|
||||
Sp: 220
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 20
|
||||
Str: 80
|
||||
Agi: 110
|
||||
Vit: 63
|
||||
Int: 51
|
||||
Dex: 85
|
||||
Luk: 90
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Demon
|
||||
Element: Wind
|
||||
ElementLevel: 1
|
||||
WalkSpeed: 100
|
||||
AttackDelay: 672
|
||||
AttackMotion: 500
|
||||
DamageMotion: 192
|
||||
Skills:
|
||||
- Name: MER_QUICKEN
|
||||
MaxLevel: 10
|
||||
- Name: MS_PARRYING
|
||||
MaxLevel: 4
|
||||
- Name: MER_AUTOBERSERK
|
||||
MaxLevel: 1
|
||||
- Name: MS_BOWLINGBASH
|
||||
MaxLevel: 5
|
||||
- Id: 2214
|
||||
AegisName: M_WICKED_NYMPH
|
||||
Name: Wicked Nymph
|
||||
Level: 85
|
||||
Hp: 6157
|
||||
Sp: 256
|
||||
Attack: 420
|
||||
Attack2: 620
|
||||
Defense: 30
|
||||
MagicDefense: 45
|
||||
Str: 40
|
||||
Agi: 50
|
||||
Vit: 40
|
||||
Int: 92
|
||||
Dex: 60
|
||||
Luk: 110
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 3
|
||||
WalkSpeed: 200
|
||||
AttackDelay: 637
|
||||
AttackMotion: 1008
|
||||
DamageMotion: 360
|
||||
Skills:
|
||||
- Name: MER_LEXDIVINA
|
||||
MaxLevel: 3
|
||||
- Name: MER_BLESSING
|
||||
MaxLevel: 5
|
||||
- Name: MER_TENDER
|
||||
MaxLevel: 1
|
||||
- Name: MER_MAGNIFICAT
|
||||
MaxLevel: 1
|
||||
- Id: 2215
|
||||
AegisName: M_KASA
|
||||
Name: Kasa
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Large
|
||||
Element: Fire
|
||||
ElementLevel: 3
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 800
|
||||
AttackMotion: 600
|
||||
DamageMotion: 288
|
||||
Skills:
|
||||
- Name: MER_CRASH
|
||||
MaxLevel: 5
|
||||
- Name: MS_MAGNUM
|
||||
MaxLevel: 5
|
||||
- Name: MER_REGAIN
|
||||
MaxLevel: 1
|
||||
- Name: MER_AUTOBERSERK
|
||||
MaxLevel: 1
|
||||
- Id: 2216
|
||||
AegisName: M_SALAMANDER
|
||||
Name: Salamander
|
||||
Level: 87
|
||||
Hp: 9517
|
||||
Sp: 260
|
||||
Attack: 900
|
||||
Attack2: 1100
|
||||
Defense: 60
|
||||
MagicDefense: 68
|
||||
Str: 90
|
||||
Agi: 80
|
||||
Vit: 65
|
||||
Int: 45
|
||||
Dex: 87
|
||||
Luk: 95
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Large
|
||||
Element: Fire
|
||||
ElementLevel: 3
|
||||
WalkSpeed: 160
|
||||
AttackDelay: 140
|
||||
AttackMotion: 384
|
||||
DamageMotion: 288
|
||||
Skills:
|
||||
- Name: MS_BASH
|
||||
MaxLevel: 5
|
||||
- Name: ML_BRANDISH
|
||||
MaxLevel: 5
|
||||
- Name: MER_AUTOBERSERK
|
||||
MaxLevel: 1
|
||||
- Name: MER_BENEDICTION
|
||||
MaxLevel: 1
|
||||
- Id: 2217
|
||||
AegisName: M_TEDDY_BEAR
|
||||
Name: Teddy Bear
|
||||
Level: 85
|
||||
Hp: 14493
|
||||
Sp: 243
|
||||
Attack: 600
|
||||
Attack2: 800
|
||||
Defense: 100
|
||||
MagicDefense: 70
|
||||
Str: 60
|
||||
Agi: 20
|
||||
Vit: 85
|
||||
Int: 50
|
||||
Dex: 75
|
||||
Luk: 130
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Element: Neutral
|
||||
ElementLevel: 3
|
||||
WalkSpeed: 200
|
||||
AttackDelay: 512
|
||||
AttackMotion: 780
|
||||
DamageMotion: 504
|
||||
Skills:
|
||||
- Name: ML_DEVOTION
|
||||
MaxLevel: 3
|
||||
- Name: MER_REGAIN
|
||||
MaxLevel: 1
|
||||
- Name: ML_DEFENDER
|
||||
MaxLevel: 1
|
||||
- Name: MER_SCAPEGOAT
|
||||
MaxLevel: 1
|
||||
- Id: 2325
|
||||
AegisName: M_BAPHOMET_
|
||||
Name: Baphomet
|
||||
Level: 57
|
||||
Hp: 7510
|
||||
Sp: 204
|
||||
Attack: 810
|
||||
Attack2: 955
|
||||
Defense: 70
|
||||
MagicDefense: 40
|
||||
Str: 52
|
||||
Agi: 60
|
||||
Vit: 36
|
||||
Int: 17
|
||||
Dex: 57
|
||||
Luk: 25
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 1
|
||||
WalkSpeed: 100
|
||||
AttackDelay: 868
|
||||
AttackMotion: 480
|
||||
DamageMotion: 120
|
||||
Skills:
|
||||
- Name: MS_BASH
|
||||
MaxLevel: 5
|
||||
- Name: MER_QUICKEN
|
||||
MaxLevel: 10
|
||||
- Id: 2326
|
||||
AegisName: M_GALAPAGO
|
||||
Name: Galapago
|
||||
Level: 45
|
||||
Hp: 7513
|
||||
Sp: 201
|
||||
Attack: 760
|
||||
Attack2: 915
|
||||
Defense: 70
|
||||
MagicDefense: 40
|
||||
Str: 30
|
||||
Agi: 28
|
||||
Vit: 29
|
||||
Int: 18
|
||||
Dex: 30
|
||||
Luk: 16
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Brute
|
||||
Element: Earth
|
||||
ElementLevel: 1
|
||||
WalkSpeed: 165
|
||||
AttackDelay: 1430
|
||||
AttackMotion: 1080
|
||||
DamageMotion: 1080
|
||||
Skills:
|
||||
- Name: MER_BLESSING
|
||||
MaxLevel: 5
|
||||
- Id: 2342
|
||||
AegisName: MER_DIABOLIC
|
||||
Name: Diabolic
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
Skills:
|
||||
- Name: MER_CRASH
|
||||
MaxLevel: 5
|
||||
- Name: MS_MAGNUM
|
||||
MaxLevel: 5
|
||||
- Name: MER_REGAIN
|
||||
MaxLevel: 1
|
||||
- Name: MER_AUTOBERSERK
|
||||
MaxLevel: 1
|
||||
- Id: 2344
|
||||
AegisName: MER_WISH_MAIDEN
|
||||
Name: Wish Maiden
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
- Id: 2345
|
||||
AegisName: MER_ZHERLTHSH
|
||||
Name: Zherlthsh
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
Skills:
|
||||
- Name: MER_CRASH
|
||||
MaxLevel: 5
|
||||
- Name: MS_MAGNUM
|
||||
MaxLevel: 5
|
||||
- Name: MER_REGAIN
|
||||
MaxLevel: 1
|
||||
- Name: MER_AUTOBERSERK
|
||||
MaxLevel: 1
|
||||
- Id: 2346
|
||||
AegisName: MER_KTULLANUX
|
||||
Name: Ktullanux
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
- Id: 2347
|
||||
AegisName: MER_EDDGA
|
||||
Name: Eddga
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
Skills:
|
||||
- Name: MER_CRASH
|
||||
MaxLevel: 5
|
||||
- Name: MS_MAGNUM
|
||||
MaxLevel: 5
|
||||
- Name: MER_REGAIN
|
||||
MaxLevel: 1
|
||||
- Name: MER_AUTOBERSERK
|
||||
MaxLevel: 1
|
||||
- Id: 2348
|
||||
AegisName: MER_CIVIL_SERVANT
|
||||
Name: Civil Servant
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
- Id: 2349
|
||||
AegisName: MER_LOLI_RURI
|
||||
Name: Loli Ruri
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
- Id: 2350
|
||||
AegisName: MER_SEDORA
|
||||
Name: Sedora
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
- Id: 2351
|
||||
AegisName: MER_CHEPET
|
||||
Name: Chepet
|
||||
Level: 83
|
||||
Hp: 9815
|
||||
Sp: 234
|
||||
Attack: 1100
|
||||
Attack2: 1300
|
||||
Defense: 60
|
||||
MagicDefense: 60
|
||||
Str: 85
|
||||
Agi: 90
|
||||
Vit: 71
|
||||
Int: 43
|
||||
Dex: 85
|
||||
Luk: 105
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Race: Demon
|
||||
Element: Dark
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 150
|
||||
AttackDelay: 1080
|
||||
AttackMotion: 780
|
||||
DamageMotion: 180
|
||||
- Id: 2378
|
||||
AegisName: MER_ANTLER_SCARABA
|
||||
Name: Antler Scaraba
|
||||
Level: 136
|
||||
Hp: 30000
|
||||
Attack: 1418
|
||||
Attack2: 1828
|
||||
Defense: 155
|
||||
MagicDefense: 102
|
||||
Str: 23
|
||||
Agi: 99
|
||||
Vit: 59
|
||||
Int: 129
|
||||
Dex: 137
|
||||
Luk: 45
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Insect
|
||||
Element: Earth
|
||||
ElementLevel: 2
|
||||
WalkSpeed: 200
|
||||
AttackDelay: 504
|
||||
AttackMotion: 624
|
||||
DamageMotion: 360
|
||||
- Id: 2937
|
||||
AegisName: M_LOKI
|
||||
Name: Loki's Shadow
|
||||
Level: 145
|
||||
Hp: 1215600
|
||||
Attack: 1835
|
||||
Attack2: 2279
|
||||
Defense: 15
|
||||
MagicDefense: 89
|
||||
Str: 76
|
||||
Agi: 66
|
||||
Vit: 90
|
||||
Int: 55
|
||||
Dex: 189
|
||||
Luk: 22
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Demihuman
|
||||
Element: Neutral
|
||||
ElementLevel: 1
|
||||
WalkSpeed: 175
|
||||
AttackDelay: 800
|
||||
AttackMotion: 750
|
||||
DamageMotion: 300
|
||||
Skills:
|
||||
- Name: MER_INVINCIBLEOFF2
|
||||
MaxLevel: 1
|
386
db/re/mob_db.yml
386
db/re/mob_db.yml
@ -40946,32 +40946,32 @@ Body:
|
||||
Drops:
|
||||
- Item: Gold_Tulip
|
||||
Rate: 10000
|
||||
# - Id: 2034
|
||||
# AegisName: M_DESERT_WOLF_B
|
||||
# Name: Baby Desert Wolf
|
||||
# Level: 9
|
||||
# Hp: 164
|
||||
# Sp: 15
|
||||
# Attack: 500
|
||||
# Attack2: 600
|
||||
# Agi: 9
|
||||
# Vit: 9
|
||||
# Int: 5
|
||||
# Dex: 40
|
||||
# Luk: 40
|
||||
# AttackRange: 1
|
||||
# SkillRange: 10
|
||||
# ChaseRange: 12
|
||||
# Size: Small
|
||||
# Race: Brute
|
||||
# Element: Fire
|
||||
# ElementLevel: 1
|
||||
# WalkSpeed: 100
|
||||
# AttackDelay: 1600
|
||||
# AttackMotion: 900
|
||||
# DamageMotion: 240
|
||||
# Modes:
|
||||
# NoRandomWalk: true
|
||||
- Id: 2034
|
||||
AegisName: M_DESERT_WOLF_B
|
||||
Name: Baby Desert Wolf
|
||||
Level: 9
|
||||
Hp: 164
|
||||
Sp: 15
|
||||
Attack: 500
|
||||
Attack2: 600
|
||||
Agi: 9
|
||||
Vit: 9
|
||||
Int: 5
|
||||
Dex: 40
|
||||
Luk: 40
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Small
|
||||
Race: Brute
|
||||
Element: Fire
|
||||
ElementLevel: 1
|
||||
WalkSpeed: 100
|
||||
AttackDelay: 1600
|
||||
AttackMotion: 900
|
||||
DamageMotion: 240
|
||||
Modes:
|
||||
NoRandomWalk: true
|
||||
- Id: 2035
|
||||
AegisName: NIHILITY_ZEM
|
||||
Name: Nihility Zem
|
||||
@ -41026,60 +41026,60 @@ Body:
|
||||
- Item: Broken_Horn_Pipe
|
||||
Rate: 2500
|
||||
StealProtected: true
|
||||
# - Id: 2037
|
||||
# AegisName: VALKYRIE_A
|
||||
# Name: Valkyrie Randgris
|
||||
# Level: 90
|
||||
# Hp: 5500
|
||||
# Sp: 15
|
||||
# Attack: 10
|
||||
# Attack2: 160
|
||||
# Defense: 16
|
||||
# MagicDefense: 20
|
||||
# Agi: 20
|
||||
# Vit: 40
|
||||
# Dex: 20
|
||||
# Luk: 20
|
||||
# AttackRange: 1
|
||||
# SkillRange: 10
|
||||
# ChaseRange: 12
|
||||
# Size: Medium
|
||||
# Race: Angel
|
||||
# Element: Holy
|
||||
# ElementLevel: 3
|
||||
# WalkSpeed: 100
|
||||
# AttackDelay: 576
|
||||
# AttackMotion: 576
|
||||
# DamageMotion: 480
|
||||
# Modes:
|
||||
# NoRandomWalk: true
|
||||
# - Id: 2038
|
||||
# AegisName: VALKYRIE_B
|
||||
# Name: Valkyrie Randgris
|
||||
# Level: 90
|
||||
# Hp: 10500
|
||||
# Sp: 15
|
||||
# Attack: 300
|
||||
# Attack2: 450
|
||||
# Defense: 16
|
||||
# MagicDefense: 40
|
||||
# Agi: 20
|
||||
# Vit: 80
|
||||
# Dex: 80
|
||||
# Luk: 20
|
||||
# AttackRange: 1
|
||||
# SkillRange: 10
|
||||
# ChaseRange: 12
|
||||
# Size: Medium
|
||||
# Race: Angel
|
||||
# Element: Holy
|
||||
# ElementLevel: 3
|
||||
# WalkSpeed: 100
|
||||
# AttackDelay: 576
|
||||
# AttackMotion: 576
|
||||
# DamageMotion: 480
|
||||
# Modes:
|
||||
# NoRandomWalk: true
|
||||
- Id: 2037
|
||||
AegisName: VALKYRIE_A
|
||||
Name: Valkyrie Randgris
|
||||
Level: 90
|
||||
Hp: 5500
|
||||
Sp: 15
|
||||
Attack: 10
|
||||
Attack2: 160
|
||||
Defense: 16
|
||||
MagicDefense: 20
|
||||
Agi: 20
|
||||
Vit: 40
|
||||
Dex: 20
|
||||
Luk: 20
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Angel
|
||||
Element: Holy
|
||||
ElementLevel: 3
|
||||
WalkSpeed: 100
|
||||
AttackDelay: 576
|
||||
AttackMotion: 576
|
||||
DamageMotion: 480
|
||||
Modes:
|
||||
NoRandomWalk: true
|
||||
- Id: 2038
|
||||
AegisName: VALKYRIE_B
|
||||
Name: Valkyrie Randgris
|
||||
Level: 90
|
||||
Hp: 10500
|
||||
Sp: 15
|
||||
Attack: 300
|
||||
Attack2: 450
|
||||
Defense: 16
|
||||
MagicDefense: 40
|
||||
Agi: 20
|
||||
Vit: 80
|
||||
Dex: 80
|
||||
Luk: 20
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Angel
|
||||
Element: Holy
|
||||
ElementLevel: 3
|
||||
WalkSpeed: 100
|
||||
AttackDelay: 576
|
||||
AttackMotion: 576
|
||||
DamageMotion: 480
|
||||
Modes:
|
||||
NoRandomWalk: true
|
||||
- Id: 2039
|
||||
AegisName: EXECUTIONER_R
|
||||
Name: Executioner
|
||||
@ -41661,91 +41661,91 @@ Body:
|
||||
AttackMotion: 500
|
||||
DamageMotion: 1000
|
||||
Ai: 09
|
||||
# - Id: 2058
|
||||
# AegisName: M_MIMIC
|
||||
# Name: Mimic
|
||||
# Level: 51
|
||||
# Hp: 6120
|
||||
# Sp: 182
|
||||
# Attack: 800
|
||||
# Attack2: 950
|
||||
# Defense: 10
|
||||
# MagicDefense: 40
|
||||
# Str: 44
|
||||
# Agi: 121
|
||||
# Int: 60
|
||||
# Dex: 75
|
||||
# Luk: 110
|
||||
# AttackRange: 1
|
||||
# SkillRange: 10
|
||||
# ChaseRange: 12
|
||||
# Size: Medium
|
||||
# Race: Formless
|
||||
# Element: Neutral
|
||||
# ElementLevel: 3
|
||||
# WalkSpeed: 100
|
||||
# AttackDelay: 972
|
||||
# AttackMotion: 500
|
||||
# DamageMotion: 288
|
||||
# Modes:
|
||||
# NoRandomWalk: true
|
||||
# - Id: 2059
|
||||
# AegisName: M_DISGUISE
|
||||
# Name: Disguise
|
||||
# Level: 55
|
||||
# Hp: 7543
|
||||
# Sp: 180
|
||||
# Attack: 526
|
||||
# Attack2: 693
|
||||
# Defense: 18
|
||||
# MagicDefense: 29
|
||||
# Agi: 72
|
||||
# Vit: 45
|
||||
# Int: 35
|
||||
# Dex: 48
|
||||
# Luk: 65
|
||||
# AttackRange: 2
|
||||
# SkillRange: 10
|
||||
# ChaseRange: 12
|
||||
# Size: Medium
|
||||
# Race: Demon
|
||||
# Element: Earth
|
||||
# ElementLevel: 4
|
||||
# WalkSpeed: 147
|
||||
# AttackDelay: 516
|
||||
# AttackMotion: 768
|
||||
# DamageMotion: 384
|
||||
# Modes:
|
||||
# NoRandomWalk: true
|
||||
# - Id: 2060
|
||||
# AegisName: M_ALICE
|
||||
# Name: Alice
|
||||
# Level: 62
|
||||
# Hp: 10000
|
||||
# Sp: 221
|
||||
# Attack: 700
|
||||
# Attack2: 850
|
||||
# Defense: 5
|
||||
# MagicDefense: 5
|
||||
# Str: 64
|
||||
# Agi: 64
|
||||
# Vit: 42
|
||||
# Int: 85
|
||||
# Dex: 100
|
||||
# Luk: 130
|
||||
# AttackRange: 1
|
||||
# SkillRange: 10
|
||||
# ChaseRange: 12
|
||||
# Size: Medium
|
||||
# Race: Demihuman
|
||||
# Element: Neutral
|
||||
# ElementLevel: 3
|
||||
# WalkSpeed: 200
|
||||
# AttackDelay: 502
|
||||
# AttackMotion: 1999
|
||||
# DamageMotion: 480
|
||||
# Modes:
|
||||
# NoRandomWalk: true
|
||||
- Id: 2058
|
||||
AegisName: M_MIMIC
|
||||
Name: Mimic
|
||||
Level: 51
|
||||
Hp: 6120
|
||||
Sp: 182
|
||||
Attack: 800
|
||||
Attack2: 950
|
||||
Defense: 10
|
||||
MagicDefense: 40
|
||||
Str: 44
|
||||
Agi: 121
|
||||
Int: 60
|
||||
Dex: 75
|
||||
Luk: 110
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Formless
|
||||
Element: Neutral
|
||||
ElementLevel: 3
|
||||
WalkSpeed: 100
|
||||
AttackDelay: 972
|
||||
AttackMotion: 500
|
||||
DamageMotion: 288
|
||||
Modes:
|
||||
NoRandomWalk: true
|
||||
- Id: 2059
|
||||
AegisName: M_DISGUISE
|
||||
Name: Disguise
|
||||
Level: 55
|
||||
Hp: 7543
|
||||
Sp: 180
|
||||
Attack: 526
|
||||
Attack2: 693
|
||||
Defense: 18
|
||||
MagicDefense: 29
|
||||
Agi: 72
|
||||
Vit: 45
|
||||
Int: 35
|
||||
Dex: 48
|
||||
Luk: 65
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Demon
|
||||
Element: Earth
|
||||
ElementLevel: 4
|
||||
WalkSpeed: 147
|
||||
AttackDelay: 516
|
||||
AttackMotion: 768
|
||||
DamageMotion: 384
|
||||
Modes:
|
||||
NoRandomWalk: true
|
||||
- Id: 2060
|
||||
AegisName: M_ALICE
|
||||
Name: Alice
|
||||
Level: 62
|
||||
Hp: 10000
|
||||
Sp: 221
|
||||
Attack: 700
|
||||
Attack2: 850
|
||||
Defense: 5
|
||||
MagicDefense: 5
|
||||
Str: 64
|
||||
Agi: 64
|
||||
Vit: 42
|
||||
Int: 85
|
||||
Dex: 100
|
||||
Luk: 130
|
||||
AttackRange: 1
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Demihuman
|
||||
Element: Neutral
|
||||
ElementLevel: 3
|
||||
WalkSpeed: 200
|
||||
AttackDelay: 502
|
||||
AttackMotion: 1999
|
||||
DamageMotion: 480
|
||||
Modes:
|
||||
NoRandomWalk: true
|
||||
# - Id: 2061
|
||||
# AegisName: E_STAPO
|
||||
# Name: Stapo
|
||||
@ -74745,34 +74745,34 @@ Body:
|
||||
- Item: Halloween_Coin
|
||||
Rate: 10000
|
||||
StealProtected: true
|
||||
# - Id: 2937
|
||||
# AegisName: M_LOKI
|
||||
# Name: M Loki
|
||||
# Level: 145
|
||||
# Hp: 1215600
|
||||
# BaseExp: 1
|
||||
# JobExp: 1
|
||||
# Attack: 1835
|
||||
# Attack2: 444
|
||||
# Defense: 15
|
||||
# MagicDefense: 89
|
||||
# Str: 76
|
||||
# Agi: 66
|
||||
# Vit: 90
|
||||
# Int: 55
|
||||
# Dex: 189
|
||||
# Luk: 22
|
||||
# AttackRange: 2
|
||||
# SkillRange: 10
|
||||
# ChaseRange: 12
|
||||
# Size: Medium
|
||||
# Race: Demihuman
|
||||
# Element: Neutral
|
||||
# ElementLevel: 1
|
||||
# WalkSpeed: 175
|
||||
# AttackDelay: 800
|
||||
# AttackMotion: 750
|
||||
# DamageMotion: 300
|
||||
- Id: 2937
|
||||
AegisName: M_LOKI
|
||||
Name: M Loki
|
||||
Level: 145
|
||||
Hp: 1215600
|
||||
BaseExp: 1
|
||||
JobExp: 1
|
||||
Attack: 1835
|
||||
Attack2: 444
|
||||
Defense: 15
|
||||
MagicDefense: 89
|
||||
Str: 76
|
||||
Agi: 66
|
||||
Vit: 90
|
||||
Int: 55
|
||||
Dex: 189
|
||||
Luk: 22
|
||||
AttackRange: 2
|
||||
SkillRange: 10
|
||||
ChaseRange: 12
|
||||
Size: Medium
|
||||
Race: Demihuman
|
||||
Element: Neutral
|
||||
ElementLevel: 1
|
||||
WalkSpeed: 175
|
||||
AttackDelay: 800
|
||||
AttackMotion: 750
|
||||
DamageMotion: 300
|
||||
- Id: 2938
|
||||
AegisName: MM_MAGIC_SEAL
|
||||
Name: Magic Seal
|
||||
|
38
doc/yaml/db/mercenary_db.yml
Normal file
38
doc/yaml/db/mercenary_db.yml
Normal file
@ -0,0 +1,38 @@
|
||||
###########################################################################
|
||||
# Mercenary Database
|
||||
###########################################################################
|
||||
#
|
||||
# Mercenary Settings
|
||||
#
|
||||
###########################################################################
|
||||
# - Id Mercenary ID.
|
||||
# AegisName Server name to reference the mercenary in scripts and lookups, should use no spaces.
|
||||
# Name Name in English.
|
||||
# Level Level. (Default: 1)
|
||||
# Hp Total HP. (Default: 1)
|
||||
# Sp Total SP. (Default: 1)
|
||||
# Attack Minimum attack. (Default: 0)
|
||||
# Attack2 Maximum attack. (Default: 0)
|
||||
# Defense Physical defense of the mercenary, reduces melee and ranged physical attack/skill damage. (Default: 0)
|
||||
# MagicDefense Magic defense of the mercenary, reduces magical skill damage. (Default: 0)
|
||||
# Str Strength which affects attack. (Default: 1)
|
||||
# Agi Agility which affects flee. (Default: 1)
|
||||
# Vit Vitality which affects defense. (Default: 1)
|
||||
# Int Intelligence which affects magic attack. (Default: 1)
|
||||
# Dex Dexterity which affects hit rate. (Default: 1)
|
||||
# Luk Luck which affects perfect dodge/lucky flee/perfect flee/lucky dodge rate. (Default: 1)
|
||||
# AttackRange Attack range. (Default: 0)
|
||||
# SkillRange Skill cast range. (Default: 0)
|
||||
# ChaseRange Chase range. (Default: 0)
|
||||
# Size Size. (Default: Small)
|
||||
# Race Race. (Default: Formless)
|
||||
# Element Element. (Default: Neutral)
|
||||
# ElementLevel Level of element. (Default: 1)
|
||||
# WalkSpeed Walk speed. (Default: DEFAULT_WALK_SPEED)
|
||||
# AttackDelay Attack speed. (Default: 4000)
|
||||
# AttackMotion Attack animation speed. (Default: 2000)
|
||||
# DamageMotion Damage animation speed. (Default: 0)
|
||||
# Skills: List of mercenary skills. (Optional)
|
||||
# - Name Skill name.
|
||||
# MaxLevel Max skill level.
|
||||
###########################################################################
|
@ -4036,14 +4036,12 @@ ACMD_FUNC(reload) {
|
||||
mob_reload();
|
||||
pet_db.reload();
|
||||
hom_reload();
|
||||
mercenary_readdb();
|
||||
mercenary_read_skilldb();
|
||||
mercenary_db.reload();
|
||||
elemental_db.reload();
|
||||
clif_displaymessage(fd, msg_txt(sd,98)); // Monster database has been reloaded.
|
||||
} else if (strstr(command, "skilldb") || strncmp(message, "skilldb", 4) == 0) {
|
||||
skill_reload();
|
||||
hom_reload_skill();
|
||||
mercenary_read_skilldb();
|
||||
clif_displaymessage(fd, msg_txt(sd,99)); // Skill database has been reloaded.
|
||||
} else if (strstr(command, "atcommand") || strncmp(message, "atcommand", 4) == 0) {
|
||||
config_t run_test;
|
||||
|
@ -124,7 +124,7 @@ int battle_gettarget(struct block_list* bl)
|
||||
case BL_MOB: return ((struct mob_data*)bl)->target_id;
|
||||
case BL_PET: return ((struct pet_data*)bl)->target_id;
|
||||
case BL_HOM: return ((struct homun_data*)bl)->ud.target;
|
||||
case BL_MER: return ((struct mercenary_data*)bl)->ud.target;
|
||||
case BL_MER: return ((s_mercenary_data*)bl)->ud.target;
|
||||
case BL_ELEM: return ((s_elemental_data*)bl)->ud.target;
|
||||
}
|
||||
|
||||
|
@ -8309,7 +8309,7 @@ void clif_devotion(struct block_list *src, struct map_session_data *tsd)
|
||||
WBUFL(buf,2) = src->id;
|
||||
if( src->type == BL_MER )
|
||||
{
|
||||
struct mercenary_data *md = BL_CAST(BL_MER,src);
|
||||
s_mercenary_data *md = BL_CAST(BL_MER,src);
|
||||
if( md && md->master && md->devotion_flag )
|
||||
WBUFL(buf,6) = md->master->bl.id;
|
||||
|
||||
@ -9836,7 +9836,7 @@ void clif_name( struct block_list* src, struct block_list *bl, send_target targe
|
||||
memcpy(packet.name, ((TBL_HOM *)bl)->homunculus.name, NAME_LENGTH);
|
||||
break;
|
||||
case BL_MER:
|
||||
memcpy(packet.name, ((TBL_MER *)bl)->db->name, NAME_LENGTH);
|
||||
memcpy(packet.name, ((TBL_MER *)bl)->db->name.c_str(), NAME_LENGTH);
|
||||
break;
|
||||
case BL_PET:
|
||||
safestrncpy(packet.name, ((TBL_PET *)bl)->pet.name, NAME_LENGTH);
|
||||
@ -12542,7 +12542,7 @@ static void clif_parse_UseSkillToPos_homun(struct homun_data *hd, struct map_ses
|
||||
unit_skilluse_pos(&hd->bl, x, y, skill_id, skill_lv);
|
||||
}
|
||||
|
||||
static void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct map_session_data *sd, t_tick tick, uint16 skill_id, uint16 skill_lv, int target_id)
|
||||
static void clif_parse_UseSkillToId_mercenary(s_mercenary_data *md, struct map_session_data *sd, t_tick tick, uint16 skill_id, uint16 skill_lv, int target_id)
|
||||
{
|
||||
int lv;
|
||||
|
||||
@ -12566,7 +12566,7 @@ static void clif_parse_UseSkillToId_mercenary(struct mercenary_data *md, struct
|
||||
unit_skilluse_id(&md->bl, target_id, skill_id, skill_lv);
|
||||
}
|
||||
|
||||
static void clif_parse_UseSkillToPos_mercenary(struct mercenary_data *md, struct map_session_data *sd, t_tick tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo)
|
||||
static void clif_parse_UseSkillToPos_mercenary(s_mercenary_data *md, struct map_session_data *sd, t_tick tick, uint16 skill_id, uint16 skill_lv, short x, short y, int skillmoreinfo)
|
||||
{
|
||||
int lv;
|
||||
if( !md )
|
||||
@ -17696,7 +17696,7 @@ void clif_quest_show_event(struct map_session_data *sd, struct block_list *bl, e
|
||||
/// 02a2 <var id>.W <value>.L
|
||||
void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
|
||||
{
|
||||
struct mercenary_data *md;
|
||||
s_mercenary_data *md;
|
||||
struct status_data *status;
|
||||
int fd;
|
||||
if( !clif_session_isValid(sd) || (md = sd->md) == NULL )
|
||||
@ -17765,7 +17765,7 @@ void clif_mercenary_updatestatus(struct map_session_data *sd, int type)
|
||||
void clif_mercenary_info(struct map_session_data *sd)
|
||||
{
|
||||
int fd;
|
||||
struct mercenary_data *md;
|
||||
s_mercenary_data *md;
|
||||
struct status_data *status;
|
||||
int atk;
|
||||
|
||||
@ -17789,7 +17789,7 @@ void clif_mercenary_info(struct map_session_data *sd)
|
||||
WFIFOW(fd,16) = status->mdef;
|
||||
WFIFOW(fd,18) = status->flee;
|
||||
WFIFOW(fd,20) = status->amotion;
|
||||
safestrncpy(WFIFOCP(fd,22), md->db->name, NAME_LENGTH);
|
||||
safestrncpy(WFIFOCP(fd,22), md->db->name.c_str(), NAME_LENGTH);
|
||||
WFIFOW(fd,46) = md->db->lv;
|
||||
WFIFOL(fd,48) = status->hp;
|
||||
WFIFOL(fd,52) = status->max_hp;
|
||||
@ -17808,8 +17808,8 @@ void clif_mercenary_info(struct map_session_data *sd)
|
||||
/// 029d <packet len>.W { <skill id>.W <type>.L <level>.W <sp cost>.W <attack range>.W <skill name>.24B <upgradable>.B }*
|
||||
void clif_mercenary_skillblock(struct map_session_data *sd)
|
||||
{
|
||||
struct mercenary_data *md;
|
||||
int fd, i, len = 4;
|
||||
s_mercenary_data *md;
|
||||
int fd, len = 4;
|
||||
|
||||
if( sd == NULL || (md = sd->md) == NULL )
|
||||
return;
|
||||
@ -17817,20 +17817,19 @@ void clif_mercenary_skillblock(struct map_session_data *sd)
|
||||
fd = sd->fd;
|
||||
WFIFOHEAD(fd,4+37*MAX_MERCSKILL);
|
||||
WFIFOW(fd,0) = 0x29d;
|
||||
for( i = 0; i < MAX_MERCSKILL; i++ )
|
||||
{
|
||||
uint16 id;
|
||||
short idx = -1;
|
||||
if( (id = md->db->skill[i].id) == 0 )
|
||||
continue;
|
||||
if ((idx = mercenary_skill_get_index(id)) == -1)
|
||||
for (const auto &it : md->db->skill) {
|
||||
uint16 id = it.first;
|
||||
|
||||
if (!SKILL_CHK_MERC(id))
|
||||
continue;
|
||||
|
||||
uint16 lv = it.second;
|
||||
|
||||
WFIFOW(fd,len) = id;
|
||||
WFIFOL(fd,len+2) = skill_get_inf(id);
|
||||
WFIFOW(fd,len+6) = md->db->skill[idx].lv;
|
||||
WFIFOW(fd,len+8) = skill_get_sp(id, md->db->skill[idx].lv);
|
||||
WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, md->db->skill[idx].lv, false);
|
||||
WFIFOW(fd,len+6) = lv;
|
||||
WFIFOW(fd,len+8) = skill_get_sp(id, lv);
|
||||
WFIFOW(fd,len+10) = skill_get_range2(&md->bl, id, lv, false);
|
||||
safestrncpy(WFIFOCP(fd,len+12), skill_get_name(id), NAME_LENGTH);
|
||||
WFIFOB(fd,len+36) = 0; // Skillable for Mercenary?
|
||||
len += 37;
|
||||
|
@ -323,8 +323,7 @@
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\magicmushroom_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\magicmushroom_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\map_cache.dat" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\map_cache.dat')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\map_index.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\map_index.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\mercenary_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mercenary_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\mercenary_skill_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mercenary_skill_db.txt')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\mercenary_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mercenary_db.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_avail.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_avail.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_summon.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_summon.yml')" />
|
||||
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\mob_chat_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\mob_chat_db.yml')" />
|
||||
|
@ -2239,7 +2239,7 @@ struct homun_data* map_id2hd(int id){
|
||||
return BL_CAST(BL_HOM, bl);
|
||||
}
|
||||
|
||||
struct mercenary_data* map_id2mc(int id){
|
||||
struct s_mercenary_data* map_id2mc(int id){
|
||||
struct block_list* bl = map_id2bl(id);
|
||||
return BL_CAST(BL_MER, bl);
|
||||
}
|
||||
|
@ -1087,7 +1087,7 @@ struct map_session_data * map_id2sd(int id);
|
||||
struct mob_data * map_id2md(int id);
|
||||
struct npc_data * map_id2nd(int id);
|
||||
struct homun_data* map_id2hd(int id);
|
||||
struct mercenary_data* map_id2mc(int id);
|
||||
struct s_mercenary_data* map_id2mc(int id);
|
||||
struct pet_data* map_id2pd(int id);
|
||||
struct s_elemental_data* map_id2ed(int id);
|
||||
struct chat_data* map_id2cd(int id);
|
||||
@ -1195,7 +1195,7 @@ typedef struct chat_data TBL_CHAT;
|
||||
typedef struct skill_unit TBL_SKILL;
|
||||
typedef struct pet_data TBL_PET;
|
||||
typedef struct homun_data TBL_HOM;
|
||||
typedef struct mercenary_data TBL_MER;
|
||||
typedef struct s_mercenary_data TBL_MER;
|
||||
typedef struct s_elemental_data TBL_ELEM;
|
||||
|
||||
#define BL_CAST(type_, bl) \
|
||||
|
@ -29,16 +29,7 @@
|
||||
|
||||
using namespace rathena;
|
||||
|
||||
std::map<uint16, struct s_mercenary_db> mercenary_db_data;
|
||||
|
||||
/**
|
||||
* Search Mercenary by class
|
||||
* @param class_ Class ID of Mercenary
|
||||
* @return A pointer to the mercenary db entry or nullptr if not found
|
||||
**/
|
||||
struct s_mercenary_db *mercenary_db( uint16 class_ ){
|
||||
return util::map_find( mercenary_db_data, class_ );
|
||||
}
|
||||
MercenaryDatabase mercenary_db;
|
||||
|
||||
/**
|
||||
* Get View Data of Mercenary by Class ID
|
||||
@ -46,7 +37,7 @@ struct s_mercenary_db *mercenary_db( uint16 class_ ){
|
||||
* @return View Data of Mercenary
|
||||
**/
|
||||
struct view_data *mercenary_get_viewdata( uint16 class_ ){
|
||||
struct s_mercenary_db *db = mercenary_db(class_);
|
||||
std::shared_ptr<s_mercenary_db> db = mercenary_db.find(class_);
|
||||
|
||||
if( db ){
|
||||
return &db->vd;
|
||||
@ -55,20 +46,6 @@ struct view_data *mercenary_get_viewdata( uint16 class_ ){
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get mercenary skill index for mercenary skill tree
|
||||
* @param skill_id
|
||||
* @return Index in skill_tree or -1
|
||||
**/
|
||||
short mercenary_skill_get_index(uint16 skill_id) {
|
||||
if (!SKILL_CHK_MERC(skill_id))
|
||||
return -1;
|
||||
skill_id -= MC_SKILLBASE;
|
||||
if (skill_id >= MAX_MERCSKILL)
|
||||
return -1;
|
||||
return skill_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new Mercenary for Player
|
||||
* @param sd The Player
|
||||
@ -76,18 +53,17 @@ short mercenary_skill_get_index(uint16 skill_id) {
|
||||
* @param lifetime Contract duration
|
||||
* @return false if failed, true otherwise
|
||||
**/
|
||||
bool mercenary_create(struct map_session_data *sd, uint16 class_, unsigned int lifetime) {
|
||||
struct s_mercenary merc;
|
||||
struct s_mercenary_db *db;
|
||||
bool mercenary_create(map_session_data *sd, uint16 class_, unsigned int lifetime) {
|
||||
nullpo_retr(false,sd);
|
||||
|
||||
db = mercenary_db(class_);
|
||||
std::shared_ptr<s_mercenary_db> db = mercenary_db.find(class_);
|
||||
|
||||
if( !db ){
|
||||
if (db == nullptr) {
|
||||
ShowError("mercenary_create: Unknown mercenary class %d.\n", class_);
|
||||
return false;
|
||||
}
|
||||
|
||||
memset(&merc,0,sizeof(struct s_mercenary));
|
||||
s_mercenary merc = {};
|
||||
|
||||
merc.char_id = sd->status.char_id;
|
||||
merc.class_ = class_;
|
||||
@ -106,12 +82,11 @@ bool mercenary_create(struct map_session_data *sd, uint16 class_, unsigned int l
|
||||
* @param md The Mercenary
|
||||
* @return The Lifetime
|
||||
**/
|
||||
t_tick mercenary_get_lifetime(struct mercenary_data *md) {
|
||||
const struct TimerData * td;
|
||||
t_tick mercenary_get_lifetime(s_mercenary_data *md) {
|
||||
if( md == NULL || md->contract_timer == INVALID_TIMER )
|
||||
return 0;
|
||||
|
||||
td = get_timer(md->contract_timer);
|
||||
const struct TimerData *td = get_timer(md->contract_timer);
|
||||
return (td != NULL) ? DIFF_TICK(td->tick, gettick()) : 0;
|
||||
}
|
||||
|
||||
@ -120,13 +95,11 @@ t_tick mercenary_get_lifetime(struct mercenary_data *md) {
|
||||
* @param md Mercenary
|
||||
* @return enum e_MercGuildType
|
||||
**/
|
||||
enum e_MercGuildType mercenary_get_guild(struct mercenary_data *md){
|
||||
uint16 class_;
|
||||
|
||||
e_MercGuildType mercenary_get_guild(s_mercenary_data *md){
|
||||
if( md == NULL || md->db == NULL )
|
||||
return NONE_MERC_GUILD;
|
||||
|
||||
class_ = md->db->class_;
|
||||
uint16 class_ = md->db->class_;
|
||||
|
||||
if( class_ >= MERID_MER_ARCHER01 && class_ <= MERID_MER_ARCHER10 )
|
||||
return ARCH_MERC_GUILD;
|
||||
@ -143,14 +116,13 @@ enum e_MercGuildType mercenary_get_guild(struct mercenary_data *md){
|
||||
* @param md Mercenary
|
||||
* @return the Faith value
|
||||
**/
|
||||
int mercenary_get_faith(struct mercenary_data *md) {
|
||||
struct map_session_data *sd;
|
||||
enum e_MercGuildType guild;
|
||||
int mercenary_get_faith(s_mercenary_data *md) {
|
||||
map_session_data *sd;
|
||||
|
||||
if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
|
||||
return 0;
|
||||
|
||||
guild = mercenary_get_guild(md);
|
||||
e_MercGuildType guild = mercenary_get_guild(md);
|
||||
|
||||
switch( guild ){
|
||||
case ARCH_MERC_GUILD:
|
||||
@ -170,15 +142,14 @@ int mercenary_get_faith(struct mercenary_data *md) {
|
||||
* @param md The Mercenary
|
||||
* @param value Faith Value
|
||||
**/
|
||||
void mercenary_set_faith(struct mercenary_data *md, int value) {
|
||||
struct map_session_data *sd;
|
||||
enum e_MercGuildType guild;
|
||||
int *faith;
|
||||
void mercenary_set_faith(s_mercenary_data *md, int value) {
|
||||
map_session_data *sd;
|
||||
|
||||
if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
|
||||
return;
|
||||
|
||||
guild = mercenary_get_guild(md);
|
||||
e_MercGuildType guild = mercenary_get_guild(md);
|
||||
int *faith = nullptr;
|
||||
|
||||
switch( guild ){
|
||||
case ARCH_MERC_GUILD:
|
||||
@ -204,14 +175,13 @@ void mercenary_set_faith(struct mercenary_data *md, int value) {
|
||||
* @param md Mercenary
|
||||
* @return Number of calls
|
||||
**/
|
||||
int mercenary_get_calls(struct mercenary_data *md) {
|
||||
struct map_session_data *sd;
|
||||
enum e_MercGuildType guild;
|
||||
int mercenary_get_calls(s_mercenary_data *md) {
|
||||
map_session_data *sd;
|
||||
|
||||
if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
|
||||
return 0;
|
||||
|
||||
guild = mercenary_get_guild(md);
|
||||
e_MercGuildType guild = mercenary_get_guild(md);
|
||||
|
||||
switch( guild ){
|
||||
case ARCH_MERC_GUILD:
|
||||
@ -231,15 +201,14 @@ int mercenary_get_calls(struct mercenary_data *md) {
|
||||
* @param md Mercenary
|
||||
* @param value
|
||||
**/
|
||||
void mercenary_set_calls(struct mercenary_data *md, int value) {
|
||||
struct map_session_data *sd;
|
||||
enum e_MercGuildType guild;
|
||||
int *calls;
|
||||
void mercenary_set_calls(s_mercenary_data *md, int value) {
|
||||
map_session_data *sd;
|
||||
|
||||
if( md == NULL || md->db == NULL || (sd = md->master) == NULL )
|
||||
return;
|
||||
|
||||
guild = mercenary_get_guild(md);
|
||||
e_MercGuildType guild = mercenary_get_guild(md);
|
||||
int *calls = nullptr;
|
||||
|
||||
switch( guild ){
|
||||
case ARCH_MERC_GUILD:
|
||||
@ -263,7 +232,7 @@ void mercenary_set_calls(struct mercenary_data *md, int value) {
|
||||
* Save Mercenary data
|
||||
* @param md Mercenary
|
||||
**/
|
||||
void mercenary_save(struct mercenary_data *md) {
|
||||
void mercenary_save(s_mercenary_data *md) {
|
||||
md->mercenary.hp = md->battle_status.hp;
|
||||
md->mercenary.sp = md->battle_status.sp;
|
||||
md->mercenary.life_time = mercenary_get_lifetime(md);
|
||||
@ -275,8 +244,8 @@ void mercenary_save(struct mercenary_data *md) {
|
||||
* Ends contract of Mercenary
|
||||
**/
|
||||
static TIMER_FUNC(merc_contract_end){
|
||||
struct map_session_data *sd;
|
||||
struct mercenary_data *md;
|
||||
map_session_data *sd;
|
||||
s_mercenary_data *md;
|
||||
|
||||
if( (sd = map_id2sd(id)) == NULL )
|
||||
return 1;
|
||||
@ -300,8 +269,8 @@ static TIMER_FUNC(merc_contract_end){
|
||||
* @param md Mercenary
|
||||
* @param reply
|
||||
**/
|
||||
int mercenary_delete(struct mercenary_data *md, int reply) {
|
||||
struct map_session_data *sd = md->master;
|
||||
int mercenary_delete(s_mercenary_data *md, int reply) {
|
||||
map_session_data *sd = md->master;
|
||||
md->mercenary.life_time = 0;
|
||||
|
||||
mercenary_contract_stop(md);
|
||||
@ -329,7 +298,7 @@ int mercenary_delete(struct mercenary_data *md, int reply) {
|
||||
* Stop contract of Mercenary
|
||||
* @param md Mercenary
|
||||
**/
|
||||
void mercenary_contract_stop(struct mercenary_data *md) {
|
||||
void mercenary_contract_stop(s_mercenary_data *md) {
|
||||
nullpo_retv(md);
|
||||
if( md->contract_timer != INVALID_TIMER )
|
||||
delete_timer(md->contract_timer, merc_contract_end);
|
||||
@ -340,7 +309,7 @@ void mercenary_contract_stop(struct mercenary_data *md) {
|
||||
* Init contract of Mercenary
|
||||
* @param md Mercenary
|
||||
**/
|
||||
void merc_contract_init(struct mercenary_data *md) {
|
||||
void merc_contract_init(s_mercenary_data *md) {
|
||||
if( md->contract_timer == INVALID_TIMER )
|
||||
md->contract_timer = add_timer(gettick() + md->mercenary.life_time, merc_contract_end, md->master->bl.id, 0);
|
||||
|
||||
@ -353,30 +322,31 @@ void merc_contract_init(struct mercenary_data *md) {
|
||||
* @param flag : if inter-serv request was sucessfull
|
||||
* @return false:failure, true:sucess
|
||||
*/
|
||||
bool mercenary_recv_data(struct s_mercenary *merc, bool flag)
|
||||
bool mercenary_recv_data(s_mercenary *merc, bool flag)
|
||||
{
|
||||
struct map_session_data *sd;
|
||||
struct mercenary_data *md;
|
||||
struct s_mercenary_db *db;
|
||||
|
||||
db = mercenary_db(merc->class_);
|
||||
map_session_data *sd;
|
||||
|
||||
if( (sd = map_charid2sd(merc->char_id)) == NULL )
|
||||
return false;
|
||||
|
||||
std::shared_ptr<s_mercenary_db> db = mercenary_db.find(merc->class_);
|
||||
|
||||
if( !flag || !db ){ // Not created - loaded - DB info
|
||||
sd->status.mer_id = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
s_mercenary_data *md;
|
||||
|
||||
if( !sd->md ) {
|
||||
sd->md = md = (struct mercenary_data*)aCalloc(1,sizeof(struct mercenary_data));
|
||||
sd->md = md = (s_mercenary_data*)aCalloc(1,sizeof(s_mercenary_data));
|
||||
md->bl.type = BL_MER;
|
||||
md->bl.id = npc_get_new_npc_id();
|
||||
md->devotion_flag = 0;
|
||||
|
||||
md->master = sd;
|
||||
md->db = db;
|
||||
memcpy(&md->mercenary, merc, sizeof(struct s_mercenary));
|
||||
memcpy(&md->mercenary, merc, sizeof(s_mercenary));
|
||||
status_set_viewdata(&md->bl, md->mercenary.class_);
|
||||
status_change_init(&md->bl);
|
||||
unit_dataset(&md->bl);
|
||||
@ -395,7 +365,7 @@ bool mercenary_recv_data(struct s_mercenary *merc, bool flag)
|
||||
md->masterteleport_timer = INVALID_TIMER;
|
||||
merc_contract_init(md);
|
||||
} else {
|
||||
memcpy(&sd->md->mercenary, merc, sizeof(struct s_mercenary));
|
||||
memcpy(&sd->md->mercenary, merc, sizeof(s_mercenary));
|
||||
md = sd->md;
|
||||
}
|
||||
|
||||
@ -420,7 +390,7 @@ bool mercenary_recv_data(struct s_mercenary *merc, bool flag)
|
||||
* @param hp HP amount
|
||||
* @param sp SP amount
|
||||
**/
|
||||
void mercenary_heal(struct mercenary_data *md, int hp, int sp) {
|
||||
void mercenary_heal(s_mercenary_data *md, int hp, int sp) {
|
||||
if (md->master == NULL)
|
||||
return;
|
||||
if( hp )
|
||||
@ -434,7 +404,7 @@ void mercenary_heal(struct mercenary_data *md, int hp, int sp) {
|
||||
* @param md: Mercenary
|
||||
* @return false for status_damage
|
||||
*/
|
||||
bool mercenary_dead(struct mercenary_data *md) {
|
||||
bool mercenary_dead(s_mercenary_data *md) {
|
||||
mercenary_delete(md, 1);
|
||||
return false;
|
||||
}
|
||||
@ -443,18 +413,17 @@ bool mercenary_dead(struct mercenary_data *md) {
|
||||
* Gives bonus to Mercenary
|
||||
* @param md Mercenary
|
||||
**/
|
||||
void mercenary_killbonus(struct mercenary_data *md) {
|
||||
const enum sc_type scs[] = { SC_MERC_FLEEUP, SC_MERC_ATKUP, SC_MERC_HPUP, SC_MERC_SPUP, SC_MERC_HITUP };
|
||||
uint8 index = rnd() % ARRAYLENGTH(scs);
|
||||
void mercenary_killbonus(s_mercenary_data *md) {
|
||||
std::vector<sc_type> scs = { SC_MERC_FLEEUP, SC_MERC_ATKUP, SC_MERC_HPUP, SC_MERC_SPUP, SC_MERC_HITUP };
|
||||
|
||||
sc_start(&md->bl,&md->bl, scs[index], 100, rnd() % 5, 600000);
|
||||
sc_start(&md->bl,&md->bl, util::vector_random(scs), 100, rnd() % 5, 600000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Mercenary does kill
|
||||
* @param md Mercenary
|
||||
**/
|
||||
void mercenary_kills(struct mercenary_data *md){
|
||||
void mercenary_kills(s_mercenary_data *md){
|
||||
if(md->mercenary.kill_count <= (INT_MAX-1)) //safe cap to INT_MAX
|
||||
md->mercenary.kill_count++;
|
||||
|
||||
@ -474,144 +443,475 @@ void mercenary_kills(struct mercenary_data *md){
|
||||
* @param skill_id The skill
|
||||
* @return Skill Level or 0 if Mercenary doesn't have the skill
|
||||
**/
|
||||
int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id) {
|
||||
short idx = mercenary_skill_get_index(skill_id);
|
||||
|
||||
if( !md || !md->db || idx == -1)
|
||||
uint16 mercenary_checkskill(s_mercenary_data *md, uint16 skill_id) {
|
||||
if (!md || !md->db)
|
||||
return 0;
|
||||
return md->db->skill[idx].lv;
|
||||
auto skill_level = util::umap_find(md->db->skill, skill_id);
|
||||
return skill_level ? *skill_level : 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Read each line of Mercenary's database
|
||||
**/
|
||||
static bool mercenary_readdb_sub(char* str[], int columns, int current)
|
||||
{
|
||||
int ele;
|
||||
uint16 class_ = atoi(str[0]);
|
||||
struct s_mercenary_db *db;
|
||||
struct status_data *status;
|
||||
const std::string MercenaryDatabase::getDefaultLocation() {
|
||||
return std::string(db_path) + "/mercenary_db.yml";
|
||||
}
|
||||
|
||||
db = &mercenary_db_data[class_];
|
||||
/*
|
||||
* Reads and parses an entry from the mercenary_db.
|
||||
* @param node: YAML node containing the entry.
|
||||
* @return count of successfully parsed rows
|
||||
*/
|
||||
uint64 MercenaryDatabase::parseBodyNode(const YAML::Node &node) {
|
||||
uint32 id;
|
||||
|
||||
db->class_ = class_;
|
||||
safestrncpy(db->sprite, str[1], NAME_LENGTH);
|
||||
safestrncpy(db->name, str[2], NAME_LENGTH);
|
||||
db->lv = atoi(str[3]);
|
||||
if (!this->asUInt32(node, "Id", id))
|
||||
return 0;
|
||||
|
||||
status = &db->status;
|
||||
db->vd.class_ = db->class_;
|
||||
std::shared_ptr<s_mercenary_db> mercenary = this->find(id);
|
||||
bool exists = mercenary != nullptr;
|
||||
|
||||
status->max_hp = atoi(str[4]);
|
||||
status->max_sp = atoi(str[5]);
|
||||
status->rhw.range = atoi(str[6]);
|
||||
status->rhw.atk = atoi(str[7]);
|
||||
status->rhw.atk2 = status->rhw.atk + atoi(str[8]);
|
||||
status->def = atoi(str[9]);
|
||||
status->mdef = atoi(str[10]);
|
||||
status->str = atoi(str[11]);
|
||||
status->agi = atoi(str[12]);
|
||||
status->vit = atoi(str[13]);
|
||||
status->int_ = atoi(str[14]);
|
||||
status->dex = atoi(str[15]);
|
||||
status->luk = atoi(str[16]);
|
||||
db->range2 = atoi(str[17]);
|
||||
db->range3 = atoi(str[18]);
|
||||
status->size = atoi(str[19]);
|
||||
status->race = atoi(str[20]);
|
||||
if (!exists) {
|
||||
if (!this->nodesExist(node, { "AegisName", "Name" }))
|
||||
return 0;
|
||||
|
||||
ele = atoi(str[21]);
|
||||
status->def_ele = ele%20;
|
||||
status->ele_lv = (unsigned char)floor(ele/20.);
|
||||
if( !CHK_ELEMENT(status->def_ele) )
|
||||
{
|
||||
ShowWarning("Mercenary %d has invalid element type %d (max element is %d)\n", db->class_, status->def_ele, ELE_ALL - 1);
|
||||
status->def_ele = ELE_NEUTRAL;
|
||||
}
|
||||
if( !CHK_ELEMENT_LEVEL(status->ele_lv) )
|
||||
{
|
||||
ShowWarning("Mercenary %d has invalid element level %d (max is %d)\n", db->class_, status->ele_lv, MAX_ELE_LEVEL);
|
||||
status->ele_lv = 1;
|
||||
mercenary = std::make_shared<s_mercenary_db>();
|
||||
mercenary->class_ = id;
|
||||
}
|
||||
|
||||
status->aspd_rate = 1000;
|
||||
status->speed = atoi(str[22]);
|
||||
status->adelay = atoi(str[23]);
|
||||
status->amotion = atoi(str[24]);
|
||||
status->dmotion = atoi(str[25]);
|
||||
if (this->nodeExists(node, "AegisName")) {
|
||||
std::string name;
|
||||
|
||||
if (!this->asString(node, "AegisName", name))
|
||||
return 0;
|
||||
|
||||
if (name.size() > NAME_LENGTH) {
|
||||
this->invalidWarning(node["AegisName"], "AegisName \"%s\" exceeds maximum of %d characters, capping...\n", name.c_str(), NAME_LENGTH - 1);
|
||||
}
|
||||
|
||||
name.resize(NAME_LENGTH);
|
||||
mercenary->sprite = name;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Name")) {
|
||||
std::string name;
|
||||
|
||||
if (!this->asString(node, "Name", name))
|
||||
return 0;
|
||||
|
||||
if (name.size() > NAME_LENGTH) {
|
||||
this->invalidWarning(node["Name"], "Name \"%s\" exceeds maximum of %d characters, capping...\n", name.c_str(), NAME_LENGTH - 1);
|
||||
}
|
||||
|
||||
name.resize(NAME_LENGTH);
|
||||
mercenary->name = name;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Level")) {
|
||||
uint16 level;
|
||||
|
||||
if (!this->asUInt16(node, "Level", level))
|
||||
return 0;
|
||||
|
||||
if (level > MAX_LEVEL) {
|
||||
this->invalidWarning(node["Level"], "Level %d exceeds MAX_LEVEL, capping to %d.\n", level, MAX_LEVEL);
|
||||
level = MAX_LEVEL;
|
||||
}
|
||||
|
||||
mercenary->lv = level;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->lv = 1;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Hp")) {
|
||||
uint32 hp;
|
||||
|
||||
if (!this->asUInt32(node, "Hp", hp))
|
||||
return 0;
|
||||
|
||||
mercenary->status.max_hp = hp;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.max_hp = 1;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
if (this->nodeExists(node, "Sp")) {
|
||||
uint32 sp;
|
||||
|
||||
/**
|
||||
* Load Mercenary's database
|
||||
**/
|
||||
void mercenary_readdb(void) {
|
||||
const char *filename[]={ "mercenary_db.txt",DBIMPORT"/mercenary_db.txt"};
|
||||
uint8 i;
|
||||
if (!this->asUInt32(node, "Sp", sp))
|
||||
return 0;
|
||||
|
||||
mercenary_db_data.clear();
|
||||
|
||||
for(i = 0; i<ARRAYLENGTH(filename); i++){
|
||||
sv_readdb(db_path, filename[i], ',', 26, 26, -1, &mercenary_readdb_sub, i > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Read each line of Mercenary's skill
|
||||
**/
|
||||
static bool mercenary_read_skilldb_sub(char* str[], int columns, int current)
|
||||
{// <merc id>,<skill id>,<skill level>
|
||||
struct s_mercenary_db *db;
|
||||
uint16 class_, skill_id, skill_lv;
|
||||
short idx = -1;
|
||||
|
||||
class_ = atoi(str[0]);
|
||||
db = mercenary_db(class_);
|
||||
if( !db ){
|
||||
ShowError("read_mercenary_skilldb : Class %d not found in mercenary_db for skill entry.\n", class_);
|
||||
return false;
|
||||
mercenary->status.max_sp = sp;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.max_sp = 1;
|
||||
}
|
||||
|
||||
skill_id = atoi(str[1]);
|
||||
if( (idx = mercenary_skill_get_index(skill_id)) == -1 ) {
|
||||
ShowError("read_mercenary_skilldb: Invalid Mercenary skill '%s'.\n", str[1]);
|
||||
return false;
|
||||
if (this->nodeExists(node, "Attack")) {
|
||||
uint16 atk;
|
||||
|
||||
if (!this->asUInt16(node, "Attack", atk))
|
||||
return 0;
|
||||
|
||||
mercenary->status.rhw.atk = atk;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.rhw.atk = 0;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Attack2")) {
|
||||
uint16 atk;
|
||||
|
||||
if (!this->asUInt16(node, "Attack2", atk))
|
||||
return 0;
|
||||
|
||||
mercenary->status.rhw.atk2 = mercenary->status.rhw.atk + atk;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.rhw.atk2 = mercenary->status.rhw.atk;
|
||||
}
|
||||
|
||||
skill_lv = atoi(str[2]);
|
||||
if (this->nodeExists(node, "Defense")) {
|
||||
int32 def;
|
||||
|
||||
db->skill[idx].id = skill_id;
|
||||
db->skill[idx].lv = skill_lv;
|
||||
if (!this->asInt32(node, "Defense", def))
|
||||
return 0;
|
||||
|
||||
if (def < DEFTYPE_MIN || def > DEFTYPE_MAX) {
|
||||
this->invalidWarning(node["Defense"], "Invalid defense %d, capping...\n", def);
|
||||
def = cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
|
||||
}
|
||||
|
||||
mercenary->status.def = static_cast<defType>(def);
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.def = 0;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "MagicDefense")) {
|
||||
int32 def;
|
||||
|
||||
if (!this->asInt32(node, "MagicDefense", def))
|
||||
return 0;
|
||||
|
||||
if (def < DEFTYPE_MIN || def > DEFTYPE_MAX) {
|
||||
this->invalidWarning(node["MagicDefense"], "Invalid magic defense %d, capping...\n", def);
|
||||
def = cap_value(def, DEFTYPE_MIN, DEFTYPE_MAX);
|
||||
}
|
||||
|
||||
mercenary->status.mdef = static_cast<defType>(def);
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.mdef = 0;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Str")) {
|
||||
uint16 stat;
|
||||
|
||||
if (!this->asUInt16(node, "Str", stat))
|
||||
return 0;
|
||||
|
||||
mercenary->status.str = stat;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.str = 1;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Agi")) {
|
||||
uint16 stat;
|
||||
|
||||
if (!this->asUInt16(node, "Agi", stat))
|
||||
return 0;
|
||||
|
||||
mercenary->status.agi = stat;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.agi = 1;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Vit")) {
|
||||
uint16 stat;
|
||||
|
||||
if (!this->asUInt16(node, "Vit", stat))
|
||||
return 0;
|
||||
|
||||
mercenary->status.vit = stat;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.vit = 1;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Int")) {
|
||||
uint16 stat;
|
||||
|
||||
if (!this->asUInt16(node, "Int", stat))
|
||||
return 0;
|
||||
|
||||
mercenary->status.int_ = stat;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.int_ = 1;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Dex")) {
|
||||
uint16 stat;
|
||||
|
||||
if (!this->asUInt16(node, "Dex", stat))
|
||||
return 0;
|
||||
|
||||
mercenary->status.dex = stat;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.dex = 1;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Luk")) {
|
||||
uint16 stat;
|
||||
|
||||
if (!this->asUInt16(node, "Luk", stat))
|
||||
return 0;
|
||||
|
||||
mercenary->status.luk = stat;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.luk = 1;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "AttackRange")) {
|
||||
uint16 range;
|
||||
|
||||
if (!this->asUInt16(node, "AttackRange", range))
|
||||
return 0;
|
||||
|
||||
mercenary->status.rhw.range = range;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.rhw.range = 0;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "SkillRange")) {
|
||||
uint16 range;
|
||||
|
||||
if (!this->asUInt16(node, "SkillRange", range))
|
||||
return 0;
|
||||
|
||||
mercenary->range2 = range;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->range2 = 0;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "ChaseRange")) {
|
||||
uint16 range;
|
||||
|
||||
if (!this->asUInt16(node, "ChaseRange", range))
|
||||
return 0;
|
||||
|
||||
mercenary->range3 = range;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->range3 = 0;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Size")) {
|
||||
std::string size;
|
||||
|
||||
if (!this->asString(node, "Size", size))
|
||||
return 0;
|
||||
|
||||
std::string size_constant = "Size_" + size;
|
||||
int64 constant;
|
||||
|
||||
if (!script_get_constant(size_constant.c_str(), &constant)) {
|
||||
this->invalidWarning(node["Size"], "Unknown mercenary size %s, defaulting to Small.\n", size.c_str());
|
||||
constant = SZ_SMALL;
|
||||
}
|
||||
|
||||
if (constant < SZ_SMALL || constant > SZ_BIG) {
|
||||
this->invalidWarning(node["Size"], "Invalid mercenary size %s, defaulting to Small.\n", size.c_str());
|
||||
constant = SZ_SMALL;
|
||||
}
|
||||
|
||||
mercenary->status.size = static_cast<e_size>(constant);
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.size = SZ_SMALL;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Race")) {
|
||||
std::string race;
|
||||
|
||||
if (!this->asString(node, "Race", race))
|
||||
return 0;
|
||||
|
||||
std::string race_constant = "RC_" + race;
|
||||
int64 constant;
|
||||
|
||||
if (!script_get_constant(race_constant.c_str(), &constant)) {
|
||||
this->invalidWarning(node["Race"], "Unknown mercenary race %s, defaulting to Formless.\n", race.c_str());
|
||||
constant = RC_FORMLESS;
|
||||
}
|
||||
|
||||
if (!CHK_RACE(constant)) {
|
||||
this->invalidWarning(node["Race"], "Invalid mercenary race %s, defaulting to Formless.\n", race.c_str());
|
||||
constant = RC_FORMLESS;
|
||||
}
|
||||
|
||||
mercenary->status.race = static_cast<e_race>(constant);
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.race = RC_FORMLESS;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "Element")) {
|
||||
std::string ele;
|
||||
|
||||
if (!this->asString(node, "Element", ele))
|
||||
return 0;
|
||||
|
||||
std::string ele_constant = "ELE_" + ele;
|
||||
int64 constant;
|
||||
|
||||
if (!script_get_constant(ele_constant.c_str(), &constant)) {
|
||||
this->invalidWarning(node["Element"], "Unknown mercenary element %s, defaulting to Neutral.\n", ele.c_str());
|
||||
constant = ELE_NEUTRAL;
|
||||
}
|
||||
|
||||
if (!CHK_ELEMENT(constant)) {
|
||||
this->invalidWarning(node["Element"], "Invalid mercenary element %s, defaulting to Neutral.\n", ele.c_str());
|
||||
constant = ELE_NEUTRAL;
|
||||
}
|
||||
|
||||
mercenary->status.def_ele = static_cast<e_element>(constant);
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.def_ele = ELE_NEUTRAL;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "ElementLevel")) {
|
||||
uint16 level;
|
||||
|
||||
if (!this->asUInt16(node, "ElementLevel", level))
|
||||
return 0;
|
||||
|
||||
if (!CHK_ELEMENT_LEVEL(level)) {
|
||||
this->invalidWarning(node["ElementLevel"], "Invalid mercenary element level %hu, defaulting to 1.\n", level);
|
||||
level = 1;
|
||||
}
|
||||
|
||||
mercenary->status.ele_lv = static_cast<uint8>(level);
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.ele_lv = 1;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "WalkSpeed")) {
|
||||
uint16 speed;
|
||||
|
||||
if (!this->asUInt16(node, "WalkSpeed", speed))
|
||||
return 0;
|
||||
|
||||
if (speed < MIN_WALK_SPEED || speed > MAX_WALK_SPEED) {
|
||||
this->invalidWarning(node["WalkSpeed"], "Invalid mercenary walk speed %hu, capping...\n", speed);
|
||||
speed = cap_value(speed, MIN_WALK_SPEED, MAX_WALK_SPEED);
|
||||
}
|
||||
|
||||
mercenary->status.speed = speed;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.speed = DEFAULT_WALK_SPEED;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "AttackDelay")) {
|
||||
uint16 speed;
|
||||
|
||||
if (!this->asUInt16(node, "AttackDelay", speed))
|
||||
return 0;
|
||||
|
||||
mercenary->status.adelay = cap_value(speed, 0, 4000);
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.adelay = 4000;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "AttackMotion")) {
|
||||
uint16 speed;
|
||||
|
||||
if (!this->asUInt16(node, "AttackMotion", speed))
|
||||
return 0;
|
||||
|
||||
mercenary->status.amotion = cap_value(speed, 0, 2000);
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.amotion = 2000;
|
||||
}
|
||||
|
||||
if (this->nodeExists(node, "DamageMotion")) {
|
||||
uint16 speed;
|
||||
|
||||
if (!this->asUInt16(node, "DamageMotion", speed))
|
||||
return 0;
|
||||
|
||||
mercenary->status.dmotion = speed;
|
||||
} else {
|
||||
if (!exists)
|
||||
mercenary->status.dmotion = 0;
|
||||
}
|
||||
|
||||
mercenary->status.aspd_rate = 1000;
|
||||
|
||||
if (this->nodeExists(node, "Skills")) {
|
||||
const YAML::Node &skillsNode = node["Skills"];
|
||||
|
||||
for (const YAML::Node &skill : skillsNode) {
|
||||
std::string skill_name;
|
||||
|
||||
if (!this->asString(skill, "Name", skill_name))
|
||||
return 0;
|
||||
|
||||
uint16 skill_id = skill_name2id(skill_name.c_str());
|
||||
|
||||
if (skill_id == 0) {
|
||||
this->invalidWarning(skill["Name"], "Invalid skill %s, skipping.\n", skill_name.c_str());
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!SKILL_CHK_MERC(skill_id)) {
|
||||
this->invalidWarning(skill["Name"], "Skill %s (%u) is out of the mercenary skill range [%u-%u], skipping.\n", skill_name.c_str(), skill_id, MC_SKILLBASE, MC_SKILLBASE + MAX_MERCSKILL - 1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint16 level;
|
||||
|
||||
if (!this->asUInt16(skill, "MaxLevel", level))
|
||||
return 0;
|
||||
|
||||
if (level == 0) {
|
||||
if (mercenary->skill.erase(skill_id) == 0)
|
||||
this->invalidWarning(skill["Name"], "Failed to remove %s, the skill doesn't exist for mercenary %hu.\n", skill_name.c_str(), id);
|
||||
continue;
|
||||
}
|
||||
|
||||
mercenary->skill[skill_id] = level;
|
||||
}
|
||||
}
|
||||
|
||||
if (!exists)
|
||||
this->put(id, mercenary);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load Mercenary's skill database
|
||||
**/
|
||||
void mercenary_read_skilldb(void){
|
||||
const char *filename[]={ "mercenary_skill_db.txt",DBIMPORT"/mercenary_skill_db.txt"};
|
||||
uint8 i;
|
||||
|
||||
for(i = 0; i<ARRAYLENGTH(filename); i++){
|
||||
sv_readdb(db_path, filename[i], ',', 3, 3, -1, &mercenary_read_skilldb_sub, i > 0);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Init Mercenary datas
|
||||
**/
|
||||
void do_init_mercenary(void){
|
||||
mercenary_readdb();
|
||||
mercenary_read_skilldb();
|
||||
mercenary_db.load();
|
||||
|
||||
//add_timer_func_list(mercenary_contract, "mercenary_contract");
|
||||
add_timer_func_list(merc_contract_end, "merc_contract_end");
|
||||
}
|
||||
|
||||
/**
|
||||
* Do Final Mercenary datas
|
||||
**/
|
||||
void do_final_mercenary(void){
|
||||
mercenary_db_data.clear();
|
||||
mercenary_db.clear();
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ enum e_MercGuildType {
|
||||
SWORD_MERC_GUILD,
|
||||
};
|
||||
|
||||
enum MERID {
|
||||
enum e_MERID {
|
||||
MERID_MER_ARCHER01 = 6017,
|
||||
MERID_MER_ARCHER10 = 6026,
|
||||
MERID_MER_LANCER01,
|
||||
@ -29,65 +29,67 @@ enum MERID {
|
||||
};
|
||||
|
||||
struct s_mercenary_db {
|
||||
int class_;
|
||||
char sprite[NAME_LENGTH], name[NAME_LENGTH];
|
||||
unsigned short lv;
|
||||
short range2, range3;
|
||||
struct status_data status;
|
||||
struct view_data vd;
|
||||
struct {
|
||||
unsigned short id, lv;
|
||||
} skill[MAX_MERCSKILL];
|
||||
int32 class_;
|
||||
std::string sprite, name;
|
||||
uint16 lv;
|
||||
uint16 range2, range3;
|
||||
status_data status;
|
||||
view_data vd;
|
||||
std::unordered_map<uint16, uint16> skill;
|
||||
};
|
||||
|
||||
struct mercenary_data {
|
||||
struct block_list bl;
|
||||
struct unit_data ud;
|
||||
struct view_data *vd;
|
||||
struct status_data base_status, battle_status;
|
||||
struct status_change sc;
|
||||
struct regen_data regen;
|
||||
struct s_mercenary_data {
|
||||
block_list bl;
|
||||
unit_data ud;
|
||||
view_data *vd;
|
||||
status_data base_status, battle_status;
|
||||
status_change sc;
|
||||
regen_data regen;
|
||||
|
||||
struct s_mercenary_db *db;
|
||||
struct s_mercenary mercenary;
|
||||
std::shared_ptr<s_mercenary_db> db;
|
||||
s_mercenary mercenary;
|
||||
std::vector<uint16> blockskill;
|
||||
|
||||
int masterteleport_timer;
|
||||
struct map_session_data *master;
|
||||
map_session_data *master;
|
||||
int contract_timer;
|
||||
|
||||
unsigned devotion_flag : 1;
|
||||
};
|
||||
|
||||
struct s_mercenary_db *mercenary_db(uint16 class_);
|
||||
struct view_data * mercenary_get_viewdata(uint16 class_);
|
||||
|
||||
bool mercenary_create(struct map_session_data *sd, uint16 class_, unsigned int lifetime);
|
||||
bool mercenary_recv_data(struct s_mercenary *merc, bool flag);
|
||||
void mercenary_save(struct mercenary_data *md);
|
||||
class MercenaryDatabase : public TypesafeYamlDatabase<int32, s_mercenary_db> {
|
||||
public:
|
||||
MercenaryDatabase() : TypesafeYamlDatabase("MERCENARY_DB", 1) {
|
||||
|
||||
void mercenary_heal(struct mercenary_data *md, int hp, int sp);
|
||||
bool mercenary_dead(struct mercenary_data *md);
|
||||
}
|
||||
|
||||
int mercenary_delete(struct mercenary_data *md, int reply);
|
||||
void mercenary_contract_stop(struct mercenary_data *md);
|
||||
const std::string getDefaultLocation();
|
||||
uint64 parseBodyNode(const YAML::Node& node);
|
||||
};
|
||||
|
||||
t_tick mercenary_get_lifetime(struct mercenary_data *md);
|
||||
enum e_MercGuildType mercenary_get_guild(struct mercenary_data *md);
|
||||
int mercenary_get_faith(struct mercenary_data *md);
|
||||
void mercenary_set_faith(struct mercenary_data *md, int value);
|
||||
int mercenary_get_calls(struct mercenary_data *md);
|
||||
void mercenary_set_calls(struct mercenary_data *md, int value);
|
||||
void mercenary_kills(struct mercenary_data *md);
|
||||
extern MercenaryDatabase mercenary_db;
|
||||
|
||||
int mercenary_checkskill(struct mercenary_data *md, uint16 skill_id);
|
||||
short mercenary_skill_get_index(uint16 skill_id);
|
||||
bool mercenary_create(map_session_data *sd, uint16 class_, unsigned int lifetime);
|
||||
bool mercenary_recv_data(s_mercenary *merc, bool flag);
|
||||
void mercenary_save(s_mercenary_data *md);
|
||||
|
||||
/**
|
||||
* atcommand.cpp required
|
||||
**/
|
||||
void mercenary_readdb(void);
|
||||
void mercenary_read_skilldb(void);
|
||||
void mercenary_heal(s_mercenary_data *md, int hp, int sp);
|
||||
bool mercenary_dead(s_mercenary_data *md);
|
||||
|
||||
int mercenary_delete(s_mercenary_data *md, int reply);
|
||||
void mercenary_contract_stop(s_mercenary_data *md);
|
||||
|
||||
t_tick mercenary_get_lifetime(s_mercenary_data *md);
|
||||
e_MercGuildType mercenary_get_guild(s_mercenary_data *md);
|
||||
int mercenary_get_faith(s_mercenary_data *md);
|
||||
void mercenary_set_faith(s_mercenary_data *md, int value);
|
||||
int mercenary_get_calls(s_mercenary_data *md);
|
||||
void mercenary_set_calls(s_mercenary_data *md, int value);
|
||||
void mercenary_kills(s_mercenary_data *md);
|
||||
|
||||
uint16 mercenary_checkskill(s_mercenary_data *md, uint16 skill_id);
|
||||
|
||||
void do_init_mercenary(void);
|
||||
void do_final_mercenary(void);
|
||||
|
@ -2351,7 +2351,7 @@ void mob_log_damage(struct mob_data *md, struct block_list *src, int damage)
|
||||
}
|
||||
case BL_MER:
|
||||
{
|
||||
struct mercenary_data *mer = (TBL_MER*)src;
|
||||
s_mercenary_data *mer = (TBL_MER*)src;
|
||||
if( mer->master )
|
||||
char_id = mer->master->status.char_id;
|
||||
if( damage )
|
||||
|
@ -660,7 +660,7 @@ struct map_session_data {
|
||||
|
||||
struct pet_data *pd;
|
||||
struct homun_data *hd; // [blackhole89]
|
||||
struct mercenary_data *md;
|
||||
s_mercenary_data *md;
|
||||
s_elemental_data *ed;
|
||||
|
||||
struct s_hate_mob {
|
||||
|
@ -15363,7 +15363,7 @@ BUILDIN_FUNC(getmercinfo)
|
||||
{
|
||||
int type;
|
||||
struct map_session_data* sd;
|
||||
struct mercenary_data* md;
|
||||
s_mercenary_data* md;
|
||||
|
||||
if( !script_charid2sd(3,sd) ){
|
||||
script_pushnil(st);
|
||||
@ -15385,7 +15385,7 @@ BUILDIN_FUNC(getmercinfo)
|
||||
{
|
||||
case 0: script_pushint(st,md->mercenary.mercenary_id); break;
|
||||
case 1: script_pushint(st,md->mercenary.class_); break;
|
||||
case 2: script_pushstrcopy(st,md->db->name); break;
|
||||
case 2: script_pushstrcopy(st,md->db->name.c_str()); break;
|
||||
case 3: script_pushint(st,mercenary_get_faith(md)); break;
|
||||
case 4: script_pushint(st,mercenary_get_calls(md)); break;
|
||||
case 5: script_pushint(st,md->mercenary.kill_count); break;
|
||||
@ -17995,7 +17995,7 @@ BUILDIN_FUNC(rid2name)
|
||||
case BL_NPC: script_pushstrcopy(st,((TBL_NPC*)bl)->exname); break;
|
||||
case BL_PET: script_pushstrcopy(st,((TBL_PET*)bl)->pet.name); break;
|
||||
case BL_HOM: script_pushstrcopy(st,((TBL_HOM*)bl)->homunculus.name); break;
|
||||
case BL_MER: script_pushstrcopy(st,((TBL_MER*)bl)->db->name); break;
|
||||
case BL_MER: script_pushstrcopy(st,((TBL_MER*)bl)->db->name.c_str()); break;
|
||||
default:
|
||||
ShowError("buildin_rid2name: BL type unknown.\n");
|
||||
script_pushconststr(st,"");
|
||||
@ -19877,7 +19877,7 @@ BUILDIN_FUNC(mercenary_create)
|
||||
|
||||
class_ = script_getnum(st,2);
|
||||
|
||||
if( !mercenary_db(class_) )
|
||||
if( !mercenary_db.exists(class_) )
|
||||
return SCRIPT_CMD_SUCCESS;
|
||||
|
||||
contract_time = script_getnum(st,3);
|
||||
|
@ -1068,7 +1068,7 @@ bool skill_isNotOk_hom(struct homun_data *hd, uint16 skill_id, uint16 skill_lv)
|
||||
* @param md: Mercenary who casted
|
||||
* @return true: Skill cannot be used, false: otherwise
|
||||
*/
|
||||
bool skill_isNotOk_mercenary(uint16 skill_id, struct mercenary_data *md)
|
||||
bool skill_isNotOk_mercenary(uint16 skill_id, s_mercenary_data *md)
|
||||
{
|
||||
nullpo_retr(1, md);
|
||||
|
||||
@ -6511,7 +6511,7 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
|
||||
struct map_session_data *sd, *dstsd;
|
||||
struct mob_data *md, *dstmd;
|
||||
struct homun_data *hd;
|
||||
struct mercenary_data *mer;
|
||||
s_mercenary_data *mer;
|
||||
struct status_data *sstatus, *tstatus;
|
||||
struct status_change *tsc;
|
||||
struct status_change_entry *tsce;
|
||||
@ -21128,7 +21128,7 @@ int skill_blockhomun_start(struct homun_data *hd, uint16 skill_id, int tick) //[
|
||||
}
|
||||
|
||||
TIMER_FUNC(skill_blockmerc_end){
|
||||
struct mercenary_data *md = (TBL_MER*)map_id2bl(id);
|
||||
s_mercenary_data *md = (TBL_MER*)map_id2bl(id);
|
||||
|
||||
if (md) {
|
||||
auto skill = util::vector_get(md->blockskill, (uint16)data);
|
||||
@ -21140,7 +21140,7 @@ TIMER_FUNC(skill_blockmerc_end){
|
||||
return 1;
|
||||
}
|
||||
|
||||
int skill_blockmerc_start(struct mercenary_data *md, uint16 skill_id, int tick)
|
||||
int skill_blockmerc_start(s_mercenary_data *md, uint16 skill_id, int tick)
|
||||
{
|
||||
nullpo_retr(-1, md);
|
||||
|
||||
|
@ -613,7 +613,7 @@ bool skill_check_cloaking(struct block_list *bl, struct status_change_entry *sce
|
||||
void skill_enchant_elemental_end(struct block_list *bl, int type);
|
||||
bool skill_isNotOk(uint16 skill_id, struct 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, struct 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);
|
||||
|
||||
@ -633,7 +633,7 @@ int skill_blockpc_get(struct map_session_data *sd, int skillid);
|
||||
int skill_blockpc_clear(struct map_session_data *sd);
|
||||
TIMER_FUNC(skill_blockpc_end);
|
||||
int skill_blockhomun_start (struct homun_data*,uint16 skill_id,int);
|
||||
int skill_blockmerc_start (struct mercenary_data*,uint16 skill_id,int);
|
||||
int skill_blockmerc_start (s_mercenary_data*,uint16 skill_id,int);
|
||||
|
||||
|
||||
// (Epoque:) To-do: replace this macro with some sort of skill tree check (rather than hard-coded skill names)
|
||||
|
@ -5140,10 +5140,10 @@ int status_calc_pc_( struct map_session_data* sd, enum e_status_calc_opt opt ){
|
||||
* @param opt: Whether it is first calc or not (0 on level up or status)
|
||||
* @return 0
|
||||
*/
|
||||
int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt)
|
||||
int status_calc_mercenary_(s_mercenary_data *md, enum e_status_calc_opt opt)
|
||||
{
|
||||
struct status_data *status = &md->base_status;
|
||||
struct s_mercenary *merc = &md->mercenary;
|
||||
s_mercenary *merc = &md->mercenary;
|
||||
|
||||
if (opt&SCO_FIRST) {
|
||||
memcpy(status, &md->db->status, sizeof(struct status_data));
|
||||
@ -8453,7 +8453,7 @@ const char* status_get_name(struct block_list *bl)
|
||||
case BL_MOB: return ((TBL_MOB*)bl)->name;
|
||||
case BL_PET: return ((TBL_PET*)bl)->pet.name;
|
||||
case BL_HOM: return ((TBL_HOM*)bl)->homunculus.name;
|
||||
//case BL_MER: // They only have database names which are global, not specific to GID.
|
||||
case BL_MER: return ((TBL_MER *)bl)->db->name.c_str(); // They only have database names which are global, not specific to GID.
|
||||
case BL_NPC: return ((TBL_NPC*)bl)->name;
|
||||
case BL_ELEM: return ((TBL_ELEM *)bl)->db->name.c_str(); // They only have database names which are global, not specific to GID.
|
||||
}
|
||||
@ -8813,7 +8813,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
|
||||
vd = npc_get_viewdata(class_);
|
||||
else if (homdb_checkid(class_))
|
||||
vd = hom_get_viewdata(class_);
|
||||
else if (mercenary_db(class_))
|
||||
else if (mercenary_db.exists(class_))
|
||||
vd = mercenary_get_viewdata(class_);
|
||||
else if (elemental_db.exists(class_))
|
||||
vd = elemental_get_viewdata(class_);
|
||||
@ -8943,7 +8943,7 @@ void status_set_viewdata(struct block_list *bl, int class_)
|
||||
break;
|
||||
case BL_MER:
|
||||
{
|
||||
struct mercenary_data *md = (struct mercenary_data*)bl;
|
||||
s_mercenary_data *md = (s_mercenary_data*)bl;
|
||||
if (vd)
|
||||
md->vd = vd;
|
||||
else
|
||||
|
@ -17,7 +17,7 @@ struct block_list;
|
||||
struct mob_data;
|
||||
struct pet_data;
|
||||
struct homun_data;
|
||||
struct mercenary_data;
|
||||
struct s_mercenary_data;
|
||||
struct s_elemental_data;
|
||||
struct npc_data;
|
||||
struct status_change;
|
||||
@ -2881,7 +2881,7 @@ int status_calc_mob_(struct mob_data* md, enum e_status_calc_opt opt);
|
||||
void status_calc_pet_(struct pet_data* pd, enum e_status_calc_opt opt);
|
||||
int status_calc_pc_(struct map_session_data* sd, enum e_status_calc_opt opt);
|
||||
int status_calc_homunculus_(struct homun_data *hd, enum e_status_calc_opt opt);
|
||||
int status_calc_mercenary_(struct mercenary_data *md, enum e_status_calc_opt opt);
|
||||
int status_calc_mercenary_(s_mercenary_data *md, e_status_calc_opt opt);
|
||||
int status_calc_elemental_(s_elemental_data *ed, e_status_calc_opt opt);
|
||||
int status_calc_npc_(struct npc_data *nd, enum e_status_calc_opt opt);
|
||||
|
||||
|
@ -65,7 +65,7 @@ struct unit_data* unit_bl2ud(struct block_list *bl)
|
||||
case BL_PET: return &((struct pet_data*)bl)->ud;
|
||||
case BL_NPC: return &((struct npc_data*)bl)->ud;
|
||||
case BL_HOM: return &((struct homun_data*)bl)->ud;
|
||||
case BL_MER: return &((struct mercenary_data*)bl)->ud;
|
||||
case BL_MER: return &((s_mercenary_data*)bl)->ud;
|
||||
case BL_ELEM: return &((s_elemental_data*)bl)->ud;
|
||||
default : return NULL;
|
||||
}
|
||||
@ -3216,7 +3216,7 @@ int unit_remove_map_(struct block_list *bl, clr_type clrtype, const char* file,
|
||||
break;
|
||||
}
|
||||
case BL_MER: {
|
||||
struct mercenary_data *md = (struct mercenary_data *)bl;
|
||||
s_mercenary_data *md = (s_mercenary_data *)bl;
|
||||
|
||||
ud->canact_tick = ud->canmove_tick;
|
||||
|
||||
@ -3557,7 +3557,7 @@ int unit_free(struct block_list *bl, clr_type clrtype)
|
||||
break;
|
||||
}
|
||||
case BL_MER: {
|
||||
struct mercenary_data *md = (TBL_MER*)bl;
|
||||
s_mercenary_data *md = (TBL_MER*)bl;
|
||||
struct map_session_data *sd = md->master;
|
||||
|
||||
if( mercenary_get_lifetime(md) > 0 )
|
||||
|
@ -130,6 +130,14 @@ static void elemental_skill_txt_data(const std::string& modePath, const std::str
|
||||
sv_readdb(fixedPath.c_str(), "elemental_skill_db.txt", ',', 4, 4, -1, read_elemental_skilldb, false);
|
||||
}
|
||||
|
||||
// Mercenary's Skill Database data to memory
|
||||
static void mercenary_skill_txt_data(const std::string& modePath, const std::string& fixedPath) {
|
||||
mercenary_skill_tree.clear();
|
||||
|
||||
if (fileExists(fixedPath + "/mercenary_skill_db.txt"))
|
||||
sv_readdb(fixedPath.c_str(), "mercenary_skill_db.txt", ',', 3, 3, -1, mercenary_read_skilldb, 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 ){
|
||||
@ -489,6 +497,12 @@ int do_init( int argc, char** argv ){
|
||||
return 0;
|
||||
}
|
||||
|
||||
mercenary_skill_txt_data(path_db_mode, path_db);
|
||||
if (!process("MERCENARY_DB", 1, root_paths, "mercenary_db", [](const std::string &path, const std::string &name_ext) -> bool {
|
||||
return sv_readdb(path.c_str(), name_ext.c_str(), ',', 26, 26, -1, &mercenary_readdb, false);
|
||||
})) {
|
||||
return 0;
|
||||
}
|
||||
// TODO: add implementations ;-)
|
||||
|
||||
return 0;
|
||||
@ -4528,3 +4542,111 @@ static bool read_elementaldb(char* str[], int columns, int current) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// mercenary_db.yml function
|
||||
//---------------------------
|
||||
static bool mercenary_read_skilldb(char* str[], int columns, int current) {
|
||||
uint16 skill_id = atoi(str[1]);
|
||||
std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
|
||||
|
||||
if (skill_name == nullptr) {
|
||||
ShowError("mercenary_read_skilldb: Invalid skill '%hu'.\n", skill_id);
|
||||
return false;
|
||||
}
|
||||
|
||||
s_mercenary_skill_csv entry = {};
|
||||
|
||||
entry.skill_name = *skill_name;
|
||||
entry.max_lv = atoi(str[2]);
|
||||
|
||||
uint16 class_ = atoi(str[0]);
|
||||
|
||||
if (util::umap_find(mercenary_skill_tree, class_))
|
||||
mercenary_skill_tree[class_].push_back(entry);
|
||||
else {
|
||||
mercenary_skill_tree[class_] = std::vector<s_mercenary_skill_csv>();
|
||||
mercenary_skill_tree[class_].push_back(entry);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// Copied and adjusted from mercenary.cpp
|
||||
static bool mercenary_readdb(char* str[], int columns, int current) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Id" << YAML::Value << str[0];
|
||||
body << YAML::Key << "AegisName" << YAML::Value << str[1];
|
||||
body << YAML::Key << "Name" << YAML::Value << str[2];
|
||||
if (atoi(str[3]) != 1)
|
||||
body << YAML::Key << "Level" << YAML::Value << str[3];
|
||||
if (atoi(str[4]) != 1)
|
||||
body << YAML::Key << "Hp" << YAML::Value << str[4];
|
||||
if (atoi(str[5]) != 1)
|
||||
body << YAML::Key << "Sp" << YAML::Value << str[5];
|
||||
if (atoi(str[7]) != 0)
|
||||
body << YAML::Key << "Attack" << YAML::Value << str[7];
|
||||
if (atoi(str[8]) != 0)
|
||||
body << YAML::Key << "Attack2" << YAML::Value << str[8];
|
||||
if (atoi(str[9]) != 0)
|
||||
body << YAML::Key << "Defense" << YAML::Value << str[9];
|
||||
if (atoi(str[10]) != 0)
|
||||
body << YAML::Key << "MagicDefense" << YAML::Value << str[10];
|
||||
if (atoi(str[11]) != 1)
|
||||
body << YAML::Key << "Str" << YAML::Value << str[11];
|
||||
if (atoi(str[12]) != 1)
|
||||
body << YAML::Key << "Agi" << YAML::Value << str[12];
|
||||
if (atoi(str[13]) != 1)
|
||||
body << YAML::Key << "Vit" << YAML::Value << str[13];
|
||||
if (atoi(str[14]) != 1)
|
||||
body << YAML::Key << "Int" << YAML::Value << str[14];
|
||||
if (atoi(str[15]) != 1)
|
||||
body << YAML::Key << "Dex" << YAML::Value << str[15];
|
||||
if (atoi(str[16]) != 1)
|
||||
body << YAML::Key << "Luk" << YAML::Value << str[16];
|
||||
if (atoi(str[6]) != 0)
|
||||
body << YAML::Key << "AttackRange" << YAML::Value << str[6];
|
||||
if (atoi(str[17]) != 0)
|
||||
body << YAML::Key << "SkillRange" << YAML::Value << str[17];
|
||||
if (atoi(str[18]) != 0)
|
||||
body << YAML::Key << "ChaseRange" << YAML::Value << str[18];
|
||||
if (atoi(str[19]) != 0)
|
||||
body << YAML::Key << "Size" << YAML::Value << constant_lookup(strtol(str[19], nullptr, 10), "Size_") + 5;
|
||||
if (atoi(str[20]) != 0)
|
||||
body << YAML::Key << "Race" << YAML::Value << name2Upper(constant_lookup(atoi(str[20]), "RC_") + 3);
|
||||
|
||||
int ele = strtol(str[21], nullptr, 10);
|
||||
if (atoi(str[21]) != 0)
|
||||
body << YAML::Key << "Element" << YAML::Value << name2Upper(constant_lookup(ele % 20, "ELE_") + 4);
|
||||
if (atoi(str[21]) != 1)
|
||||
body << YAML::Key << "ElementLevel" << YAML::Value << floor(ele / 20.);
|
||||
|
||||
if (atoi(str[22]) != 0)
|
||||
body << YAML::Key << "WalkSpeed" << YAML::Value << cap_value(std::stoi(str[22]), MIN_WALK_SPEED, MAX_WALK_SPEED);
|
||||
if (atoi(str[23]) != 0)
|
||||
body << YAML::Key << "AttackDelay" << YAML::Value << str[23];
|
||||
if (atoi(str[24]) != 0)
|
||||
body << YAML::Key << "AttackMotion" << YAML::Value << str[24];
|
||||
if (atoi(str[25]) != 0)
|
||||
body << YAML::Key << "DamageMotion" << YAML::Value << str[25];
|
||||
|
||||
for (const auto &skillit : mercenary_skill_tree) {
|
||||
if (skillit.first != atoi(str[0]))
|
||||
continue;
|
||||
|
||||
body << YAML::Key << "Skills";
|
||||
body << YAML::BeginSeq;
|
||||
|
||||
for (const auto &it : skillit.second) {
|
||||
body << YAML::BeginMap;
|
||||
body << YAML::Key << "Name" << YAML::Value << it.skill_name;
|
||||
body << YAML::Key << "MaxLevel" << YAML::Value << it.max_lv;
|
||||
body << YAML::EndMap;
|
||||
}
|
||||
|
||||
body << YAML::EndSeq;
|
||||
}
|
||||
|
||||
body << YAML::EndMap;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
@ -128,6 +128,13 @@ struct s_elemental_skill_csv {
|
||||
|
||||
std::unordered_map<uint16, std::vector<s_elemental_skill_csv>> elemental_skill_tree;
|
||||
|
||||
struct s_mercenary_skill_csv {
|
||||
std::string skill_name;
|
||||
uint16 max_lv;
|
||||
};
|
||||
|
||||
std::unordered_map<uint16, std::vector<s_mercenary_skill_csv>> mercenary_skill_tree;
|
||||
|
||||
static std::map<std::string, int> um_mapid2jobname {
|
||||
{ "Novice", JOB_NOVICE }, // Novice and Super Novice share the same value
|
||||
{ "SuperNovice", JOB_NOVICE },
|
||||
@ -486,5 +493,7 @@ static bool pc_readdb_job_basehpsp(char *fields[], int columns, int current);
|
||||
static bool pc_readdb_job1(char *fields[], int columns, int current);
|
||||
static bool read_elemental_skilldb(char* str[], int columns, int current);
|
||||
static bool read_elementaldb(char* str[], int columns, int current);
|
||||
static bool mercenary_read_skilldb(char* str[], int columns, int current);
|
||||
static bool mercenary_readdb(char* str[], int columns, int current);
|
||||
|
||||
#endif /* CSV2YAML_HPP */
|
||||
|
Loading…
x
Reference in New Issue
Block a user