diff --git a/db/create_arrow_db.txt b/db/create_arrow_db.txt
deleted file mode 100644
index f8231f97fc..0000000000
--- a/db/create_arrow_db.txt
+++ /dev/null
@@ -1,289 +0,0 @@
-// Arrow Crafting Database
-//
-// Structure of Database:
-// SourceID,MakeID1,MakeAmount1,...,MakeID5,MakeAmount5
-//
-// 01. SourceID ID of the item, that is consumed by Arrow Crafting.
-// 02. MakeID ID of the item received from Arrow Crafting.
-// 03. MakeAmount Amount of MakeID item received from Arrow Crafting.
-// ...
-//
-// NOTE:
-// - Up to MAX_ARROW_RESULT (typically 5) ID/Amount pairs can be specified.
-// - To remove entry by importing, put 0 on 'MakeID'
-
-// Old Blue Box --> 50 Sharp Arrows, 50 Sleep Arrows
-603,1764,50,1768,50
-// Dead Branch --> 40 Mute Arrows
-604,1769,40
-// Amulet --> 40 Cursed Arrows
-609,1761,40
-// Empty Bottle --> 2 Iron Arrows
-713,1770,2
-// Emperium --> 600 Immaterial Arrows, 600 Mute Arrows, 600 Oridecon Arrows
-714,1757,600,1769,600,1765,600
-// Yellow Gemstone --> 30 Stone Arrows, 1 Sleep Arrow
-715,1756,30,1768,1
-// Red Gemstone --> 10 Rusty Arrows, 1 Poison Arrow, 1 Cursed Arrow
-716,1762,10,1763,1,1761,1
-// Blue Gemstone --> 30 Crystal Arrows, 1 Frozen Arrow
-717,1754,30,1759,1
-// Cursed Ruby --> 50 Cursed Arrows, 10 Sleep Arrows
-724,1761,50,1768,10
-// Cracked Diamond --> 50 Sharp Arrows
-733,1764,50
-// Rough Oridecon --> 50 Oridecon Arrows
-756,1765,50
-// Rough Elunium --> 200 Steel Arrows, 5 Stun Arrows
-757,1753,200,1758,5
-// Tree Root --> 7 Arrows
-902,1750,7
-// Scorpion Tail --> 3 Rusty Arrows
-904,1762,3
-// Jellopy --> 4 Arrows
-909,1750,4
-// Garlet --> 12 Iron Arrows
-910,1770,12
-// Scell --> 8 Steel Arrows
-911,1753,8
-// Zargon --> 50 Silver Arrows
-912,1751,50
-// Tooth of Bat --> 1 Shadow Arrow
-913,1767,1
-// Wolf Claw --> 15 Iron Arrows
-920,1770,15
-// Orc's Fang --> 30 Iron Arrows, 5 Steel Arrows, 10 Stone Arrows
-922,1770,30,1753,5,1756,10
-// Evil Horn --> 20 Shadow Arrows, 10 Flash Arrows, 5 Stun Arrows
-923,1767,20,1760,10,1758,5
-// Venom Canine --> 1 Poison Arrow
-937,1763,1
-// Bee Sting --> 1 Rusty Arrow
-939,1762,1
-// Horn --> 35 Iron Arrows
-947,1770,35
-// Cactus Needle --> 50 Arrows
-952,1750,50
-// Gill --> 80 Iron Arrows, 150 Crystal Arrows
-956,1770,80,1754,150
-// Decayed Nail --> 1 Rusty Arrow, 1 Shadow Arrow
-957,1762,1,1767,1
-// Horrendous Mouth --> 5 Shadow Arrows
-958,1767,5
-// Stinky Scale --> 1 Poison Arrow
-959,1763,1
-// Heroic Emblem --> 1 Oridecon Arrow, 5 Stun Arrows
-968,1765,1,1758,5
-// Gold --> 50 Flash Arrows, 50 Oridecon Arrows
-969,1760,50,1765,50
-// Oridecon --> 250 Oridecon Arrows
-984,1765,250
-// Elunium --> 1000 Steel Arrows, 50 Stun Arrows
-985,1753,1000,1758,50
-// Red Blood --> 600 Fire Arrows
-990,1752,600
-// Crystal Blue --> 150 Crystal Arrows
-991,1754,150
-// Wind of Verdure --> 150 Arrows of Wind
-992,1755,150
-// Green Live --> 150 Stone Arrows
-993,1756,150
-// Flame Heart --> 1800 Fire Arrows, 5 Mute Arrows
-994,1752,1800,1769,5
-// Mystic Frozen --> 450 Crystal Arrows, 5 Frozen Arrows
-995,1754,450,1759,5
-// Rough Wind --> 450 Arrows of Wind, 5 Sleep Arrows
-996,1755,450,1768,5
-// Great Nature --> 450 Stone Arrows, 5 Flash Arrows
-997,1756,450,1760,5
-// Iron --> 100 Iron Arrows
-998,1770,100
-// Steel --> 100 Steel Arrows
-999,1753,100
-// Star Crumb --> 30 Flash Arrows
-1000,1760,30
-// Star Dust --> 10 Flash Arrows
-1001,1760,10
-// Iron Ore --> 50 Iron Arrows
-1002,1770,50
-// Coal --> 8 Shadow Arrows
-1003,1767,8
-// Phracon --> 50 Iron Arrows
-1010,1770,50
-// Emveretarcon --> 200 Iron Arrows, 40 Silver Arrows
-1011,1770,200,1751,40
-// Mole Claw --> 50 Iron Arrows, 60 Stone Arrows
-1018,1770,50,1756,60
-// Trunk --> 40 Arrows
-1019,1750,40
-// Dokebi Horn --> 40 Iron Arrows, 2 Shadow Arrows
-1021,1770,40,1767,2
-// Porcupine Quill --> 70 Arrows, 30 Stone Arrows
-1027,1750,70,1756,30
-// Mantis Scythe --> 1 Sharp Arrow
-1031,1764,1
-// Dragon Canine --> 1 Oridecon Arrow, 50 Iron Arrows
-1035,1765,1,1770,50
-// Little Evil Horn --> 2 Cursed Arrows, 50 Iron Arrows
-1038,1761,2,1770,50
-// Lantern --> 80 Iron Arrows
-1041,1770,80
-// Orc Claw --> 10 Steel Arrows
-1043,1753,10
-// Zenorc's Fang --> 5 Rusty Arrows
-1044,1762,5
-// Ancient Tooth --> 20 Steel Arrows, 300 Crystal Arrows
-1053,1753,20,1754,300
-// Fang --> 2 Sharp Arrows, 40 Silver Arrows
-1063,1764,2,1751,40
-// Reins --> 100 Iron Arrows, 50 Steel Arrows
-1064,1770,100,1753,50
-// Fine-grained Trunk --> 20 Arrows
-1066,1750,20
-// Solid Trunk --> 20 Arrows
-1067,1750,20
-// Barren Trunk --> 20 Arrows
-1068,1750,20
-// Clock Hand --> 5 Sleep Arrows, 100 Arrows
-1095,1768,5,1750,100
-// Manacles --> 50 Steel Arrows
-1098,1753,50
-// Unicorn Horn --> 1000 Silver Arrows
-2257,1751,1000
-// Opera Masque --> 200 Steel Arrows, 40 Mute Arrows
-2281,1753,200,1769,40
-// Mr. Scream --> 200 Sharp Arrows, 300 Steel Arrows
-2288,1764,200,1753,300
-// Welding Mask --> 200 Steel Arrows, 40 Stun Arrows
-2292,1753,200,1758,40
-// Glittering Jacket --> 1000 Flash Arrows
-2319,1760,1000
-// Wooden Mail --> 700 Arrows, 500 Iron Arrows
-2328,1750,700,1770,500
-// Wooden Mail (Slotted) --> 1000 Arrows, 700 Iron Arrows
-2329,1750,1000,1770,700
-// Silver Robe --> 700 Silver Arrows
-2332,1751,700
-// Silver Robe (Slotted) --> 1000 Silver Arrows, 10 Immaterial Arrows
-2333,1751,1000,1757,10
-// Shackles --> 700 Iron Arrows, 50 Steel Arrows
-2408,1770,700,1753,50
-// Matyr's Leash --> 150 Arrows of Wind, 100 Steel Arrows, 10 Sharp Arrows
-2618,1755,150,1753,100,1764,10
-// Fin Helm --> 600 Crystal Arrows, 200 Steel Arrows
-5014,1754,600,1753,200
-// Ogre Tooth --> 30 Steel Arrows, 5 Rusty Arrows
-7002,1753,30,1762,5
-// Stiff Horn --> 2 Stun Arrows
-7008,1758,2
-// Tail of Steel Scorpion --> 250 Steel Arrows, 1 Poison Arrow
-7010,1753,250,1763,1
-// Young Twig --> 1000 Mute Arrows
-7018,1769,1000
-// Loki's Whispers --> 1000 Shadow Arrows
-7019,1767,1000
-// Mother's Nightmare --> 1000 Cursed Arrows
-7020,1761,1000
-// Foolishness of the Blind --> 200 Flash Arrows
-7021,1760,200
-// Old Hilt --> 1000 Oridecon Arrows
-7022,1765,1000
-// Blade of Darkness --> 600 Sharp Arrows, 200 Shadow Arrows
-7023,1764,600,1767,200
-// Bloody Edge --> 600 Sharp Arrows, 200 Cursed Arrows
-7024,1764,600,1761,200
-// Lucifer's Lament --> 800 Stun Arrows, 400 Mute Arrows, 800 Sleep Arrows
-7025,1758,800,1769,400,1768,800
-// Key of the Clock Tower --> 50 Oridecon Arrows
-7026,1765,50
-// Key of the Underground --> 100 Shadow Arrows
-7027,1767,100
-// Matchstick --> 3000 Fire Arrows
-7035,1752,3000
-// Fang of Garm --> 300 Crystal Arrows
-7036,1754,300
-
-//New Ingredients
-
-// Ice Cubic --> 100 Crystal Arrows
-7066,1754,100
-// Stone Fragment --> 50 Stone Arrows, 30 Stun Arrows
-7067,1756,50,1758,30
-// Burnt Tree --> 250 Fire Arrows
-7068,1752,250
-// Destroyed Armor --> 150 Steel Arrows
-7069,1753,150
-// Burning Heart --> 150 Fire Arrows
-7097,1752,150
-// Live Coal --> 100 Fire Arrows
-7098,1752,100
-// Sharp Leaf --> 30 Sharp Arrows
-7100,1764,30
-// Piece of Shield --> 100 Steel Arrows, 100 Oridecon Arrows, 300 Immaterial Arrows
-7108,1753,100,1765,100,1757,300
-// Shining Spear Blade --> 100 Oridecon Arrows
-7109,1765,100
-// Burning Horseshoe --> 100 Steel Arrows
-7120,1753,100
-// Dragon Skin --> 10 Steel Arrows, 50 Cursed Arrows, 50 Mute Arrows
-7123,1753,10,1761,50,1769,50
-// Piece of Bamboo --> 100 Arrows
-7150,1750,100
-// Poisonous Toad Skin --> 20 Poison Arrows
-7155,1763,20
-// Hard Feeler --> 20 Sharp Arrows
-7163,1764,20
-// Solid Peach --> 30 Stun Arrows
-7164,1758,30
-// Leopard Claw --> 10 Sharp Arrows
-7172,1764,10
-// Armor Piece of Dullahan --> 150 Shadow Arrows
-7210,1767,150
-// Tangled Chains --> 50 Steel Arrows, 50 Shadow Arrows
-7221,1753,50,1767,50
-// Cat's Eye --> 200 Arrows of Wind
-7263,1755,200
-// Dark Crystal Fragment --> 30 Cursed Arrows, 50 Shadow Arrows
-7315,1761,30,1767,50
-// Insect Leg --> 10 Sharp Arrows, 50 Poison Arrows
-7316,1764,10,1763,50
-// Old Pick --> 100 Rusty Arrows, 50 Steel Arrows
-7318,1762,100,1753,50
-// Used Iron Plate --> 100 Rusty Arrows, 100 Steel Arrows
-7319,1762,100,1753,100
-// Crystal Fragment --> 10 Flash Arrows, 30 Sleep Arrows
-7321,1760,10,1768,30
-// Battered Kettle --> 50 Steel Arrows
-7323,1753,50
-// Will of the Darkness --> 30 Cursed Arrows, 30 Poison Arrows, 50 Shadow Arrows
-7340,1761,30,1763,30,1767,50
-// Golden Ornament --> 200 Silver Arrows, 300 Holy Arrows
-7435,1751,200,1772,300
-// Cursed Seal --> 50 Cursed Arrows, 50 Mute Arrows
-7442,1761,50,1769,50
-// Green Bijou --> 100 Stone Arrows, 80 Poison Arrows
-7445,1756,100,1763,80
-// Blue Bijou --> 50 Arrows of Wind, 50 Crystal Arrows, 80 Frozen Arrows
-7446,1755,50,1754,50,1759,80
-// Red Bijou --> 100 Fire Arrows, 80 Flash Arrows
-7447,1752,100,1760,80
-// Yellow Bijou --> 50 Silver Arrows, 50 Immaterial Arrows, 80 Sleep Arrows
-7448,1751,50,1757,50,1768,80
-// Skeletal Armor Piece --> 500 Immaterial Arrows, 200 Shadow Arrows, 100 Oridecon Arrows
-7450,1757,500,1767,200,1765,100
-// Fire Dragon Scale --> 300 Fire Arrows, 300 Stun Arrows
-7451,1752,300,1758,300
-// Valhalla's Flower --> 600 Immaterial Arrows, 600 Holy Arrows, 600 Sharp Arrows
-7510,1757,600,1772,600,1764,600
-// Darkness Rune --> 300 Shadow Arrows, 150 Flash Arrows
-7511,1767,300,1760,150
-// Ice Heart --> 50 Crystal Arrows, 50 Frozen Arrows
-7561,1754,50,1759,50
-// Ice Scale --> 150 Crystal Arrows, 400 Frozen Arrows, 200 Mute Arrows
-7562,1754,150,1759,400,1769,200
-// Will of Red Darkness --> 200 Cursed Arrows, 200 Poison Arrows, 100 Shadow Arrows
-7566,1761,200,1763,200,1767,100
-// Clattering Skull --> 50 Shadow Arrows, 50 Cursed Arrows
-7752,1767,50,1761,50
-// Broken Farm Tools --> 50 Rusty Arrows, 10 Iron Arrows, 20 Cursed Arrows
-7753,1762,50,1770,10,1761,20
diff --git a/db/create_arrow_db.yml b/db/create_arrow_db.yml
new file mode 100644
index 0000000000..54041a6e4a
--- /dev/null
+++ b/db/create_arrow_db.yml
@@ -0,0 +1,749 @@
+# 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 .
+#
+###########################################################################
+# Arrow Crafting Database
+###########################################################################
+#
+# Arrow Crafting Settings
+#
+###########################################################################
+# - Source AegisName of the item that is consumed.
+# Make: List of item(s) received by the player.
+# - Item AegisName of the item received.
+# Amount Amount of Item received. (Use 0 to remove the Item on import)
+###########################################################################
+
+Header:
+ Type: CREATE_ARROW_DB
+ Version: 1
+
+Body:
+ - Source: Old_Blue_Box
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 50
+ - Item: Sleep_Arrow
+ Amount: 50
+ - Source: Branch_Of_Dead_Tree
+ Make:
+ - Item: Silence_Arrow
+ Amount: 40
+ - Source: Amulet
+ Make:
+ - Item: Curse_Arrow
+ Amount: 40
+ - Source: Empty_Bottle
+ Make:
+ - Item: Iron_Arrow
+ Amount: 2
+ - Source: Emperium
+ Make:
+ - Item: Immatrial_Arrow
+ Amount: 600
+ - Item: Oridecon_Arrow
+ Amount: 600
+ - Item: Silence_Arrow
+ Amount: 600
+ - Source: Yellow_Gemstone
+ Make:
+ - Item: Sleep_Arrow
+ Amount: 1
+ - Item: Stone_Arrow
+ Amount: 30
+ - Source: Red_Gemstone
+ Make:
+ - Item: Curse_Arrow
+ Amount: 1
+ - Item: Poison_Arrow
+ Amount: 1
+ - Item: Rusty_Arrow
+ Amount: 10
+ - Source: Blue_Gemstone
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 30
+ - Item: Freezing_Arrow
+ Amount: 1
+ - Source: Cardinal_Jewel_
+ Make:
+ - Item: Curse_Arrow
+ Amount: 50
+ - Item: Sleep_Arrow
+ Amount: 10
+ - Source: Crystal_Jewel___
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 50
+ - Source: Oridecon_Stone
+ Make:
+ - Item: Oridecon_Arrow
+ Amount: 50
+ - Source: Elunium_Stone
+ Make:
+ - Item: Steel_Arrow
+ Amount: 200
+ - Item: Stun_Arrow
+ Amount: 5
+ - Source: Tree_Root
+ Make:
+ - Item: Arrow
+ Amount: 7
+ - Source: Scorpion's_Tail
+ Make:
+ - Item: Rusty_Arrow
+ Amount: 3
+ - Source: Jellopy
+ Make:
+ - Item: Arrow
+ Amount: 4
+ - Source: Garlet
+ Make:
+ - Item: Iron_Arrow
+ Amount: 12
+ - Source: Scell
+ Make:
+ - Item: Steel_Arrow
+ Amount: 8
+ - Source: Zargon
+ Make:
+ - Item: Silver_Arrow
+ Amount: 50
+ - Source: Tooth_Of_Bat
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 1
+ - Source: Claw_Of_Wolves
+ Make:
+ - Item: Iron_Arrow
+ Amount: 15
+ - Source: Orcish_Cuspid
+ Make:
+ - Item: Iron_Arrow
+ Amount: 30
+ - Item: Steel_Arrow
+ Amount: 5
+ - Item: Stone_Arrow
+ Amount: 10
+ - Source: Evil_Horn
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 20
+ - Item: Flash_Arrow
+ Amount: 10
+ - Item: Stun_Arrow
+ Amount: 5
+ - Source: Posionous_Canine
+ Make:
+ - Item: Poison_Arrow
+ Amount: 1
+ - Source: Bee_Sting
+ Make:
+ - Item: Rusty_Arrow
+ Amount: 1
+ - Source: Horn
+ Make:
+ - Item: Iron_Arrow
+ Amount: 35
+ - Source: Cactus_Needle
+ Make:
+ - Item: Arrow
+ Amount: 50
+ - Source: Gill
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 150
+ - Item: Iron_Arrow
+ Amount: 80
+ - Source: Decayed_Nail
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 1
+ - Item: Rusty_Arrow
+ Amount: 1
+ - Source: Horrendous_Mouth
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 5
+ - Source: Rotten_Scale
+ Make:
+ - Item: Poison_Arrow
+ Amount: 1
+ - Source: Voucher_Of_Orcish_Hero
+ Make:
+ - Item: Oridecon_Arrow
+ Amount: 1
+ - Item: Stun_Arrow
+ Amount: 5
+ - Source: Gold
+ Make:
+ - Item: Flash_Arrow
+ Amount: 50
+ - Item: Oridecon_Arrow
+ Amount: 50
+ - Source: Oridecon
+ Make:
+ - Item: Oridecon_Arrow
+ Amount: 250
+ - Source: Elunium
+ Make:
+ - Item: Steel_Arrow
+ Amount: 1000
+ - Item: Stun_Arrow
+ Amount: 50
+ - Source: Boody_Red
+ Make:
+ - Item: Fire_Arrow
+ Amount: 600
+ - Source: Crystal_Blue
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 150
+ - Source: Wind_Of_Verdure
+ Make:
+ - Item: Arrow_Of_Wind
+ Amount: 150
+ - Source: Yellow_Live
+ Make:
+ - Item: Stone_Arrow
+ Amount: 150
+ - Source: Flame_Heart
+ Make:
+ - Item: Fire_Arrow
+ Amount: 1800
+ - Item: Silence_Arrow
+ Amount: 5
+ - Source: Mistic_Frozen
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 450
+ - Item: Freezing_Arrow
+ Amount: 5
+ - Source: Rough_Wind
+ Make:
+ - Item: Arrow_Of_Wind
+ Amount: 450
+ - Item: Sleep_Arrow
+ Amount: 5
+ - Source: Great_Nature
+ Make:
+ - Item: Flash_Arrow
+ Amount: 5
+ - Item: Stone_Arrow
+ Amount: 450
+ - Source: Iron
+ Make:
+ - Item: Iron_Arrow
+ Amount: 100
+ - Source: Steel
+ Make:
+ - Item: Steel_Arrow
+ Amount: 100
+ - Source: Star_Crumb
+ Make:
+ - Item: Flash_Arrow
+ Amount: 30
+ - Source: Sparkling_Dust
+ Make:
+ - Item: Flash_Arrow
+ Amount: 10
+ - Source: Iron_Ore
+ Make:
+ - Item: Iron_Arrow
+ Amount: 50
+ - Source: Coal
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 8
+ - Source: Phracon
+ Make:
+ - Item: Iron_Arrow
+ Amount: 50
+ - Source: Emveretarcon
+ Make:
+ - Item: Iron_Arrow
+ Amount: 200
+ - Item: Silver_Arrow
+ Amount: 40
+ - Source: Nail_Of_Mole
+ Make:
+ - Item: Iron_Arrow
+ Amount: 50
+ - Item: Stone_Arrow
+ Amount: 60
+ - Source: Wooden_Block
+ Make:
+ - Item: Arrow
+ Amount: 40
+ - Source: Dokkaebi_Horn
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 2
+ - Item: Iron_Arrow
+ Amount: 40
+ - Source: Porcupine_Spike
+ Make:
+ - Item: Arrow
+ Amount: 70
+ - Item: Stone_Arrow
+ Amount: 30
+ - Source: Limb_Of_Mantis
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 1
+ - Source: Dragon_Canine
+ Make:
+ - Item: Iron_Arrow
+ Amount: 50
+ - Item: Oridecon_Arrow
+ Amount: 1
+ - Source: Petite_DiablOfs_Horn
+ Make:
+ - Item: Curse_Arrow
+ Amount: 2
+ - Item: Iron_Arrow
+ Amount: 50
+ - Source: Lantern
+ Make:
+ - Item: Iron_Arrow
+ Amount: 80
+ - Source: Nail_Of_Orc
+ Make:
+ - Item: Steel_Arrow
+ Amount: 10
+ - Source: Tooth_Of_
+ Make:
+ - Item: Rusty_Arrow
+ Amount: 5
+ - Source: Tooth_Of_Ancient_Fish
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 300
+ - Item: Steel_Arrow
+ Amount: 20
+ - Source: Sharpened_Cuspid
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 2
+ - Item: Silver_Arrow
+ Amount: 40
+ - Source: Reins
+ Make:
+ - Item: Iron_Arrow
+ Amount: 100
+ - Item: Steel_Arrow
+ Amount: 50
+ - Source: Tree_Of_Archer_1
+ Make:
+ - Item: Arrow
+ Amount: 20
+ - Source: Tree_Of_Archer_2
+ Make:
+ - Item: Arrow
+ Amount: 20
+ - Source: Tree_Of_Archer_3
+ Make:
+ - Item: Arrow
+ Amount: 20
+ - Source: Needle_Of_Alarm
+ Make:
+ - Item: Arrow
+ Amount: 100
+ - Item: Sleep_Arrow
+ Amount: 5
+ - Source: Manacles
+ Make:
+ - Item: Steel_Arrow
+ Amount: 50
+ - Source: Snowy_Horn
+ Make:
+ - Item: Silver_Arrow
+ Amount: 1000
+ - Source: Phantom_Of_Opera
+ Make:
+ - Item: Silence_Arrow
+ Amount: 40
+ - Item: Steel_Arrow
+ Amount: 200
+ - Source: Mr_Scream
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 200
+ - Item: Steel_Arrow
+ Amount: 300
+ - Source: Welding_Mask
+ Make:
+ - Item: Steel_Arrow
+ Amount: 200
+ - Item: Stun_Arrow
+ Amount: 40
+ - Source: Glittering_Clothes
+ Make:
+ - Item: Flash_Arrow
+ Amount: 1000
+ - Source: Wooden_Mail
+ Make:
+ - Item: Arrow
+ Amount: 700
+ - Item: Iron_Arrow
+ Amount: 500
+ - Source: Wooden_Mail_
+ Make:
+ - Item: Arrow
+ Amount: 1000
+ - Item: Iron_Arrow
+ Amount: 700
+ - Source: Silver_Robe
+ Make:
+ - Item: Silver_Arrow
+ Amount: 700
+ - Source: Silver_Robe_
+ Make:
+ - Item: Immatrial_Arrow
+ Amount: 10
+ - Item: Silver_Arrow
+ Amount: 1000
+ - Source: Cuffs
+ Make:
+ - Item: Iron_Arrow
+ Amount: 700
+ - Item: Steel_Arrow
+ Amount: 50
+ - Source: Matyr's_Flea_Guard
+ Make:
+ - Item: Arrow_Of_Wind
+ Amount: 150
+ - Item: Incisive_Arrow
+ Amount: 10
+ - Item: Steel_Arrow
+ Amount: 100
+ - Source: Fin_Helm
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 600
+ - Item: Steel_Arrow
+ Amount: 200
+ - Source: Ogre_Tooth
+ Make:
+ - Item: Rusty_Arrow
+ Amount: 5
+ - Item: Steel_Arrow
+ Amount: 30
+ - Source: Stiff_Horn
+ Make:
+ - Item: Stun_Arrow
+ Amount: 2
+ - Source: Tail_Of_Steel_Scorpion
+ Make:
+ - Item: Poison_Arrow
+ Amount: 1
+ - Item: Steel_Arrow
+ Amount: 250
+ - Source: Young_Twig
+ Make:
+ - Item: Silence_Arrow
+ Amount: 1000
+ - Source: Loki's_Whispers
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 1000
+ - Source: Mother's_Nightmare
+ Make:
+ - Item: Curse_Arrow
+ Amount: 1000
+ - Source: Foolishness_Of_Blind
+ Make:
+ - Item: Flash_Arrow
+ Amount: 200
+ - Source: Old_Hilt
+ Make:
+ - Item: Oridecon_Arrow
+ Amount: 1000
+ - Source: Blade_Lost_In_Darkness
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 200
+ - Item: Incisive_Arrow
+ Amount: 600
+ - Source: Bloody_Edge
+ Make:
+ - Item: Curse_Arrow
+ Amount: 200
+ - Item: Incisive_Arrow
+ Amount: 600
+ - Source: Lucifer's_Lament
+ Make:
+ - Item: Silence_Arrow
+ Amount: 400
+ - Item: Sleep_Arrow
+ Amount: 800
+ - Item: Stun_Arrow
+ Amount: 800
+ - Source: Key_Of_Clock_Tower
+ Make:
+ - Item: Oridecon_Arrow
+ Amount: 50
+ - Source: Underground_Key
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 100
+ - Source: Matchstick
+ Make:
+ - Item: Fire_Arrow
+ Amount: 3000
+ - Source: Fang_Of_Garm
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 300
+ - Source: Ice_Piece
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 100
+ - Source: Stone_Piece
+ Make:
+ - Item: Stone_Arrow
+ Amount: 50
+ - Item: Stun_Arrow
+ Amount: 30
+ - Source: Burn_Tree
+ Make:
+ - Item: Fire_Arrow
+ Amount: 250
+ - Source: Broken_Armor_Piece
+ Make:
+ - Item: Steel_Arrow
+ Amount: 150
+ - Source: Burning_Heart
+ Make:
+ - Item: Fire_Arrow
+ Amount: 150
+ - Source: Live_Coal
+ Make:
+ - Item: Fire_Arrow
+ Amount: 100
+ - Source: Sharp_Leaf
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 30
+ - Source: Boroken_Shiled_Piece
+ Make:
+ - Item: Immatrial_Arrow
+ Amount: 300
+ - Item: Oridecon_Arrow
+ Amount: 100
+ - Item: Steel_Arrow
+ Amount: 100
+ - Source: Shine_Spear_Blade
+ Make:
+ - Item: Oridecon_Arrow
+ Amount: 100
+ - Source: Burning_Horse_Shoe
+ Make:
+ - Item: Steel_Arrow
+ Amount: 100
+ - Source: Dragon's_Skin
+ Make:
+ - Item: Curse_Arrow
+ Amount: 50
+ - Item: Silence_Arrow
+ Amount: 50
+ - Item: Steel_Arrow
+ Amount: 10
+ - Source: Bamboo_Cut
+ Make:
+ - Item: Arrow
+ Amount: 100
+ - Source: Poison_Toad's_Skin
+ Make:
+ - Item: Poison_Arrow
+ Amount: 20
+ - Source: Sharp_Feeler
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 20
+ - Source: Hard_Peach
+ Make:
+ - Item: Stun_Arrow
+ Amount: 30
+ - Source: Leopard_Talon
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 10
+ - Source: Dullahan_Armor
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 150
+ - Source: Tangled_Chain
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 50
+ - Item: Steel_Arrow
+ Amount: 50
+ - Source: Cat_Eyed_Stone
+ Make:
+ - Item: Arrow_Of_Wind
+ Amount: 200
+ - Source: Dark_Crystal_Fragment
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 50
+ - Item: Curse_Arrow
+ Amount: 30
+ - Source: Long_Limb
+ Make:
+ - Item: Incisive_Arrow
+ Amount: 10
+ - Item: Poison_Arrow
+ Amount: 50
+ - Source: Old_Pick
+ Make:
+ - Item: Rusty_Arrow
+ Amount: 100
+ - Item: Steel_Arrow
+ Amount: 50
+ - Source: Old_Steel_Plate
+ Make:
+ - Item: Rusty_Arrow
+ Amount: 100
+ - Item: Steel_Arrow
+ Amount: 100
+ - Source: Fragment_Of_Crystal
+ Make:
+ - Item: Flash_Arrow
+ Amount: 10
+ - Item: Sleep_Arrow
+ Amount: 30
+ - Source: Battered_Kettle
+ Make:
+ - Item: Steel_Arrow
+ Amount: 50
+ - Source: Will_Of_Darkness
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 50
+ - Item: Curse_Arrow
+ Amount: 30
+ - Item: Poison_Arrow
+ Amount: 30
+ - Source: Golden_Bracelet
+ Make:
+ - Item: Holy_Arrow
+ Amount: 300
+ - Item: Silver_Arrow
+ Amount: 200
+ - Source: Cursed_Seal
+ Make:
+ - Item: Curse_Arrow
+ Amount: 50
+ - Item: Silence_Arrow
+ Amount: 50
+ - Source: Dragonball_Green
+ Make:
+ - Item: Poison_Arrow
+ Amount: 80
+ - Item: Stone_Arrow
+ Amount: 100
+ - Source: Dragonball_Blue
+ Make:
+ - Item: Arrow_Of_Wind
+ Amount: 50
+ - Item: Crystal_Arrow
+ Amount: 50
+ - Item: Freezing_Arrow
+ Amount: 80
+ - Source: Dragonball_Red
+ Make:
+ - Item: Fire_Arrow
+ Amount: 100
+ - Item: Flash_Arrow
+ Amount: 80
+ - Source: Dragonball_Yellow
+ Make:
+ - Item: Immatrial_Arrow
+ Amount: 50
+ - Item: Silver_Arrow
+ Amount: 50
+ - Item: Sleep_Arrow
+ Amount: 80
+ - Source: Piece_Of_Bone_Armor
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 200
+ - Item: Immatrial_Arrow
+ Amount: 500
+ - Item: Oridecon_Arrow
+ Amount: 100
+ - Source: Scale_Of_Red_Dragon
+ Make:
+ - Item: Fire_Arrow
+ Amount: 300
+ - Item: Stun_Arrow
+ Amount: 300
+ - Source: Valhalla_Flower
+ Make:
+ - Item: Holy_Arrow
+ Amount: 600
+ - Item: Immatrial_Arrow
+ Amount: 600
+ - Item: Incisive_Arrow
+ Amount: 600
+ - Source: Rune_Of_Darkness
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 300
+ - Item: Flash_Arrow
+ Amount: 150
+ - Source: Ice_Heart
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 50
+ - Item: Freezing_Arrow
+ Amount: 50
+ - Source: Ice_Scale
+ Make:
+ - Item: Crystal_Arrow
+ Amount: 150
+ - Item: Freezing_Arrow
+ Amount: 400
+ - Item: Silence_Arrow
+ Amount: 200
+ - Source: Will_Of_Darkness_
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 100
+ - Item: Curse_Arrow
+ Amount: 200
+ - Item: Poison_Arrow
+ Amount: 200
+ - Source: Clattering_Skull
+ Make:
+ - Item: Arrow_Of_Shadow
+ Amount: 50
+ - Item: Curse_Arrow
+ Amount: 50
+ - Source: Broken_Farming_Utensil
+ Make:
+ - Item: Curse_Arrow
+ Amount: 20
+ - Item: Iron_Arrow
+ Amount: 10
+ - Item: Rusty_Arrow
+ Amount: 50
+
+Footer:
+ Imports:
+ - Path: db/import/create_arrow_db.yml
diff --git a/db/import-tmpl/create_arrow_db.txt b/db/import-tmpl/create_arrow_db.txt
deleted file mode 100644
index 3b7a22500c..0000000000
--- a/db/import-tmpl/create_arrow_db.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-// Arrow Crafting Database
-//
-// Structure of Database:
-// SourceID,MakeID1,MakeAmount1,...,MakeID5,MakeAmount5
-//
-// 01. SourceID ID of the item, that is consumed by Arrow Crafting.
-// 02. MakeID ID of the item received from Arrow Crafting.
-// 03. MakeAmount Amount of MakeID item received from Arrow Crafting.
-// ...
-//
-// NOTE:
-// - Up to MAX_ARROW_RESULT (typically 5) ID/Amount pairs can be specified.
-// - To remove entry by importing, put 0 on 'MakeID'
-
diff --git a/db/import-tmpl/create_arrow_db.yml b/db/import-tmpl/create_arrow_db.yml
new file mode 100644
index 0000000000..e7f742554a
--- /dev/null
+++ b/db/import-tmpl/create_arrow_db.yml
@@ -0,0 +1,33 @@
+# 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 .
+#
+###########################################################################
+# Arrow Crafting Database
+###########################################################################
+#
+# Arrow Crafting Settings
+#
+###########################################################################
+# - Source AegisName of the item that is consumed.
+# Make: List of item(s) received by the player.
+# - Item AegisName of the item received.
+# Amount Amount of Item received. (Use 0 to remove the Item on import)
+###########################################################################
+
+Header:
+ Type: CREATE_ARROW_DB
+ Version: 1
diff --git a/doc/yaml/db/create_arrow_db.yml b/doc/yaml/db/create_arrow_db.yml
new file mode 100644
index 0000000000..303e053dc1
--- /dev/null
+++ b/doc/yaml/db/create_arrow_db.yml
@@ -0,0 +1,12 @@
+###########################################################################
+# Arrow Crafting Database
+###########################################################################
+#
+# Arrow Crafting Settings
+#
+###########################################################################
+# - Source AegisName of the item that is consumed.
+# Make: List of item(s) received by the player.
+# - Item AegisName of the item received.
+# Amount Amount of Item received. (Use 0 to remove the Item on import)
+###########################################################################
diff --git a/src/map/clif.cpp b/src/map/clif.cpp
index 200cf673f0..dafefe6899 100644
--- a/src/map/clif.cpp
+++ b/src/map/clif.cpp
@@ -3851,21 +3851,15 @@ void clif_arrow_fail(struct map_session_data *sd,int type) {
void clif_arrow_create_list( struct map_session_data *sd ){
nullpo_retv( sd );
- int fd = sd->fd;
-
- if( !session_isActive( fd ) ){
- return;
- }
-
- WFIFOHEAD( fd, sizeof( struct PACKET_ZC_MAKINGARROW_LIST ) + MAX_SKILL_ARROW_DB * sizeof( struct PACKET_ZC_MAKINGARROW_LIST_sub ) );
- struct PACKET_ZC_MAKINGARROW_LIST *p = (struct PACKET_ZC_MAKINGARROW_LIST *)WFIFOP( fd, 0 );
+ struct PACKET_ZC_MAKINGARROW_LIST *p = (struct PACKET_ZC_MAKINGARROW_LIST *)packet_buffer;
p->packetType = HEADER_ZC_MAKINGARROW_LIST;
int count = 0;
- for( int i = 0; i < MAX_SKILL_ARROW_DB; i++ ){
- t_itemid nameid = skill_arrow_db[i].nameid;
- if( !itemdb_exists( nameid ) ){
+ for (const auto &it : skill_arrow_db) {
+ t_itemid nameid = it.second->nameid;
+
+ if( !item_db.exists( nameid ) ){
continue;
}
@@ -3888,7 +3882,8 @@ void clif_arrow_create_list( struct map_session_data *sd ){
}
p->packetLength = sizeof( struct PACKET_ZC_MAKINGARROW_LIST ) + count * sizeof( struct PACKET_ZC_MAKINGARROW_LIST_sub );
- WFIFOSET( fd, p->packetLength );
+
+ clif_send( p, p->packetLength, &sd->bl, SELF );
if( count > 0 ){
sd->menuskill_id = AC_MAKINGARROW;
@@ -19033,14 +19028,7 @@ void clif_parse_debug(int fd,struct map_session_data *sd)
void clif_elementalconverter_list( struct map_session_data *sd ){
nullpo_retv( sd );
- int fd = sd->fd;
-
- if( !session_isActive( fd ) ){
- return;
- }
-
- WFIFOHEAD( fd, sizeof( struct PACKET_ZC_MAKINGARROW_LIST ) + MAX_SKILL_ARROW_DB * sizeof( struct PACKET_ZC_MAKINGARROW_LIST_sub ) );
- struct PACKET_ZC_MAKINGARROW_LIST *p = (struct PACKET_ZC_MAKINGARROW_LIST *)WFIFOP( fd, 0 );
+ struct PACKET_ZC_MAKINGARROW_LIST *p = (struct PACKET_ZC_MAKINGARROW_LIST *)packet_buffer;
p->packetType = HEADER_ZC_MAKINGARROW_LIST;
int count = 0;
@@ -19052,7 +19040,8 @@ void clif_elementalconverter_list( struct map_session_data *sd ){
}
p->packetLength = sizeof( struct PACKET_ZC_MAKINGARROW_LIST ) + count * sizeof( struct PACKET_ZC_MAKINGARROW_LIST_sub );
- WFIFOSET( fd, p->packetLength );
+
+ clif_send( p, p->packetLength, &sd->bl, SELF );
if( count > 0 ){
sd->menuskill_id = SA_CREATECON;
diff --git a/src/map/map-server.vcxproj b/src/map/map-server.vcxproj
index 31dc7e1f52..de4e1a2e46 100644
--- a/src/map/map-server.vcxproj
+++ b/src/map/map-server.vcxproj
@@ -302,7 +302,7 @@
-
+
diff --git a/src/map/skill.cpp b/src/map/skill.cpp
index e4a9c331f1..daaf81d673 100755
--- a/src/map/skill.cpp
+++ b/src/map/skill.cpp
@@ -84,12 +84,9 @@ struct skill_usave {
struct s_skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB];
static unsigned short skill_produce_count;
-struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB];
-static unsigned short skill_arrow_count;
-
AbraDatabase abra_db;
-
ReadingSpellbookDatabase reading_spellbook_db;
+SkillArrowDatabase skill_arrow_db;
#define MAX_SKILL_CHANGEMATERIAL_DB 75
#define MAX_SKILL_CHANGEMATERIAL_SET 3
@@ -20341,34 +20338,36 @@ bool skill_produce_mix(struct map_session_data *sd, uint16 skill_id, t_itemid na
*/
bool skill_arrow_create(struct map_session_data *sd, t_itemid nameid)
{
- short i, j, idx = -1;
- struct item tmp_item;
-
nullpo_ret(sd);
- if (!nameid || !itemdb_exists(nameid) || !skill_arrow_count)
+ if (!nameid || !item_db.exists(nameid) || skill_arrow_db.empty())
return false;
- for (i = 0; i < MAX_SKILL_ARROW_DB;i++) {
- if (nameid == skill_arrow_db[i].nameid) {
- idx = i;
+ std::shared_ptr arrow = nullptr;
+
+ for (const auto &it : skill_arrow_db) {
+ if (nameid == it.second->nameid) {
+ arrow = it.second;
break;
}
}
+ short j;
- if (idx < 0 || (j = pc_search_inventory(sd,nameid)) < 0)
+ if (arrow == nullptr || (j = pc_search_inventory(sd,nameid)) < 0 || arrow->created.empty())
return false;
pc_delitem(sd,j,1,0,0,LOG_TYPE_PRODUCE);
- for (i = 0; i < MAX_ARROW_RESULT; i++) {
+
+ for (const auto &it : arrow->created) {
char flag = 0;
- if (skill_arrow_db[idx].cre_id[i] == 0 || !itemdb_exists(skill_arrow_db[idx].cre_id[i]) || skill_arrow_db[idx].cre_amount[i] == 0)
+ if (it.first == 0 || !item_db.exists(it.first) || it.second == 0)
continue;
- memset(&tmp_item,0,sizeof(tmp_item));
+
+ struct item tmp_item = { 0 };
tmp_item.identify = 1;
- tmp_item.nameid = skill_arrow_db[idx].cre_id[i];
- tmp_item.amount = skill_arrow_db[idx].cre_amount[i];
+ tmp_item.nameid = it.first;
+ tmp_item.amount = it.second;
if (battle_config.produce_item_name_input&0x4) {
tmp_item.card[0] = CARD0_CREATE;
tmp_item.card[1] = 0;
@@ -22717,42 +22716,75 @@ static bool skill_parse_row_producedb(char* split[], int columns, int current)
return true;
}
-/** Reads create arrow db
- * Sturcture: SourceID,MakeID1,MakeAmount1,...,MakeID5,MakeAmount5
+const std::string SkillArrowDatabase::getDefaultLocation() {
+ return std::string(db_path) + "/create_arrow_db.yml";
+}
+
+/**
+ * Reads and parses an entry from the create_arrow_db.
+ * @param node: YAML node containing the entry.
+ * @return count of successfully parsed rows
*/
-static bool skill_parse_row_createarrowdb(char* split[], int columns, int current)
-{
- unsigned short x, y, i;
- t_itemid material_id = strtoul(split[0], nullptr, 10);
+uint64 SkillArrowDatabase::parseBodyNode(const YAML::Node &node) {
+ std::string source_name;
- if (!(itemdb_exists(material_id))) {
- ShowError("skill_parse_row_createarrowdb: Invalid item %u.\n", material_id);
- return false;
+ if (!this->asString(node, "Source", source_name))
+ return 0;
+
+ struct item_data *item = itemdb_search_aegisname(source_name.c_str());
+
+ if (item == nullptr) {
+ this->invalidWarning(node["Source"], "Item %s does not exist.\n", source_name.c_str());
+ return 0;
}
- //search if we override something, (if not i=last idx)
- ARR_FIND(0, skill_arrow_count, i, skill_arrow_db[i].nameid == material_id);
- if (i >= ARRAYLENGTH(skill_arrow_db)) {
- ShowError("skill_parse_row_createarrowdb: Maximum db entries reached.\n");
- return false;
+ t_itemid nameid = item->nameid;
+
+ std::shared_ptr arrow = this->find(nameid);
+ bool exists = arrow != nullptr;
+
+ if (!exists) {
+ arrow = std::make_shared();
+ arrow->nameid = nameid;
}
- // Import just for clearing/disabling from original data
- if (strtoul(split[1], nullptr, 10) == 0) {
- memset(&skill_arrow_db[i], 0, sizeof(skill_arrow_db[i]));
- //ShowInfo("skill_parse_row_createarrowdb: Arrow creation with Material ID %u removed from list.\n", material_id);
- return true;
+ const YAML::Node &MakeNode = node["Make"];
+
+ for (const auto &it : MakeNode) {
+ std::string item_name;
+
+ if (!this->asString(it, "Item", item_name))
+ return 0;
+
+ struct item_data *item = itemdb_search_aegisname(item_name.c_str());
+
+ if (item == nullptr) {
+ this->invalidWarning(it["Item"], "Item %s does not exist.\n", item_name.c_str());
+ return 0;
+ }
+
+ uint16 amount;
+
+ if (!this->asUInt16(it, "Amount", amount))
+ return 0;
+
+ if (amount == 0) {
+ if (arrow->created.erase(item->nameid) == 0)
+ this->invalidWarning(it["Amount"], "Failed to remove %s, the entry doesn't exist in Source %s.\n", item_name.c_str(), source_name.c_str());
+ continue;
+ }
+ if (amount > MAX_AMOUNT) {
+ this->invalidWarning(it["Amount"], "Amount %hu exceeds %hu, skipping.\n", amount, MAX_AMOUNT);
+ continue;
+ }
+
+ arrow->created[item->nameid] = amount;
}
- skill_arrow_db[i].nameid = material_id;
- for (x = 1, y = 0; x+1 < columns && split[x] && split[x+1] && y < MAX_ARROW_RESULT; x += 2, y++) {
- skill_arrow_db[i].cre_id[y] = strtoul(split[x], nullptr, 10);
- skill_arrow_db[i].cre_amount[y] = atoi(split[x+1]);
- }
- if (i == skill_arrow_count)
- skill_arrow_count++;
+ if (!exists)
+ this->put(nameid, arrow);
- return true;
+ return 1;
}
const std::string AbraDatabase::getDefaultLocation() {
@@ -22974,9 +23006,8 @@ static void skill_readdb(void)
};
memset(skill_produce_db,0,sizeof(skill_produce_db));
- memset(skill_arrow_db,0,sizeof(skill_arrow_db));
memset(skill_changematerial_db,0,sizeof(skill_changematerial_db));
- skill_produce_count = skill_arrow_count = skill_changematerial_count = 0;
+ skill_produce_count = skill_changematerial_count = 0;
skill_db.load();
@@ -22996,7 +23027,6 @@ static void skill_readdb(void)
sv_readdb(dbsubpath2, "skill_nocast_db.txt" , ',', 2, 2, -1, skill_parse_row_nocastdb, 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, "skill_changematerial_db.txt" , ',', 5, 5+2*MAX_SKILL_CHANGEMATERIAL_SET, MAX_SKILL_CHANGEMATERIAL_DB, skill_parse_row_changematerialdb, i > 0);
sv_readdb(dbsubpath1, "skill_damage_db.txt" , ',', 4, 3+SKILLDMG_MAX, -1, skill_parse_row_skilldamage, i > 0);
@@ -23007,6 +23037,7 @@ static void skill_readdb(void)
abra_db.load();
magic_mushroom_db.load();
reading_spellbook_db.load();
+ skill_arrow_db.load();
skill_init_unit_layout();
skill_init_nounit_layout();
@@ -23017,6 +23048,8 @@ void skill_reload (void) {
abra_db.clear();
magic_mushroom_db.clear();
reading_spellbook_db.clear();
+ skill_arrow_db.clear();
+
skill_readdb();
initChangeTables(); // Re-init Status Change tables
@@ -23059,6 +23092,12 @@ void do_init_skill(void)
void do_final_skill(void)
{
+ skill_db.clear();
+ abra_db.clear();
+ magic_mushroom_db.clear();
+ reading_spellbook_db.clear();
+ skill_arrow_db.clear();
+
db_destroy(skillunit_group_db);
db_destroy(skillunit_db);
db_destroy(skillusave_db);
diff --git a/src/map/skill.hpp b/src/map/skill.hpp
index ec478f7e62..a9de4dae1e 100644
--- a/src/map/skill.hpp
+++ b/src/map/skill.hpp
@@ -29,8 +29,6 @@ struct status_change_entry;
#define MAX_SKILL_PRODUCE_DB 282 /// Max Produce DB
#define MAX_PRODUCE_RESOURCE 12 /// Max Produce requirements
-#define MAX_SKILL_ARROW_DB 150 /// Max Arrow Creation DB
-#define MAX_ARROW_RESULT 5 /// Max Arrow results/created
#define MAX_SKILL_LEVEL 13 /// Max Skill Level (for skill_db storage)
#define MAX_MOBSKILL_LEVEL 100 /// Max monster skill level (on skill usage)
#define MAX_SKILL_CRIMSON_MARKER 3 /// Max Crimson Marker targets (RL_C_MARKER)
@@ -433,10 +431,20 @@ extern struct s_skill_produce_db skill_produce_db[MAX_SKILL_PRODUCE_DB];
/// Creating database arrow
struct s_skill_arrow_db {
t_itemid nameid; /// Material ID
- t_itemid cre_id[MAX_ARROW_RESULT]; /// Arrow created
- uint16 cre_amount[MAX_ARROW_RESULT]; /// Amount of each arrow created
+ std::unordered_map created; /// Arrow created
};
-extern struct s_skill_arrow_db skill_arrow_db[MAX_SKILL_ARROW_DB];
+
+class SkillArrowDatabase : public TypesafeYamlDatabase {
+public:
+ SkillArrowDatabase() : TypesafeYamlDatabase("CREATE_ARROW_DB", 1) {
+
+ }
+
+ const std::string getDefaultLocation();
+ uint64 parseBodyNode(const YAML::Node& node);
+};
+
+extern SkillArrowDatabase skill_arrow_db;
/// Abracadabra database
struct s_skill_abra_db {
diff --git a/src/tool/csv2yaml.cpp b/src/tool/csv2yaml.cpp
index 23490c6fc4..005448e278 100644
--- a/src/tool/csv2yaml.cpp
+++ b/src/tool/csv2yaml.cpp
@@ -337,6 +337,12 @@ int do_init( int argc, char** argv ){
return 0;
}
+ if (!process("CREATE_ARROW_DB", 1, root_paths, "create_arrow_db", [](const std::string& path, const std::string& name_ext) -> bool {
+ return sv_readdb(path.c_str(), name_ext.c_str(), ',', 1+2, 1+2*MAX_ARROW_RESULT, MAX_SKILL_ARROW_DB, &skill_parse_row_createarrowdb, false);
+ })) {
+ return 0;
+ }
+
// TODO: add implementations ;-)
return 0;
@@ -3607,3 +3613,56 @@ static bool mob_readdb_group_yaml(void) {
}
return true;
}
+
+// Copied and adjusted from skill.cpp
+static bool skill_parse_row_createarrowdb(char* split[], int columns, int current)
+{
+ t_itemid nameid = static_cast(strtoul(split[0], nullptr, 10));
+
+ if (nameid == 0)
+ return true;
+
+ std::string *material_name = util::umap_find(aegis_itemnames, nameid);
+
+ if (!material_name) {
+ ShowError("skill_parse_row_createarrowdb: Invalid item %u.\n", nameid);
+ return false;
+ }
+
+ // Import just for clearing/disabling from original data
+ if (strtoul(split[1], nullptr, 10) == 0) {
+ body << YAML::BeginMap;
+ body << YAML::Key << "Remove" << YAML::Value << *material_name;
+ body << YAML::EndMap;
+ return true;
+ }
+
+ std::map item_created;
+
+ for (uint16 x = 1; x+1 < columns && split[x] && split[x+1]; x += 2) {
+ nameid = static_cast(strtoul(split[x], nullptr, 10));
+ std::string* item_name = util::umap_find(aegis_itemnames, nameid);
+
+ if (!item_name) {
+ ShowError("skill_parse_row_createarrowdb: Invalid item %u.\n", nameid);
+ return false;
+ }
+
+ item_created.insert({ *item_name, strtoul(split[x+1], nullptr, 10) });
+ }
+
+ body << YAML::BeginMap;
+ body << YAML::Key << "Source" << YAML::Value << *material_name;
+ body << YAML::Key << "Make";
+ body << YAML::BeginSeq;
+ for (const auto &it : item_created) {
+ body << YAML::BeginMap;
+ body << YAML::Key << "Item" << YAML::Value << it.first;
+ body << YAML::Key << "Amount" << YAML::Value << it.second;
+ body << YAML::EndMap;
+ }
+ body << YAML::EndSeq;
+ body << YAML::EndMap;
+
+ return true;
+}
diff --git a/src/tool/csv2yaml.hpp b/src/tool/csv2yaml.hpp
index 3f8a654c29..cc0bd92a83 100644
--- a/src/tool/csv2yaml.hpp
+++ b/src/tool/csv2yaml.hpp
@@ -13,6 +13,8 @@
#define MAX_SKILL_EQUIP_REQUIRE 10
#define MAX_QUEST_DROPS 3
#define MAX_MAP_PER_INSTANCE 255
+#define MAX_ARROW_RESULT 5 /// Max Arrow results/created
+#define MAX_SKILL_ARROW_DB 150 /// Max Arrow Creation DB
// Database to memory maps
struct s_skill_unit_csv : s_skill_db {
@@ -420,5 +422,6 @@ static bool mob_parse_row_chatdb(char* fields[], int columns, int current);
static bool read_homunculus_expdb(const char* file);
static bool mob_readdb_group(char* str[], int columns, int current);
static bool mob_readdb_group_yaml(void);
+static bool skill_parse_row_createarrowdb(char* fields[], int columns, int current);
#endif /* CSV2YAML_HPP */