Converted Abra Database to YAML (#4480)

* Removed useless skill name usage in the database.
This commit is contained in:
Aleos
2019-12-18 18:40:50 -05:00
committed by GitHub
parent 84bdf59e36
commit 2fc7472001
9 changed files with 547 additions and 290 deletions

View File

@@ -1,227 +0,0 @@
// Hocus-Pocus (Abracadabra) Castable Skills Database
//
// Structure of Database:
// SkillID,DummyName,ProbabilityPerLvl
//
// 01. SkillID Skill ID to be casted by hocus pocus.
// 02. DummyName Name of the skill (informative, not used by server).
// 03. ProbabilityPerLvl Not a rate! Chance at which the skill is selected compared
// with other entries probabilties
//
// NOTE:
// - The skill is picked at random from the entire database and then tested for rate. If it
// does not succeed at that rate, another skill is picked and tested. This continues
// until a skill succeeds. Abracadabra-specific skills have a different chance to occur
// depending on skill level used. All other skills have an equal chance and appear from
// level 1 onward.
// - To remove entry by importing, put "clear" (without quotes) in DummyName
5,Bash,500
6,Provoke,500
7,Magnum Break,500
8,Endure,500
10,Sight,500
11,Napalm Beat,500
12,Safety Wall,500
13,Soul Strike,500
14,Cold Bolt,500
15,Frost Diver,500
16,Stone Curse,500
17,Fire Ball,500
18,Fire Wall,500
19,Fire Bolt,500
20,Lightning Bolt,500
21,Thunder Storm,500
24,Ruwach,500
25,Pneuma,500
26,Teleport,500
27,Warp Portal,500
28,Heal,500
29,Increase AGI,500
30,Decrease AGI,500
31,Aqua Benedicta,500
32,Signum Crucis,500
33,Angelus,500
34,Blessing,500
35,Cure,500
40,Item Appraisal,500
41,Vending,500
42,Mammonite,500
45,Improve Concentration,500
46,Double Strafe,500
47,Arrow Shower,500
50,Steal,500
51,Hiding,500
52,Envenom,500
53,Detoxify,500
54,Resurrection,500
56,Pierce,500
57,Brandish Spear,500
58,Spear Stab,500
59,Spear Boomerang,500
60,TwoHand Quicken,500
61,Counter Attack,500
62,Bowling Bash,500
66,Impositio Manus,500
67,Suffragium,500
68,Aspersio,500
69,B.S Sacramenti,500
70,Sanctuary,500
71,Slow poison,500
72,Status Recovery,500
73,Kyrie Eleison,500
74,Magnificat,500
75,Gloria,500
76,Lex Divina,500
77,Turn Undead,500
78,Lex Aeterna,500
79,Magnus Exorcismus,500
80,Fire Pillar,500
81,Sightrasher,500
//82,Fire Ivy,500
83,Meteor Storm,500
84,Jupitel Thunder,500
85,Lord of Vermilion,500
86,Water Ball,500
87,Ice Wall,500
88,Frost Nova,500
89,Storm Gust,500
90,Earth spike,500
91,Heaven's Drive,500
92,Quagmire,500
93,Sense,500
//108,Weapon Repair,500
110,Hammer Fall,500
111,Adrenaline Rush,500
112,Weapon Perfection,500
113,Power-Thrust,500
114,Maximize Power,500
115,Skid Trap,500
116,Land Mine,500
117,Ankle Snare,500
118,Shockwave Trap,500
119,Sandman,500
120,Flasher,500
121,Freezing Trap,500
122,Blast Mine,500
123,Claymore Trap,500
124,Remove Trap,500
125,Talkie box,500
129,Blitz Beat,500
130,Detect,500
131,Spring Trap,500
135,Cloaking,500
136,Sonic Blow,500
137,Grimtooth,500
138,Enchant Poison,500
139,Poison React,500
140,Venom Dust,500
141,Venom Splasher,500
//---EP4.0 Skill---
211,Mug,500
212,Back Stab,500
214,Sightless Raid,500
215,Divest Weapon,500
216,Divest Shield,500
217,Divest Armor,500
218,Divest Helm,500
219,Snatch,500
220,Scribble,500
//221,Piece,500
222,Remover,500
249,Guard,500
250,Smite,500
251,Shield Boomerang,500
252,Shield Reflect,500
253,Holy Cross,500
254,Grand Cross,500
255,Sacrifice,500
256,Resistant Souls,500
257,Defending Aura,500
258,Spear Quicken,500
261,Summon Spirit Sphere,500
262,Absorb Spirit Sphere,500
264,Snap,500
266,Occult Impact,500
267,Throw Spirit Sphere,500
268,Mental Strength,500
269,Root,500
270,Fury,500
271,Asura Strike,500
//272,Raging Quadruple Blow,500
//273,Raging Thrust,500
275,Cast Cancel,500
276,Magic Rod,500
277,Spell Break,500
279,Hindsight,500
280,Endow Blaze,500
281,Endow Tsunami,500
282,Endow Tornado,500
283,Endow Quake,500
285,Volcano,500
286,Deluge,500
287,Whirlwind,500
288,Magnetic Earth,500
289,Dispel,500
// Abracadabra Derivation Skill
291,Monocell,250:500:750:1000:1250:1200:1750:2000:2250:2500
292,Class Change,0:0:0:0:10:10:20:20:30:30
293,Summon Monster,100:200:300:400:500:600:700:800:900:1000
294,Grampus Morph,0:0:0:0:0:0:0:10:50:100
295,Grim Reaper,50:100:150:200:250:300:350:400:450:500
//296,Gold Digger,50:100:150:200:250:300:350:400:450:500
//297,Beastly Hypnosis,50:100:150:200:250:300:350:400:450:500
298,Questioning,1000:800:600:400:200:0:0:0:0:0
299,Gravity,0:0:0:0:0:0:0:20:50:100
//300,Leveling,0:0:0:0:0:0:0:0:10:50
301,Suicide,0:0:0:0:0:0:0:10:50:100
302,Rejuvination,0:0:0:0:0:0:20:50:100:200
303,Coma,0:0:0:0:100:200:300:400:500:600
// Dancer / Bard commonness
//304,Amp,500
//305,Encore,500
//306,Lullaby,500
//307,Mental Sensing,500
//308,Down Tempo,500
//309,Battle Theme,500
//310,Harmonic Lick,500
//311,Classical Pluck,500
//312,Power Chord,500
//313,Acoustic Rhythm,500
//314,Ragnarok,500
// Bard skill
316,Melody Strike,500
//317,Unchained Serenade,500
318,Unbarring Octave,500
//319,Perfect Tablature,500
//320,Impressive Riff,500
//321,Magic Strings,500
//322,Song of Lutie,500
// Dancer skill
324,Slinging Arrow,500
//325,Hip Shaker,500
326,Dazzler,500
//327,Focus Ballet,500
//328,Slow Grace,500
//329,Lady Luck,500
//330,Gypsy's Kiss,500

324
db/abra_db.yml Normal file
View File

@@ -0,0 +1,324 @@
# This file is a part of rAthena.
# Copyright(C) 2019 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/>.
#
###########################################################################
# Abracadabra Database
###########################################################################
#
# Abracadabra Settings
#
###########################################################################
# - Skill Skill to be casted by Abracadabra.
# Probability: Probability of skill compared to others in database (1 = 0.01%, 10000 = 100%). (Default: 500)
# - Level Skill level.
# Probability Probability at specific skill level (1 = 0.01%, 10000 = 100%). (Default: 0)
###########################################################################
Header:
Type: ABRA_DB
Version: 1
Body:
- Skill: SM_BASH
- Skill: SM_PROVOKE
- Skill: SM_MAGNUM
- Skill: SM_ENDURE
- Skill: MG_SIGHT
- Skill: MG_NAPALMBEAT
- Skill: MG_SAFETYWALL
- Skill: MG_SOULSTRIKE
- Skill: MG_COLDBOLT
- Skill: MG_FROSTDIVER
- Skill: MG_STONECURSE
- Skill: MG_FIREBALL
- Skill: MG_FIREWALL
- Skill: MG_FIREBOLT
- Skill: MG_LIGHTNINGBOLT
- Skill: MG_THUNDERSTORM
- Skill: AL_RUWACH
- Skill: AL_PNEUMA
- Skill: AL_TELEPORT
- Skill: AL_WARP
- Skill: AL_HEAL
- Skill: AL_INCAGI
- Skill: AL_DECAGI
- Skill: AL_HOLYWATER
- Skill: AL_CRUCIS
- Skill: AL_ANGELUS
- Skill: AL_BLESSING
- Skill: AL_CURE
- Skill: MC_IDENTIFY
- Skill: MC_VENDING
- Skill: MC_MAMMONITE
- Skill: AC_CONCENTRATION
- Skill: AC_DOUBLE
- Skill: AC_SHOWER
- Skill: TF_STEAL
- Skill: TF_HIDING
- Skill: TF_POISON
- Skill: TF_DETOXIFY
- Skill: ALL_RESURRECTION
- Skill: KN_PIERCE
- Skill: KN_BRANDISHSPEAR
- Skill: KN_SPEARSTAB
- Skill: KN_SPEARBOOMERANG
- Skill: KN_TWOHANDQUICKEN
- Skill: KN_AUTOCOUNTER
- Skill: KN_BOWLINGBASH
- Skill: PR_IMPOSITIO
- Skill: PR_SUFFRAGIUM
- Skill: PR_ASPERSIO
- Skill: PR_BENEDICTIO
- Skill: PR_SANCTUARY
- Skill: PR_SLOWPOISON
- Skill: PR_STRECOVERY
- Skill: PR_KYRIE
- Skill: PR_MAGNIFICAT
- Skill: PR_GLORIA
- Skill: PR_LEXDIVINA
- Skill: PR_TURNUNDEAD
- Skill: PR_LEXAETERNA
- Skill: PR_MAGNUS
- Skill: WZ_FIREPILLAR
- Skill: WZ_SIGHTRASHER
- Skill: WZ_METEOR
- Skill: WZ_JUPITEL
- Skill: WZ_VERMILION
- Skill: WZ_WATERBALL
- Skill: WZ_ICEWALL
- Skill: WZ_FROSTNOVA
- Skill: WZ_STORMGUST
- Skill: WZ_EARTHSPIKE
- Skill: WZ_HEAVENDRIVE
- Skill: WZ_QUAGMIRE
- Skill: WZ_ESTIMATION
- Skill: BS_HAMMERFALL
- Skill: BS_ADRENALINE
- Skill: BS_WEAPONPERFECT
- Skill: BS_OVERTHRUST
- Skill: BS_MAXIMIZE
- Skill: HT_SKIDTRAP
- Skill: HT_LANDMINE
- Skill: HT_ANKLESNARE
- Skill: HT_SHOCKWAVE
- Skill: HT_SANDMAN
- Skill: HT_FLASHER
- Skill: HT_FREEZINGTRAP
- Skill: HT_BLASTMINE
- Skill: HT_CLAYMORETRAP
- Skill: HT_REMOVETRAP
- Skill: HT_TALKIEBOX
- Skill: HT_BLITZBEAT
- Skill: HT_DETECTING
- Skill: HT_SPRINGTRAP
- Skill: AS_CLOAKING
- Skill: AS_SONICBLOW
- Skill: AS_GRIMTOOTH
- Skill: AS_ENCHANTPOISON
- Skill: AS_POISONREACT
- Skill: AS_VENOMDUST
- Skill: AS_SPLASHER
- Skill: RG_STEALCOIN
- Skill: RG_BACKSTAP
- Skill: RG_RAID
- Skill: RG_STRIPWEAPON
- Skill: RG_STRIPSHIELD
- Skill: RG_STRIPARMOR
- Skill: RG_STRIPHELM
- Skill: RG_INTIMIDATE
- Skill: RG_GRAFFITI
- Skill: RG_CLEANER
- Skill: CR_AUTOGUARD
- Skill: CR_SHIELDCHARGE
- Skill: CR_SHIELDBOOMERANG
- Skill: CR_REFLECTSHIELD
- Skill: CR_HOLYCROSS
- Skill: CR_GRANDCROSS
- Skill: CR_DEVOTION
- Skill: CR_PROVIDENCE
- Skill: CR_DEFENDER
- Skill: CR_SPEARQUICKEN
- Skill: MO_CALLSPIRITS
- Skill: MO_ABSORBSPIRITS
- Skill: MO_BODYRELOCATION
- Skill: MO_INVESTIGATE
- Skill: MO_FINGEROFFENSIVE
- Skill: MO_STEELBODY
- Skill: MO_BLADESTOP
- Skill: MO_EXPLOSIONSPIRITS
- Skill: MO_EXTREMITYFIST
- Skill: SA_CASTCANCEL
- Skill: SA_MAGICROD
- Skill: SA_SPELLBREAKER
- Skill: SA_AUTOSPELL
- Skill: SA_FLAMELAUNCHER
- Skill: SA_FROSTWEAPON
- Skill: SA_LIGHTNINGLOADER
- Skill: SA_SEISMICWEAPON
- Skill: SA_VOLCANO
- Skill: SA_DELUGE
- Skill: SA_VIOLENTGALE
- Skill: SA_LANDPROTECTOR
- Skill: SA_DISPELL
- Skill: SA_MONOCELL
Probability:
- Level: 1
Probability: 250
- Level: 2
Probability: 500
- Level: 3
Probability: 750
- Level: 4
Probability: 1000
- Level: 5
Probability: 1250
- Level: 6
Probability: 1200
- Level: 7
Probability: 1750
- Level: 8
Probability: 2000
- Level: 9
Probability: 2250
- Level: 10
Probability: 2500
- Skill: SA_CLASSCHANGE
Probability:
- Level: 5
Probability: 10
- Level: 6
Probability: 10
- Level: 7
Probability: 20
- Level: 8
Probability: 20
- Level: 9
Probability: 30
- Level: 10
Probability: 30
- Skill: SA_SUMMONMONSTER
Probability:
- Level: 1
Probability: 100
- Level: 2
Probability: 200
- Level: 3
Probability: 300
- Level: 4
Probability: 400
- Level: 5
Probability: 500
- Level: 6
Probability: 600
- Level: 7
Probability: 700
- Level: 8
Probability: 800
- Level: 9
Probability: 900
- Level: 10
Probability: 1000
- Skill: SA_REVERSEORCISH
Probability:
- Level: 8
Probability: 10
- Level: 9
Probability: 50
- Level: 10
Probability: 100
- Skill: SA_DEATH
Probability:
- Level: 1
Probability: 50
- Level: 2
Probability: 100
- Level: 3
Probability: 150
- Level: 4
Probability: 200
- Level: 5
Probability: 250
- Level: 6
Probability: 300
- Level: 7
Probability: 350
- Level: 8
Probability: 400
- Level: 9
Probability: 450
- Level: 10
Probability: 500
- Skill: SA_QUESTION
Probability:
- Level: 1
Probability: 1000
- Level: 2
Probability: 800
- Level: 3
Probability: 600
- Level: 4
Probability: 400
- Level: 5
Probability: 200
- Skill: SA_GRAVITY
Probability:
- Level: 8
Probability: 20
- Level: 9
Probability: 50
- Level: 10
Probability: 100
- Skill: SA_INSTANTDEATH
Probability:
- Level: 8
Probability: 10
- Level: 9
Probability: 50
- Level: 10
Probability: 100
- Skill: SA_FULLRECOVERY
Probability:
- Level: 7
Probability: 20
- Level: 8
Probability: 50
- Level: 9
Probability: 100
- Level: 10
Probability: 200
- Skill: SA_COMA
Probability:
- Level: 5
Probability: 100
- Level: 6
Probability: 200
- Level: 7
Probability: 300
- Level: 8
Probability: 400
- Level: 9
Probability: 500
- Level: 10
Probability: 600
- Skill: BA_MUSICALSTRIKE
- Skill: BA_FROSTJOKER
- Skill: DC_THROWARROW
- Skill: DC_SCREAM
Footer:
Imports:
- Path: db/import/abra_db.yml

View File

@@ -1,17 +0,0 @@
// Hocus-Pocus (Abracadabra) Castable Skills Database
//
// Structure of Database:
// SkillID,DummyName,ProbabilityPerLvl
//
// 01. SkillID Skill ID to be casted by hocus pocus.
// 02. DummyName Name of the skill (informative, not used by server).
// 03. ProbabilityPerLvl Not a rate! Chance at which the skill is selected compared
// with other entries probabilties
//
// NOTE:
// - The skill is picked at random from the entire database and then tested for rate. If it
// does not succeed at that rate, another skill is picked and tested. This continues
// until a skill succeeds. Abracadabra-specific skills have a different chance to occur
// depending on skill level used. All other skills have an equal chance and appear from
// level 1 onward.
// - To remove entry by importing, put "clear" (without quotes) in DummyName

View File

@@ -0,0 +1,33 @@
# This file is a part of rAthena.
# Copyright(C) 2019 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/>.
#
###########################################################################
# Abracadabra Database
###########################################################################
#
# Abracadabra Settings
#
###########################################################################
# - Skill Skill to be casted by Abracadabra.
# Probability: Probability of skill compared to others in database (1 = 0.01%, 10000 = 100%). (Default: 500)
# - Level Skill level.
# Probability Probability at specific skill level (1 = 0.01%, 10000 = 100%). (Default: 0)
###########################################################################
Header:
Type: ABRA_DB
Version: 1

12
doc/yaml/db/abra_db.yml Normal file
View File

@@ -0,0 +1,12 @@
###########################################################################
# Abracadabra Database
###########################################################################
#
# Abracadabra Settings
#
###########################################################################
# - Skill Skill to be casted by Abracadabra.
# Probability: Probability of skill compared to others in database (1 = 0.01%, 10000 = 100%). (Default: 500)
# - Level Skill level.
# Probability Probability at specific skill level (1 = 0.01%, 10000 = 100%). (Default: 0)
###########################################################################

View File

@@ -290,7 +290,7 @@
<Copy SourceFiles="$(SolutionDir)conf\msg_conf\import-tmpl\map_msg_rus_conf.txt" DestinationFolder="$(SolutionDir)conf\msg_conf\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)conf\msg_conf\import\map_msg_rus_conf.txt')" /> <Copy SourceFiles="$(SolutionDir)conf\msg_conf\import-tmpl\map_msg_rus_conf.txt" DestinationFolder="$(SolutionDir)conf\msg_conf\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)conf\msg_conf\import\map_msg_rus_conf.txt')" />
<Copy SourceFiles="$(SolutionDir)conf\msg_conf\import-tmpl\map_msg_spn_conf.txt" DestinationFolder="$(SolutionDir)conf\msg_conf\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)conf\msg_conf\import\map_msg_spn_conf.txt')" /> <Copy SourceFiles="$(SolutionDir)conf\msg_conf\import-tmpl\map_msg_spn_conf.txt" DestinationFolder="$(SolutionDir)conf\msg_conf\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)conf\msg_conf\import\map_msg_spn_conf.txt')" />
<Copy SourceFiles="$(SolutionDir)conf\msg_conf\import-tmpl\map_msg_tha_conf.txt" DestinationFolder="$(SolutionDir)conf\msg_conf\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)conf\msg_conf\import\map_msg_tha_conf.txt')" /> <Copy SourceFiles="$(SolutionDir)conf\msg_conf\import-tmpl\map_msg_tha_conf.txt" DestinationFolder="$(SolutionDir)conf\msg_conf\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)conf\msg_conf\import\map_msg_tha_conf.txt')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\abra_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\abra_db.txt')" /> <Copy SourceFiles="$(SolutionDir)db\import-tmpl\abra_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\abra_db.yml')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\achievement_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\achievement_db.yml')" /> <Copy SourceFiles="$(SolutionDir)db\import-tmpl\achievement_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\achievement_db.yml')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\achievement_level_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\achievement_level_db.yml')" /> <Copy SourceFiles="$(SolutionDir)db\import-tmpl\achievement_level_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\achievement_level_db.yml')" />
<Copy SourceFiles="$(SolutionDir)db\import-tmpl\attendance.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\attendance.yml')" /> <Copy SourceFiles="$(SolutionDir)db\import-tmpl\attendance.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\attendance.yml')" />

View File

@@ -87,8 +87,7 @@ static unsigned short skill_produce_count;
struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB]; struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB];
static unsigned short skill_arrow_count; static unsigned short skill_arrow_count;
struct s_skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB]; AbraDatabase abra_db;
unsigned short skill_abra_count;
struct s_skill_improvise_db { struct s_skill_improvise_db {
uint16 skill_id; uint16 skill_id;
@@ -6411,19 +6410,20 @@ int skill_castend_nodamage_id (struct block_list *src, struct block_list *bl, ui
break; break;
case SA_ABRACADABRA: case SA_ABRACADABRA:
if (!skill_abra_count) { if (abra_db.size() == 0) {
clif_skill_nodamage (src, bl, skill_id, skill_lv, 1); clif_skill_nodamage (src, bl, skill_id, skill_lv, 1);
break; break;
} }
else { else {
int abra_skill_id = 0, abra_skill_lv, checked = 0, checked_max = MAX_SKILL_ABRA_DB * 3; int abra_skill_id = 0, abra_skill_lv, checked = 0, checked_max = abra_db.size() * 3;
auto abra_spell = abra_db.begin();
do { do {
i = rnd() % MAX_SKILL_ABRA_DB; std::advance(abra_spell, rnd() % abra_db.size());
abra_skill_id = skill_abra_db[i].skill_id;
abra_skill_id = abra_spell->second->skill_id;
abra_skill_lv = min(skill_lv, skill_get_max(abra_skill_id)); abra_skill_lv = min(skill_lv, skill_get_max(abra_skill_id));
} while ( checked++ < checked_max && } while (checked++ < checked_max && rnd() % 10000 >= abra_spell->second->per[max(skill_lv - 1, 0)]);
(abra_skill_id == 0 ||
rnd()%10000 >= skill_abra_db[i].per[max(skill_lv-1,0)]) );
if (!skill_get_index(abra_skill_id)) if (!skill_get_index(abra_skill_id))
break; break;
@@ -21585,40 +21585,90 @@ static bool skill_parse_row_nonearnpcrangedb(char* split[], int column, int curr
return true; return true;
} }
/** Reads skill chance by Abracadabra/Hocus Pocus spell
* Structure: SkillID,DummyName,RatePerLvl const std::string AbraDatabase::getDefaultLocation() {
return std::string(db_path) + "/abra_db.yml";
}
/**
* Reads and parses an entry from the abra_db.
* @param node: YAML node containing the entry.
* @return count of successfully parsed rows
*/ */
static bool skill_parse_row_abradb(char* split[], int columns, int current) uint64 AbraDatabase::parseBodyNode(const YAML::Node &node) {
{ std::string skill_name;
unsigned short i, skill_id = atoi(split[0]);
if (!skill_get_index(skill_id) || !skill_get_max(skill_id)) { if (!this->asString(node, "Skill", skill_name))
ShowError("skill_parse_row_abradb: Invalid skill ID %d\n", skill_id); return 0;
return false;
uint16 skill_id = skill_name2id(skill_name.c_str());
if (!skill_id) {
this->invalidWarning(node["Skill"], "Invalid Abra skill name \"%s\", skipping.\n", skill_name.c_str());
return 0;
} }
if (!skill_get_inf(skill_id)) { if (!skill_get_inf(skill_id)) {
ShowError("skill_parse_row_abradb: Passive skills cannot be casted (%d/%s)\n", skill_id, skill_get_name(skill_id)); this->invalidWarning(node["Skill"], "Passive skill %s cannot be casted by Abra.\n", skill_name.c_str());
return false; return 0;
} }
ARR_FIND(0, skill_abra_count, i, skill_abra_db[i].skill_id==skill_id); std::shared_ptr<s_skill_abra_db> abra = this->find(skill_id);
if (i >= ARRAYLENGTH(skill_abra_db)) { bool exists = abra != nullptr;
ShowError("skill_parse_row_abradb: Maximum db entries reached.\n");
return false; if (!exists) {
} abra = std::make_shared<s_skill_abra_db>();
// Import just for clearing/disabling from original data abra->skill_id = skill_id;
if (strcmp(split[1],"clear") == 0) {
memset(&skill_abra_db[i], 0, sizeof(skill_abra_db[i]));
//ShowInfo("skill_parse_row_abradb: Skill %d removed from list.\n", skill_id);
return true;
} }
skill_abra_db[i].skill_id = skill_id; if (this->nodeExists(node, "Probability")) {
safestrncpy(skill_abra_db[i].name, trim(split[1]), sizeof(skill_abra_db[i].name)); //store dummyname const YAML::Node probNode = node["Probability"];
skill_split_atoi(split[2],skill_abra_db[i].per); uint16 probability;
if (i == skill_abra_count)
skill_abra_count++;
return true; if (probNode.IsScalar()) {
if (!this->asUInt16Rate(probNode, "Probability", probability))
return 0;
if (!probability) {
this->invalidWarning(probNode["Probability"], "Probability has to be within the range of 1~10000, skipping.\n");
return 0;
}
abra->per.fill(probability);
} else {
abra->per.fill(0);
for (const YAML::Node &it : probNode) {
uint16 skill_lv;
if (!this->asUInt16(it, "Level", skill_lv))
continue;
if (skill_lv > MAX_SKILL_LEVEL) {
this->invalidWarning(it["Level"], "Probability Level exceeds the maximum skill level of %d, skipping.\n", MAX_SKILL_LEVEL);
return 0;
}
if (!this->asUInt16Rate(it, "Probability", probability))
continue;
if (!probability) {
this->invalidWarning(it["Probability"], "Probability has to be within the range of 1~10000, skipping.\n");
return 0;
}
abra->per[skill_lv - 1] = probability;
}
}
} else {
if (!exists)
abra->per.fill(500);
}
if (!exists)
this->put(skill_id, abra);
return 1;
} }
/** Reads change material db /** Reads change material db
@@ -21762,7 +21812,6 @@ static void skill_db_destroy(void) {
* skill_unit_db.txt * skill_unit_db.txt
* produce_db.txt * produce_db.txt
* create_arrow_db.txt * create_arrow_db.txt
* abra_db.txt
*------------------------------*/ *------------------------------*/
static void skill_readdb(void) static void skill_readdb(void)
{ {
@@ -21782,10 +21831,9 @@ static void skill_readdb(void)
memset(skill_produce_db,0,sizeof(skill_produce_db)); memset(skill_produce_db,0,sizeof(skill_produce_db));
memset(skill_arrow_db,0,sizeof(skill_arrow_db)); memset(skill_arrow_db,0,sizeof(skill_arrow_db));
memset(skill_abra_db,0,sizeof(skill_abra_db));
memset(skill_spellbook_db,0,sizeof(skill_spellbook_db)); memset(skill_spellbook_db,0,sizeof(skill_spellbook_db));
memset(skill_changematerial_db,0,sizeof(skill_changematerial_db)); memset(skill_changematerial_db,0,sizeof(skill_changematerial_db));
skill_produce_count = skill_arrow_count = skill_abra_count = skill_improvise_count = skill_produce_count = skill_arrow_count = skill_improvise_count =
skill_changematerial_count = skill_spellbook_count = 0; skill_changematerial_count = skill_spellbook_count = 0;
for(i=0; i<ARRAYLENGTH(dbsubpath); i++){ for(i=0; i<ARRAYLENGTH(dbsubpath); i++){
@@ -21811,7 +21859,6 @@ static void skill_readdb(void)
sv_readdb(dbsubpath2, "produce_db.txt" , ',', 5, 5+2*MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill_parse_row_producedb, i > 0); sv_readdb(dbsubpath2, "produce_db.txt" , ',', 5, 5+2*MAX_PRODUCE_RESOURCE, MAX_SKILL_PRODUCE_DB, skill_parse_row_producedb, i > 0);
sv_readdb(dbsubpath1, "create_arrow_db.txt" , ',', 1+2, 1+2*MAX_ARROW_RESULT, MAX_SKILL_ARROW_DB, skill_parse_row_createarrowdb, i > 0); sv_readdb(dbsubpath1, "create_arrow_db.txt" , ',', 1+2, 1+2*MAX_ARROW_RESULT, MAX_SKILL_ARROW_DB, skill_parse_row_createarrowdb, i > 0);
sv_readdb(dbsubpath1, "abra_db.txt" , ',', 3, 3, MAX_SKILL_ABRA_DB, skill_parse_row_abradb, i > 0);
sv_readdb(dbsubpath1, "spellbook_db.txt" , ',', 3, 3, MAX_SKILL_SPELLBOOK_DB, skill_parse_row_spellbookdb, i > 0); sv_readdb(dbsubpath1, "spellbook_db.txt" , ',', 3, 3, MAX_SKILL_SPELLBOOK_DB, skill_parse_row_spellbookdb, i > 0);
sv_readdb(dbsubpath1, "skill_copyable_db.txt" , ',', 2, 4, -1, skill_parse_row_copyabledb, i > 0); sv_readdb(dbsubpath1, "skill_copyable_db.txt" , ',', 2, 4, -1, skill_parse_row_copyabledb, i > 0);
sv_readdb(dbsubpath1, "skill_improvise_db.txt" , ',', 2, 2, MAX_SKILL_IMPROVISE_DB, skill_parse_row_improvisedb, i > 0); sv_readdb(dbsubpath1, "skill_improvise_db.txt" , ',', 2, 2, MAX_SKILL_IMPROVISE_DB, skill_parse_row_improvisedb, i > 0);
@@ -21823,6 +21870,7 @@ static void skill_readdb(void)
aFree(dbsubpath2); aFree(dbsubpath2);
} }
abra_db.load();
magic_mushroom_db.load(); magic_mushroom_db.load();
skill_init_unit_layout(); skill_init_unit_layout();

View File

@@ -4,6 +4,8 @@
#ifndef SKILL_HPP #ifndef SKILL_HPP
#define SKILL_HPP #define SKILL_HPP
#include <array>
#include "../common/cbasetypes.hpp" #include "../common/cbasetypes.hpp"
#include "../common/database.hpp" #include "../common/database.hpp"
#include "../common/db.hpp" #include "../common/db.hpp"
@@ -26,7 +28,6 @@ struct status_change_entry;
#define MAX_PRODUCE_RESOURCE 12 /// Max Produce requirements #define MAX_PRODUCE_RESOURCE 12 /// Max Produce requirements
#define MAX_SKILL_ARROW_DB 150 /// Max Arrow Creation DB #define MAX_SKILL_ARROW_DB 150 /// Max Arrow Creation DB
#define MAX_ARROW_RESULT 5 /// Max Arrow results/created #define MAX_ARROW_RESULT 5 /// Max Arrow results/created
#define MAX_SKILL_ABRA_DB 160 /// Max Skill list of Abracadabra DB
#define MAX_SKILL_IMPROVISE_DB 30 /// Max Skill for Improvise #define MAX_SKILL_IMPROVISE_DB 30 /// Max Skill for Improvise
#define MAX_SKILL_LEVEL 13 /// Max Skill Level (for skill_db storage) #define MAX_SKILL_LEVEL 13 /// Max Skill Level (for skill_db storage)
#define MAX_MOBSKILL_LEVEL 100 /// Max monster skill level (on skill usage) #define MAX_MOBSKILL_LEVEL 100 /// Max monster skill level (on skill usage)
@@ -371,11 +372,18 @@ extern struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB];
/// Abracadabra database /// Abracadabra database
struct s_skill_abra_db { struct s_skill_abra_db {
uint16 skill_id; /// Skill ID uint16 skill_id; /// Skill ID
char name[SKILL_NAME_LENGTH]; /// Shouted skill name std::array<uint16, MAX_SKILL_LEVEL> per; /// Probability summoned
int per[MAX_SKILL_LEVEL]; /// Probability summoned };
class AbraDatabase : public TypesafeYamlDatabase<uint16, s_skill_abra_db> {
public:
AbraDatabase() : TypesafeYamlDatabase("ABRA_DB", 1) {
}
const std::string getDefaultLocation();
uint64 parseBodyNode(const YAML::Node& node);
}; };
extern struct s_skill_abra_db skill_abra_db[MAX_SKILL_ABRA_DB];
extern unsigned short skill_abra_count;
void do_init_skill(void); void do_init_skill(void);
void do_final_skill(void); void do_final_skill(void);

View File

@@ -70,6 +70,7 @@ int getch( void ){
static bool guild_read_guildskill_tree_db( char* split[], int columns, int current ); static bool guild_read_guildskill_tree_db( char* split[], int columns, int current );
static size_t pet_read_db( const char* file ); static size_t pet_read_db( const char* file );
static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current); static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current);
static bool skill_parse_row_abradb(char* split[], int columns, int current);
// Constants for conversion // Constants for conversion
std::unordered_map<uint16, std::string> aegis_itemnames; std::unordered_map<uint16, std::string> aegis_itemnames;
@@ -241,6 +242,12 @@ int do_init( int argc, char** argv ){
return 0; return 0;
} }
if (!process("ABRA_DB", 1, root_paths, "abra_db", [](const std::string& path, const std::string& name_ext) -> bool {
return sv_readdb(path.c_str(), name_ext.c_str(), ',', 3, 3, -1, &skill_parse_row_abradb, false);
})) {
return 0;
}
// TODO: add implementations ;-) // TODO: add implementations ;-)
return 0; return 0;
@@ -426,6 +433,34 @@ static bool parse_skill_constants( char* split[], int columns, int current ){
return true; return true;
} }
/**
* Split the string with ':' as separator and put each value for a skilllv
* if no more value found put the last value to fill the array
* @param str: String to split
* @param val: Array of MAX_SKILL_LEVEL to put value into
* @return 0:error, x:number of value assign (should be MAX_SKILL_LEVEL)
*/
int skill_split_atoi(char *str, int *val) {
int i;
for (i = 0; i < MAX_SKILL_LEVEL; i++) {
if (!str)
break;
val[i] = atoi(str);
str = strchr(str, ':');
if (str)
*str++ = 0;
}
if (i == 0) // No data found.
return 0;
if (i == 1) // Single value, have the whole range have the same value.
return 1;
return i;
}
// Implementation of the conversion functions // Implementation of the conversion functions
// Copied and adjusted from guild.cpp // Copied and adjusted from guild.cpp
@@ -654,6 +689,7 @@ static size_t pet_read_db( const char* file ){
return entries; return entries;
} }
// Copied and adjusted from skill.cpp
static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current) static bool skill_parse_row_magicmushroomdb(char* split[], int column, int current)
{ {
uint16 skill_id = atoi(split[0]); uint16 skill_id = atoi(split[0]);
@@ -670,3 +706,43 @@ static bool skill_parse_row_magicmushroomdb(char* split[], int column, int curre
return true; return true;
} }
// Copied and adjusted from skill.cpp
static bool skill_parse_row_abradb(char* split[], int columns, int current)
{
uint16 skill_id = atoi(split[0]);
std::string *skill_name = util::umap_find(aegis_skillnames, skill_id);
if (skill_name == nullptr) {
ShowError("Skill name for Abra skill ID &hu is not known.\n", skill_id);
return false;
}
body << YAML::BeginMap;
body << YAML::Key << "Skill" << YAML::Value << *skill_name;
int arr[MAX_SKILL_LEVEL];
int arr_size = skill_split_atoi(split[2], arr);
if (arr_size == 1) {
if (arr[0] != 500)
body << YAML::Key << "Probability" << YAML::Value << arr[0];
} else {
body << YAML::Key << "Probability";
body << YAML::BeginSeq;
for (int i = 0; i < arr_size; i++) {
if (arr[i] > 0) {
body << YAML::BeginMap;
body << YAML::Key << "Level" << YAML::Value << i + 1;
body << YAML::Key << "Probability" << YAML::Value << arr[i];
body << YAML::EndMap;
}
}
body << YAML::EndSeq;
}
body << YAML::EndMap;
return true;
}