瀏覽代碼

Refine overhaul (#2295)

* Converted refine_db.txt to refine_db.yml
* Refine success rates can now be set in refine_db.yml. rAthena's default NPCs will respect this database by default.
* Added shadow equipment refiner
Thanks to @Akkarinage @aleos89 @Atemo and @Mikegyver for their inputs.
Jittapan Pluemsumran 7 年之前
父節點
當前提交
e24d30a711

+ 5 - 0
conf/battle/items.conf

@@ -110,3 +110,8 @@ default_bind_on_equip: 4
 // no = Bound items are unable to be sold at Itemshops
 // no = Bound items are unable to be sold at Itemshops
 // yes = Bound items are able to be sold at Itemshops
 // yes = Bound items are able to be sold at Itemshops
 allow_bound_sell: no
 allow_bound_sell: no
+
+// Turn on event refine chance (see db/{pre-}re/refine_db.yml)
+// no = normal refine chances in effect (official/default value)
+// yes = event refine chances in effect
+event_refine_chance: no

+ 0 - 32
db/import-tmpl/refine_db.txt

@@ -1,32 +0,0 @@
-// Refine Database [Renewal]
-//
-// Structure of Database:
-// Type,Stats per level,Random bonus start level,Random bonus value,Chance+1:Bonus+1,Chance+2:Bonus+2,Chance+3:Bonus+3,...
-//
-// For armors, values of 100 add 1 armor defense.
-// For weapons, values of 100 add 1 ATK&MATK.
-//
-// Type:
-//	0 - Armors
-//	1 - Level 1 weapons
-//	2 - Level 2 weapons
-//	3 - Level 3 weapons
-//	4 - Level 4 weapons
-//
-// Stats per level:
-// This value is applied for every upgrade level.
-//
-// Random bonus start level:
-// This value specifies the start point for those levels that give a random bonus value (usually the first unsafe upgrade).
-//
-// Random bonus value:
-// A random number between 0 and (Random bonus start level - Upgrade level + 1) * this value is applied for all upgrades past
-// Random bonus start level. This is only applied for weapons, and not displayed client-side.
-//
-// Chance:
-// 100 = 100%
-//
-// Notes:
-// Changing the number of upgrade levels requires modifying MAX_REFINE in src/map/status.h.
-// For Renewal Armors, there may or may not be another bonus, according to iRO wiki: Every upgrade gives floor[( 3 + current upgrade ) / 4] equipment DEF)
-

+ 20 - 0
db/import-tmpl/refine_db.yml

@@ -0,0 +1,20 @@
+# This file is a part of rAthena++.
+#   Copyright(C) 2017 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/>.
+#
+###########################################################################
+# Custom Refine Database
+###########################################################################

+ 0 - 41
db/pre-re/refine_db.txt

@@ -1,41 +0,0 @@
-// Refine Database [Pre-Renewal]
-//
-// Structure of Database:
-// Type,Stats per level,Random bonus start level,Random bonus value,Chance+1:Bonus+1,Chance+2:Bonus+2,Chance+3:Bonus+3,...
-//
-// For armors, values of 100 add 1 armor defense.
-// For weapons, values of 100 add 1 ATK.
-//
-// Type:
-//	0 - Armors
-//	1 - Level 1 weapons
-//	2 - Level 2 weapons
-//	3 - Level 3 weapons
-//	4 - Level 4 weapons
-//
-// Stats per level:
-// This value is applied for every upgrade level.
-//
-// Random bonus start level:
-// This value specifies the start point for those levels that give a random bonus value.
-//
-// Random bonus value:
-// A random number between 0 and (Random bonus start level - Upgrade level + 1) * this value is applied for all upgrades past
-// Random bonus start level (usually the first unsafe upgrade). This is only applied for weapons, and not displayed client-side.
-//
-// Chance:
-// 100 = 100%
-//
-// Notes:
-// Changing the number of upgrade levels requires modifying MAX_REFINE in src/map/status.h.
-
-// Armors
-0,70,0,0,100:0,100:0,100:0,100:0,60:0,40:0,40:0,20:0,20:0,10:0
-// Level 1 weapons
-1,200,8,300,100:0,100:0,100:0,100:0,100:0,100:0,100:0,60:0,40:0,20:0
-// Level 2 weapons
-2,300,7,500,100:0,100:0,100:0,100:0,100:0,100:0,60:0,40:0,20:0,20:0
-// Level 3 weapons
-3,500,6,800,100:0,100:0,100:0,100:0,100:0,60:0,50:0,20:0,20:0,20:0
-// Level 4 weapons
-4,700,5,1300,100:0,100:0,100:0,100:0,60:0,40:0,40:0,20:0,20:0,10:0

+ 235 - 0
db/pre-re/refine_db.yml

@@ -0,0 +1,235 @@
+# This file is a part of rAthena++.
+#   Copyright(C) 2017 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/>.
+#
+###########################################################################
+# Pre-Renewal Refine Database
+###########################################################################
+Armor:
+  StatsPerLevel: 66
+  RandomBonusStartLevel: 0
+  RandomBonusValue: 0
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 2000
+      Material: 985
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7619
+  Rates:
+    - Level: 5
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 6
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 7
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 8
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+    - Level: 10
+      NormalChance: 9
+      EnrichedChance: 20
+      EventNormalChance: 9
+      EventEnrichedChance: 35
+WeaponLv1:
+  StatsPerLevel: 200
+  RandomBonusStartLevel: 8
+  RandomBonusValue: 300
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 50
+      Material: 1010
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7620
+  Rates:
+    - Level: 8
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 9
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 85
+    - Level: 10
+      NormalChance: 19
+      EnrichedChance: 30
+      EventNormalChance: 19
+      EventEnrichedChance: 55
+WeaponLv2:
+  StatsPerLevel: 300
+  RandomBonusStartLevel: 7
+  RandomBonusValue: 500
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 200
+      Material: 1011
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7620
+  Rates:
+    - Level: 7
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 8
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 85
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 60
+    - Level: 10
+      NormalChance: 19
+      EnrichedChance: 30
+      EventNormalChance: 19
+      EventEnrichedChance: 45
+WeaponLv3:
+  StatsPerLevel: 500
+  RandomBonusStartLevel: 6
+  RandomBonusValue: 800
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 5000
+      Material: 984
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7620
+  Rates:
+    - Level: 6
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 7
+      NormalChance: 50
+      EnrichedChance: 80
+      EventNormalChance: 50
+      EventEnrichedChance: 90
+    - Level: 8
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 70
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 60
+    - Level: 10
+      NormalChance: 19
+      EnrichedChance: 30
+      EventNormalChance: 19
+      EventEnrichedChance: 45
+WeaponLv4:
+  StatsPerLevel: 700
+  RandomBonusStartLevel: 5
+  RandomBonusValue: 1300
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 20000
+      Material: 984
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7620
+  Rates:
+    - Level: 5
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 6
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 7
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 8
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 60
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+    - Level: 10
+      NormalChance: 9
+      EnrichedChance: 20
+      EventNormalChance: 9
+      EventEnrichedChance: 35
+Shadow:
+  StatsPerLevel: 0
+  RandomBonusStartLevel: 0
+  RandomBonusValue: 0
+  Rates:
+    - Level: 5
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 6
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 7
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 8
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+    - Level: 10
+      NormalChance: 9
+      EnrichedChance: 20
+      EventNormalChance: 9
+      EventEnrichedChance: 35

+ 0 - 41
db/re/refine_db.txt

@@ -1,41 +0,0 @@
-// Refine Database [Renewal]
-//
-// Structure of Database:
-// Type,Stats per level,Random bonus start level,Random bonus value,Chance+1:Bonus+1,Chance+2:Bonus+2,Chance+3:Bonus+3,...
-//
-// For armors, values of 100 add 1 armor defense.
-// For weapons, values of 100 add 1 ATK&MATK.
-//
-// Type:
-//	0 - Armors
-//	1 - Level 1 weapons
-//	2 - Level 2 weapons
-//	3 - Level 3 weapons
-//	4 - Level 4 weapons
-//
-// Stats per level:
-// This value is applied for every upgrade level.
-//
-// Random bonus start level:
-// This value specifies the start point for those levels that give a random bonus value (usually the first unsafe upgrade).
-//
-// Random bonus value:
-// A random number between 0 and (Random bonus start level - Upgrade level + 1) * this value is applied for all upgrades past
-// Random bonus start level. This is only applied for weapons, and not displayed client-side.
-//
-// Chance:
-// 100 = 100%
-//
-// Notes:
-// Changing the number of upgrade levels requires modifying MAX_REFINE in src/map/status.h.
-// For Renewal Armors, there may or may not be another bonus, according to iRO wiki: Every upgrade gives floor[( 3 + current upgrade ) / 4] equipment DEF)
-
-0,0,0,0,100:100,100:100,100:100,100:100,60:200,40:200,40:200,20:200,20:300,9:300,8:300,8:300,8:400,8:400,7:400,7:400,7:500,7:500,5:500,5:500
-// Level 1 weapons
-1,200,8,300,100:0,100:0,100:0,100:0,100:0,100:0,100:0,60:0,40:0,19:0,18:0,18:0,18:0,18:0,18:0,17:300,17:300,17:300,15:300,15:300
-// Level 2 weapons
-2,300,7,500,100:0,100:0,100:0,100:0,100:0,100:0,60:0,40:0,20:0,19:0,18:0,18:0,18:0,18:0,18:0,17:600,17:600,17:600,15:600,15:600
-// Level 3 weapons
-3,500,6,800,100:0,100:0,100:0,100:0,100:0,60:0,50:0,20:0,20:0,19:0,18:0,18:0,18:0,18:0,18:0,17:900,17:900,17:900,15:900,15:900
-// Level 4 weapons
-4,700,5,1400,100:0,100:0,100:0,100:0,60:0,40:0,40:0,20:0,20:0,9:0,8:0,8:0,8:0,8:0,7:0,7:1200,7:1200,7:1200,5:1200,5:1200

+ 584 - 0
db/re/refine_db.yml

@@ -0,0 +1,584 @@
+# This file is a part of rAthena++.
+#   Copyright(C) 2017 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/>.
+#
+###########################################################################
+# Renewal Refine Database
+###########################################################################
+Armor:
+  StatsPerLevel: 0
+  RandomBonusStartLevel: 0
+  RandomBonusValue: 0
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 2000
+      Material: 985
+    - Type: REFINE_COST_OVER10
+      Price: 100000
+      Material: 6223
+    - Type: REFINE_COST_HD
+      Price: 20000
+      Material: 6241
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7619
+    - Type: REFINE_COST_OVER10_HD
+      Price: 100000
+      Material: 6225
+  Rates:
+    - Level: 1
+      Bonus: 100
+    - Level: 2
+      Bonus: 100
+    - Level: 3
+      Bonus: 100
+    - Level: 4
+      Bonus: 100
+    - Level: 5
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+      Bonus: 200
+    - Level: 6
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+      Bonus: 200
+    - Level: 7
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+      Bonus: 200
+    - Level: 8
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+      Bonus: 200
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+      Bonus: 300
+    - Level: 10
+      NormalChance: 9
+      EnrichedChance: 20
+      EventNormalChance: 9
+      EventEnrichedChance: 35
+      Bonus: 300
+    - Level: 11
+      NormalChance: 8
+      EnrichedChance: 8
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+      Bonus: 300
+    - Level: 12
+      NormalChance: 8
+      EnrichedChance: 8
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+      Bonus: 300
+    - Level: 13
+      NormalChance: 8
+      EnrichedChance: 8
+      EventNormalChance: 16
+      EventEnrichedChance: 16
+      Bonus: 400
+    - Level: 14
+      NormalChance: 8
+      EnrichedChance: 8
+      EventNormalChance: 16
+      EventEnrichedChance: 16
+      Bonus: 400
+    - Level: 15
+      NormalChance: 7
+      EnrichedChance: 7
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 400
+    - Level: 16
+      NormalChance: 7
+      EnrichedChance: 7
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 400
+    - Level: 17
+      NormalChance: 7
+      EnrichedChance: 7
+      EventNormalChance: 14
+      EventEnrichedChance: 14
+      Bonus: 500
+    - Level: 18
+      NormalChance: 7
+      EnrichedChance: 7
+      EventNormalChance: 14
+      EventEnrichedChance: 14
+      Bonus: 500
+    - Level: 19
+      NormalChance: 5
+      EnrichedChance: 5
+      EventNormalChance: 10
+      EventEnrichedChance: 10
+      Bonus: 500
+    - Level: 20
+      NormalChance: 5
+      EnrichedChance: 5
+      EventNormalChance: 10
+      EventEnrichedChance: 10
+      Bonus: 500
+WeaponLv1:
+  StatsPerLevel: 200
+  RandomBonusStartLevel: 8
+  RandomBonusValue: 300
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 50
+      Material: 1010
+    - Type: REFINE_COST_OVER10
+      Price: 100000
+      Material: 6224
+    - Type: REFINE_COST_HD
+      Price: 20000
+      Material: 6240
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7620
+    - Type: REFINE_COST_OVER10_HD
+      Price: 100000
+      Material: 6226
+  Rates:
+    - Level: 8
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 9
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 85
+    - Level: 10
+      NormalChance: 19
+      EnrichedChance: 30
+      EventNormalChance: 19
+      EventEnrichedChance: 55
+    - Level: 11
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 40
+      EventEnrichedChance: 40
+    - Level: 12
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 40
+      EventEnrichedChance: 40
+    - Level: 13
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 35
+      EventEnrichedChance: 35
+    - Level: 14
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 35
+      EventEnrichedChance: 35
+    - Level: 15
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 30
+      EventEnrichedChance: 30
+    - Level: 16
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 30
+      EventEnrichedChance: 30
+      Bonus: 300
+    - Level: 17
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+      Bonus: 300
+    - Level: 18
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+      Bonus: 300
+    - Level: 19
+      NormalChance: 15
+      EnrichedChance: 15
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 300
+    - Level: 20
+      NormalChance: 15
+      EnrichedChance: 15
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 300
+WeaponLv2:
+  StatsPerLevel: 300
+  RandomBonusStartLevel: 7
+  RandomBonusValue: 500
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 200
+      Material: 1011
+    - Type: REFINE_COST_OVER10
+      Price: 100000
+      Material: 6224
+    - Type: REFINE_COST_HD
+      Price: 20000
+      Material: 6240
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7620
+    - Type: REFINE_COST_OVER10_HD
+      Price: 100000
+      Material: 6226
+  Rates:
+    - Level: 7
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 8
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 85
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 60
+    - Level: 10
+      NormalChance: 19
+      EnrichedChance: 30
+      EventNormalChance: 19
+      EventEnrichedChance: 45
+    - Level: 11
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 40
+      EventEnrichedChance: 40
+    - Level: 12
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 40
+      EventEnrichedChance: 40
+    - Level: 13
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 35
+      EventEnrichedChance: 35
+    - Level: 14
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 35
+      EventEnrichedChance: 35
+    - Level: 15
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 30
+      EventEnrichedChance: 30
+    - Level: 16
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 30
+      EventEnrichedChance: 30
+      Bonus: 600
+    - Level: 17
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+      Bonus: 600
+    - Level: 18
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+      Bonus: 600
+    - Level: 19
+      NormalChance: 15
+      EnrichedChance: 15
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 600
+    - Level: 20
+      NormalChance: 15
+      EnrichedChance: 15
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 600
+WeaponLv3:
+  StatsPerLevel: 500
+  RandomBonusStartLevel: 6
+  RandomBonusValue: 800
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 5000
+      Material: 984
+    - Type: REFINE_COST_OVER10
+      Price: 100000
+      Material: 6224
+    - Type: REFINE_COST_HD
+      Price: 20000
+      Material: 6240
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7620
+    - Type: REFINE_COST_OVER10_HD
+      Price: 100000
+      Material: 6226
+  Rates:
+    - Level: 6
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 7
+      NormalChance: 50
+      EnrichedChance: 80
+      EventNormalChance: 50
+      EventEnrichedChance: 90
+    - Level: 8
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 70
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 60
+    - Level: 10
+      NormalChance: 19
+      EnrichedChance: 30
+      EventNormalChance: 19
+      EventEnrichedChance: 45
+    - Level: 11
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 40
+      EventEnrichedChance: 40
+    - Level: 12
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 40
+      EventEnrichedChance: 40
+    - Level: 13
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 35
+      EventEnrichedChance: 35
+    - Level: 14
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 35
+      EventEnrichedChance: 35
+    - Level: 15
+      NormalChance: 18
+      EnrichedChance: 18
+      EventNormalChance: 30
+      EventEnrichedChance: 30
+    - Level: 16
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 30
+      EventEnrichedChance: 30
+      Bonus: 900
+    - Level: 17
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+      Bonus: 900
+    - Level: 18
+      NormalChance: 17
+      EnrichedChance: 17
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+      Bonus: 900
+    - Level: 19
+      NormalChance: 15
+      EnrichedChance: 15
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 900
+    - Level: 20
+      NormalChance: 15
+      EnrichedChance: 15
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 900
+WeaponLv4:
+  StatsPerLevel: 700
+  RandomBonusStartLevel: 5
+  RandomBonusValue: 1400
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 20000
+      Material: 984
+    - Type: REFINE_COST_OVER10
+      Price: 100000
+      Material: 6224
+    - Type: REFINE_COST_HD
+      Price: 20000
+      Material: 6240
+    - Type: REFINE_COST_ENRICHED
+      Price: 2000
+      Material: 7620
+    - Type: REFINE_COST_OVER10_HD
+      Price: 100000
+      Material: 6226
+  Rates:
+    - Level: 5
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 6
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 7
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 8
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 60
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+    - Level: 10
+      NormalChance: 9
+      EnrichedChance: 20
+      EventNormalChance: 9
+      EventEnrichedChance: 35
+    - Level: 11
+      NormalChance: 8
+      EnrichedChance: 8
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+    - Level: 12
+      NormalChance: 8
+      EnrichedChance: 8
+      EventNormalChance: 20
+      EventEnrichedChance: 20
+    - Level: 13
+      NormalChance: 8
+      EnrichedChance: 8
+      EventNormalChance: 16
+      EventEnrichedChance: 16
+    - Level: 14
+      NormalChance: 8
+      EnrichedChance: 8
+      EventNormalChance: 16
+      EventEnrichedChance: 16
+    - Level: 15
+      NormalChance: 7
+      EnrichedChance: 7
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+    - Level: 16
+      NormalChance: 7
+      EnrichedChance: 7
+      EventNormalChance: 15
+      EventEnrichedChance: 15
+      Bonus: 1200
+    - Level: 17
+      NormalChance: 7
+      EnrichedChance: 7
+      EventNormalChance: 14
+      EventEnrichedChance: 14
+      Bonus: 1200
+    - Level: 18
+      NormalChance: 7
+      EnrichedChance: 7
+      EventNormalChance: 14
+      EventEnrichedChance: 14
+      Bonus: 1200
+    - Level: 19
+      NormalChance: 5
+      EnrichedChance: 5
+      EventNormalChance: 10
+      EventEnrichedChance: 10
+      Bonus: 1200
+    - Level: 20
+      NormalChance: 5
+      EnrichedChance: 5
+      EventNormalChance: 10
+      EventEnrichedChance: 10
+      Bonus: 1200
+Shadow:
+  StatsPerLevel: 0
+  RandomBonusStartLevel: 0
+  RandomBonusValue: 0
+  Costs:
+    - Type: REFINE_COST_NORMAL
+      Price: 20000
+      Material: 985
+    - Type: REFINE_COST_HD
+      Price: 20000
+      Material: 6241
+    - Type: REFINE_COST_ENRICHED
+      Price: 20000
+      Material: 7619
+  Rates:
+    - Level: 5
+      NormalChance: 60
+      EnrichedChance: 90
+      EventNormalChance: 60
+      EventEnrichedChance: 95
+    - Level: 6
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 7
+      NormalChance: 40
+      EnrichedChance: 70
+      EventNormalChance: 40
+      EventEnrichedChance: 80
+    - Level: 8
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+    - Level: 9
+      NormalChance: 20
+      EnrichedChance: 40
+      EventNormalChance: 20
+      EventEnrichedChance: 50
+    - Level: 10
+      NormalChance: 9
+      EnrichedChance: 20
+      EventNormalChance: 9
+      EventEnrichedChance: 35

+ 27 - 2
doc/script_commands.txt

@@ -2719,14 +2719,17 @@ Examples:
 
 
 ---------------------------------------
 ---------------------------------------
 
 
-*getequippercentrefinery(<equipment slot>{,<char_id>})
+*getequippercentrefinery(<equipment slot>{,<enriched>,<char_id>})
 
 
 This function calculates and returns the percent value chance to successfully
 This function calculates and returns the percent value chance to successfully
 refine the item found in the specified equipment slot of the invoking character
 refine the item found in the specified equipment slot of the invoking character
 by +1. There is no actual formula, the success rate for a given weapon level of
 by +1. There is no actual formula, the success rate for a given weapon level of
-a certain refine level is found in the db/refine_db.txt file. For a list of
+a certain refine level is found in the db/(pre-)re/refine_db.yml file. For a list of
 equipment slots see 'getequipid'.
 equipment slots see 'getequipid'.
 
 
+If enriched parameter is set to true, chance to successfully refine the item with
+enriched material is returned instead.
+
 These values can be displayed for the player to see, or used to calculate the
 These values can be displayed for the player to see, or used to calculate the
 random change of a refine succeeding or failing and then going through with it
 random change of a refine succeeding or failing and then going through with it
 (which is what the official NPC refinery scripts use it for)
 (which is what the official NPC refinery scripts use it for)
@@ -2737,6 +2740,28 @@ random change of a refine succeeding or failing and then going through with it
 
 
 ---------------------------------------
 ---------------------------------------
 
 
+*getequiprefinecost(<equipment slot>,<type>,<information>{,<char id>})
+
+This function returns refine cost for equipment in <equipment slot> based on
+passed arguments <type> and <information>.
+
+Valid cost types are:
+
+REFINE_COST_NORMAL     - For normal refining
+REFINE_COST_OVER10     - For refining over +10
+REFINE_COST_HD         - For refining with HD ores
+REFINE_COST_ENRICHED   - For refining with enriched ores
+REFINE_COST_OVER10_HD  - For refining over +10 with HD ores
+
+This function will return required cost for refining based on <information> argument.
+
+Valid information types are:
+
+REFINE_ZENY_COST       - Zeny
+REFINE_MATERIAL_ID     - Material Item ID
+
+---------------------------------------
+
 *getareadropitem("<map name>",<x1>,<y1>,<x2>,<y2>,<item>)
 *getareadropitem("<map name>",<x1>,<y1>,<x2>,<y2>,<item>)
 
 
 This function will count all the items with the specified ID number lying on the
 This function will count all the items with the specified ID number lying on the

+ 5 - 22
npc/merchants/advanced_refiner.txt

@@ -1,22 +1,11 @@
 //===== rAthena Script =======================================
 //===== rAthena Script =======================================
 //= Advanced Refiner
 //= Advanced Refiner
-//===== By: ==================================================
-//= L0ne_W0lf
-//===== Current Version: =====================================
-//= 1.6
-//===== Compatible With: =====================================
-//= rAthena Project
 //===== Description: =========================================
 //===== Description: =========================================
 //= [Official Conversion]
 //= [Official Conversion]
 //= Refiner that uses Enriched ores to increase upgrade success.
 //= Refiner that uses Enriched ores to increase upgrade success.
-//= After a conversation with Doddler, it's been established that
-//= the advanced refiner works similar the the "Bubble Gum" item.
-//= The success percentage is not "increased" however, if it fails
-//= You get a second try. This tries twice at the same time,
-//= effectively giving you a re-roll on your attempt.
 //= - Dialog is only partly official to iRO.
 //= - Dialog is only partly official to iRO.
 //= - Uses the iRO position for this NPC.
 //= - Uses the iRO position for this NPC.
-//===== Additional Comments: =================================
+//===== Changelog: ===========================================
 //= 1.0 First Version. [L0ne_W0lf]
 //= 1.0 First Version. [L0ne_W0lf]
 //= 1.1 Fixed a weird carriage return. o_o [L0ne_W0lf]
 //= 1.1 Fixed a weird carriage return. o_o [L0ne_W0lf]
 //= 1.2 Optimizing refine method [Zephyrus]
 //= 1.2 Optimizing refine method [Zephyrus]
@@ -26,6 +15,7 @@
 //= 1.4b Fixed coordinates. [Euphy]
 //= 1.4b Fixed coordinates. [Euphy]
 //= 1.5 Some official script updates. [Euphy]
 //= 1.5 Some official script updates. [Euphy]
 //= 1.6 Added VIP features. [Euphy]
 //= 1.6 Added VIP features. [Euphy]
+//= 1.7 Removed re-roll behavior. [Secret]
 //============================================================
 //============================================================
 
 
 payon,157,146,6	script	Suhnbi#cash	85,{
 payon,157,146,6	script	Suhnbi#cash	85,{
@@ -65,19 +55,12 @@ payon,157,146,6	script	Suhnbi#cash	85,{
 		close;
 		close;
 	}
 	}
 
 
-	// Make sure you have the neccessary items and Zeny to refine your items
-	// Determines chance of failure and verifies that you want to continue.
-	switch(getequipweaponlv(.@part)) {
-		case 1: callsub S_RefineValidate,1,7620,50,.@part; break;
-		case 2: callsub S_RefineValidate,2,7620,200,.@part; break;
-		case 3: callsub S_RefineValidate,3,7620,5000,.@part; break;
-		case 4: callsub S_RefineValidate,4,7620,20000,.@part; break;
-		default: callsub S_RefineValidate,0,7619,2000,.@part; break;
-	}
+	.@price = getequiprefinecost(.@part, REFINE_COST_ENRICHED, REFINE_ZENY_COST);
+	.@material = getequiprefinecost(.@part, REFINE_COST_ENRICHED, REFINE_MATERIAL_ID);
 
 
 	mes "[Suhnbi]";
 	mes "[Suhnbi]";
 	mes "Clang! Clang! Clang!";
 	mes "Clang! Clang! Clang!";
-	if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) {
+	if (getequippercentrefinery(.@part, true) > rand(100)) {
 		successrefitem .@part;
 		successrefitem .@part;
 		next;
 		next;
 		emotion e_no1;
 		emotion e_no1;

+ 81 - 111
npc/merchants/refine.txt

@@ -38,7 +38,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 986,1; // Anvil
 			getitem 986,1; // Anvil
-			set Zeny, Zeny-30000;
+			Zeny = Zeny-30000;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "This is the cheapest one, but efficient enough to forge most items. Thank ye fer shopping at me workshop.  Feel free to come anytime, whenever ye need.";
 			mes "This is the cheapest one, but efficient enough to forge most items. Thank ye fer shopping at me workshop.  Feel free to come anytime, whenever ye need.";
 			close;
 			close;
@@ -49,7 +49,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 987,1; // Oridecon_Anvil
 			getitem 987,1; // Oridecon_Anvil
-			set Zeny, Zeny-120000;
+			Zeny = Zeny-120000;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "Aye, friend ye have an eye for the anvil. This must be the proper anvil for a Blacksmith, eh? Thank ye fer shopping at me workshop.  Feel free to come anytime, whenever ye need.";
 			mes "Aye, friend ye have an eye for the anvil. This must be the proper anvil for a Blacksmith, eh? Thank ye fer shopping at me workshop.  Feel free to come anytime, whenever ye need.";
 			close;
 			close;
@@ -60,7 +60,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 988,1; // Golden_Anvil
 			getitem 988,1; // Golden_Anvil
-			set Zeny, Zeny-300000;
+			Zeny = Zeny-300000;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "This one is the best among all me stuffs in me workshop! With this, ye can rule the Blacksmith world! Thank ye fer shopping at me workshop.  Feel free to come anytime, whenever ye need.";
 			mes "This one is the best among all me stuffs in me workshop! With this, ye can rule the Blacksmith world! Thank ye fer shopping at me workshop.  Feel free to come anytime, whenever ye need.";
 			close;
 			close;
@@ -101,7 +101,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 					break;
 					break;
 				}
 				}
 			}
 			}
-			set .@sell,.@input * 150;
+			.@sell = .@input * 150;
 			if (Zeny < .@sell) {
 			if (Zeny < .@sell) {
 				mes "[Christopher Guillenrow]";
 				mes "[Christopher Guillenrow]";
 				mes "I don't think I can let ye have this with the zeny ye have. I can't lose me money because of ye.";
 				mes "I don't think I can let ye have this with the zeny ye have. I can't lose me money because of ye.";
@@ -113,7 +113,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 612,.@input; // Portable_Furnace
 			getitem 612,.@input; // Portable_Furnace
-			set Zeny, Zeny-.@sell;
+			Zeny = Zeny-.@sell;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			close;
 			close;
@@ -124,7 +124,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 613,1; // Iron_Hammer
 			getitem 613,1; // Iron_Hammer
-			set Zeny, Zeny-1000;
+			Zeny = Zeny-1000;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			close;
 			close;
@@ -135,7 +135,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 614,1; // Golden_Hammer
 			getitem 614,1; // Golden_Hammer
-			set Zeny, Zeny-3000;
+			Zeny = Zeny-3000;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			close;
 			close;
@@ -146,7 +146,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 615,1; // Oridecon_Hammer
 			getitem 615,1; // Oridecon_Hammer
-			set Zeny, Zeny-5000;
+			Zeny = Zeny-5000;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			close;
 			close;
@@ -182,7 +182,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 					break;
 					break;
 				}
 				}
 			}
 			}
-			set .@sell,.@input * 200;
+			.@sell = .@input * 200;
 			if (Zeny < .@sell) {
 			if (Zeny < .@sell) {
 				mes "[Christopher Guillenrow]";
 				mes "[Christopher Guillenrow]";
 				mes "Ye don't have enough money. Ye know I can't sell this at a lower price... You know how the wifey nags about Zeny.";
 				mes "Ye don't have enough money. Ye know I can't sell this at a lower price... You know how the wifey nags about Zeny.";
@@ -194,7 +194,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 1010,.@input; // Phracon
 			getitem 1010,.@input; // Phracon
-			set Zeny, Zeny-.@sell;
+			Zeny = Zeny-.@sell;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need.";
 			close;
 			close;
@@ -220,7 +220,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 					break;
 					break;
 				}
 				}
 			}
 			}
-			set .@sell,.@input * 1000;
+			.@sell = .@input * 1000;
 			if (Zeny < .@sell) {
 			if (Zeny < .@sell) {
 				mes "[Christopher Guillenrow]";
 				mes "[Christopher Guillenrow]";
 				mes "I don't think I can let ye have this with the zeny ye have. I can't lose me money because of ye.";
 				mes "I don't think I can let ye have this with the zeny ye have. I can't lose me money because of ye.";
@@ -232,7 +232,7 @@ geffen_in,110,172,0	script	Christopher#1	63,{
 				close;
 				close;
 			}
 			}
 			getitem 1011,.@input; // Emveretarcon
 			getitem 1011,.@input; // Emveretarcon
-			set Zeny, Zeny-.@sell;
+			Zeny = Zeny-.@sell;
 			mes "[Christopher Guillenrow]";
 			mes "[Christopher Guillenrow]";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need, whenever ye want.";
 			mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need, whenever ye want.";
 			close;
 			close;
@@ -314,7 +314,7 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 				close;
 				close;
 			}
 			}
 			getitem 986,1; //Anvil
 			getitem 986,1; //Anvil
-			set Zeny, Zeny-30000;
+			Zeny = Zeny-30000;
 			mes "[Paul Spanner]";
 			mes "[Paul Spanner]";
 			mes "It is the cheapest anvil which has the most basic ability.";
 			mes "It is the cheapest anvil which has the most basic ability.";
 			mes "Thank you for using my shop. If you need anything, just let me know.";
 			mes "Thank you for using my shop. If you need anything, just let me know.";
@@ -326,7 +326,7 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 				close;
 				close;
 			}
 			}
 			getitem 987,1; //Oridecon_Anvil
 			getitem 987,1; //Oridecon_Anvil
-			set Zeny, Zeny-120000;
+			Zeny = Zeny-120000;
 			mes "[Paul Spanner]";
 			mes "[Paul Spanner]";
 			mes "Ah, you have an eye for anvil. A Blacksmith needs an anvil at least as good as this.";
 			mes "Ah, you have an eye for anvil. A Blacksmith needs an anvil at least as good as this.";
 			mes "Thank you for using my shop. If you need anything, just let me know.";
 			mes "Thank you for using my shop. If you need anything, just let me know.";
@@ -338,7 +338,7 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 				close;
 				close;
 			}
 			}
 			getitem 988,1; //Golden_Anvil
 			getitem 988,1; //Golden_Anvil
-			set Zeny, Zeny-300000;
+			Zeny = Zeny-300000;
 			mes "[Paul Spanner]";
 			mes "[Paul Spanner]";
 			mes "I can tell your ambition to become a good Blacksmith just by looking at you to choose this Golden Anvil!";
 			mes "I can tell your ambition to become a good Blacksmith just by looking at you to choose this Golden Anvil!";
 			mes "This anvil will surely aid you in creating the best weapons.";
 			mes "This anvil will surely aid you in creating the best weapons.";
@@ -360,27 +360,27 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 		next;
 		next;
 		switch(select("Mini Furnace - 150z.:Iron Hammer - 1,000z.:Golden Hammer - 3,000z.:Oridecon Hammer - 5,000z.:Cancel.")) {
 		switch(select("Mini Furnace - 150z.:Iron Hammer - 1,000z.:Golden Hammer - 3,000z.:Oridecon Hammer - 5,000z.:Cancel.")) {
 		case 1:
 		case 1:
-			set .@item,612;
-			set .@item_cost,150;
-			set .@item_weight,200;
+			.@item = 612;
+			.@item_cost = 150;
+			.@item_weight = 200;
 			mes "[Paul Spanner]";
 			mes "[Paul Spanner]";
 			mes "You definately need this furnce to process ores!";
 			mes "You definately need this furnce to process ores!";
 			next;
 			next;
 			break;
 			break;
 		case 2:
 		case 2:
-			set .@item,613;
-			set .@item_cost,1000;
-			set .@item_weight,200;
+			.@item = 613;
+			.@item_cost = 1000;
+			.@item_weight = 200;
 			break;
 			break;
 		case 3:
 		case 3:
-			set .@item,614;
-			set .@item_cost,3000;
-			set .@item_weight,300;
+			.@item = 614;
+			.@item_cost = 3000;
+			.@item_weight = 300;
 			break;
 			break;
 		case 4:
 		case 4:
-			set .@item,615;
-			set .@item_cost,5000;
-			set .@item_weight,400;
+			.@item = 615;
+			.@item_cost = 5000;
+			.@item_weight = 400;
 			break;
 			break;
 		case 5:
 		case 5:
 			mes "[Paul Spanner]";
 			mes "[Paul Spanner]";
@@ -406,7 +406,7 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 				break;
 				break;
 			}
 			}
 		}
 		}
-		set .@sell,.@input * .@item_cost;
+		.@sell = .@input * .@item_cost;
 		if (Zeny < .@sell) {
 		if (Zeny < .@sell) {
 			mes "[Paul Spanner]";
 			mes "[Paul Spanner]";
 			mes "You don't have enough money. Sorry, I cannot sell them at a loss.";
 			mes "You don't have enough money. Sorry, I cannot sell them at a loss.";
@@ -417,7 +417,7 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 			mes "Hey, you look pale. Why don't you go lighten your weight first.";
 			mes "Hey, you look pale. Why don't you go lighten your weight first.";
 			close;
 			close;
 		}
 		}
-		set Zeny, Zeny-.@sell;
+		Zeny = Zeny-.@sell;
 		getitem .@item,.@input;
 		getitem .@item,.@input;
 		mes "[Paul Spanner]";
 		mes "[Paul Spanner]";
 		mes "Thank you for using my shop. If you need anything, just let me know.";
 		mes "Thank you for using my shop. If you need anything, just let me know.";
@@ -429,12 +429,12 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 		next;
 		next;
 		switch(select("Phracon - 200z.:Emveretarcon - 1,000z.:Quit.")) {
 		switch(select("Phracon - 200z.:Emveretarcon - 1,000z.:Quit.")) {
 		case 1:
 		case 1:
-			set .@item,1010;
-			set .@item_price,200;
+			.@item = 1010;
+			.@item_price = 200;
 			break;
 			break;
 		case 2:
 		case 2:
-			set .@item,1011;
-			set .@item_price,1000;
+			.@item = 1011;
+			.@item_price = 1000;
 			break;
 			break;
 		case 3:
 		case 3:
 			mes "[Paul Spanner]";
 			mes "[Paul Spanner]";
@@ -460,7 +460,7 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 				break;
 				break;
 			}
 			}
 		}
 		}
-		set .@sell,.@input * .@item_price;
+		.@sell = .@input * .@item_price;
 		if (Zeny < .@sell) {
 		if (Zeny < .@sell) {
 			mes "[Paul Spanner]";
 			mes "[Paul Spanner]";
 			mes "You don't have enough money. Sorry, I cannot sell them at a loss.";
 			mes "You don't have enough money. Sorry, I cannot sell them at a loss.";
@@ -472,7 +472,7 @@ ein_in01,38,29,0	script	Paul Spanner	63,{
 			close;
 			close;
 		}
 		}
 		getitem .@item,.@input;
 		getitem .@item,.@input;
-		set Zeny, Zeny-.@sell;
+		Zeny = Zeny-.@sell;
 		mes "[Paul Spanner]";
 		mes "[Paul Spanner]";
 		mes "Thank you for using my shop. If you need anything, just let me know.";
 		mes "Thank you for using my shop. If you need anything, just let me know.";
 		close;
 		close;
@@ -562,7 +562,7 @@ lhz_in02,282,20,7	script	Fulerr	869,{
 function	script	refinemain	{
 function	script	refinemain	{
 	disable_items;
 	disable_items;
 	.@npc_name$ = getarg(0);
 	.@npc_name$ = getarg(0);
-	set .@features,getarg(1);
+	.@features = getarg(1);
 	mes "["+ .@npc_name$ +"]";
 	mes "["+ .@npc_name$ +"]";
 	mes "I'm the Armsmith.";
 	mes "I'm the Armsmith.";
 	mes "I can refine all kinds of weapons, armor and equipment, so let me";
 	mes "I can refine all kinds of weapons, armor and equipment, so let me";
@@ -570,19 +570,19 @@ function	script	refinemain	{
 	next;
 	next;
 
 
 	setarray .@indices[1], EQI_HEAD_TOP, EQI_ARMOR, EQI_HAND_L, EQI_HAND_R, EQI_GARMENT, EQI_SHOES, EQI_ACC_L, EQI_ACC_R, EQI_HEAD_MID, EQI_HEAD_LOW;
 	setarray .@indices[1], EQI_HEAD_TOP, EQI_ARMOR, EQI_HAND_L, EQI_HAND_R, EQI_GARMENT, EQI_SHOES, EQI_ACC_L, EQI_ACC_R, EQI_HEAD_MID, EQI_HEAD_LOW;
-	for(set .@i,1; .@i<getarraysize(.@indices); set .@i,.@i+1) {
+	for(.@i = 1; .@i<getarraysize(.@indices); ++.@i) {
 		if(getequipisequiped(.@indices[.@i])) {
 		if(getequipisequiped(.@indices[.@i])) {
-			set .@menu$, .@menu$ + F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]";
-			set .@equipped,1;
+			.@menu$ = .@menu$ + F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]";
+			.@equipped = 1;
 		}
 		}
-		set .@menu$, .@menu$ + ":";
+		.@menu$ = .@menu$ + ":";
 	}
 	}
 	if (.@equipped == 0) {
 	if (.@equipped == 0) {
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
 		mes "I don't think I can refine any items you have...";
 		mes "I don't think I can refine any items you have...";
 		close;
 		close;
 	}
 	}
-	set .@part, .@indices[select(.@menu$)];
+	.@part = .@indices[select(.@menu$)];
 
 
 	if(!getequipisequiped(.@part)) { //custom check
 	if(!getequipisequiped(.@part)) { //custom check
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
@@ -607,50 +607,20 @@ function	script	refinemain	{
 		mes "refined as it gets!";
 		mes "refined as it gets!";
 		close;
 		close;
 	}
 	}
-	set .@refineitemid, getequipid(.@part); // save id of the item
-	set .@refinerycnt, getequiprefinerycnt(.@part); //save refinery count
-	switch(getequipweaponlv(.@part)){
-	case 0: 	//Refine Armor
-		set .@price,2000;
-		set .@material,985; //Elunium
-		set .@safe,4;
-		break;
-	case 1: 	//Refine Level 1 Weapon
-		set .@price,50;
-		set .@material,1010; //Phracon
-		set .@safe,7;
-		break;
-	case 2: 	//Refine Level 2 Weapon
-		set .@price,200;
-		set .@material,1011; //Emveretarcon
-		set .@safe,6;
-		break;
-	case 3: 	//Refine Level 3 Weapon
-		set .@price,5000;
-		set .@material,984; //Oridecon
-		set .@safe,5;
-		break;
-	case 4: 	//Refine Level 4 Weapon
-		set .@price,20000;
-		set .@material,984; //Oridecon
-		set .@safe,4;
-		break;
-	case 5: 	//Refine other stuff?
-		set .@price,2000;
-		set .@material,985; //Elunium
-		set .@safe,4;
-		break;
-	}
+	.@refineitemid = getequipid(.@part); // save id of the item
+	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	.@price = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_ZENY_COST);
+	.@material = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_MATERIAL_ID);
 
 
 	// If the VIP system is enabled, the prices for non-VIP players are considerably higher.
 	// If the VIP system is enabled, the prices for non-VIP players are considerably higher.
 	if (VIP_SCRIPT && !vip_status(VIP_STATUS_ACTIVE)) {
 	if (VIP_SCRIPT && !vip_status(VIP_STATUS_ACTIVE)) {
 		switch(getequipweaponlv(.@part)) {
 		switch(getequipweaponlv(.@part)) {
-			case 0: set .@price, .@price * 10; break;
-			case 1: set .@price, .@price * 40; break;
-			case 2: set .@price, .@price * 50; break;
-			case 3: set .@price, .@price * 2; break;
-			case 4: set .@price, .@price * 2; break;
-			case 5: set .@price, .@price * 10; break;
+			case 0: .@price = .@price * 10; break;
+			case 1: .@price = .@price * 40; break;
+			case 2: .@price = .@price * 50; break;
+			case 3: .@price = .@price * 2; break;
+			case 4: .@price = .@price * 2; break;
+			case 5: .@price = .@price * 10; break;
 		}
 		}
 	}
 	}
 
 
@@ -705,7 +675,7 @@ function	script	refinemain	{
 			mes "here all day if you need me.";
 			mes "here all day if you need me.";
 			close;
 			close;
 		}
 		}
-		set Zeny, Zeny-.@price;
+		Zeny = Zeny-.@price;
 		delitem .@material,1;
 		delitem .@material,1;
 
 
 		// anti-hack
 		// anti-hack
@@ -723,7 +693,7 @@ function	script	refinemain	{
 			failedrefitem .@part;
 			failedrefitem .@part;
 			mes "["+ .@npc_name$ +"]";
 			mes "["+ .@npc_name$ +"]";
 			emotion (!rand(5))?e_cash:e_omg;
 			emotion (!rand(5))?e_cash:e_omg;
-			set .@lose,rand(1,3);
+			.@lose = rand(1,3);
 			if (.@lose == 1) {
 			if (.@lose == 1) {
 				mes "OH! MY GOD!";
 				mes "OH! MY GOD!";
 				mes "Damn it! Not again!";
 				mes "Damn it! Not again!";
@@ -744,7 +714,7 @@ function	script	refinemain	{
 		mes "["+getarg(0)+"]";
 		mes "["+getarg(0)+"]";
 		successrefitem .@part;
 		successrefitem .@part;
 		emotion e_heh;
 		emotion e_heh;
-		set .@win,rand(1,3);
+		.@win = rand(1,3);
 		if (.@win == 1) {
 		if (.@win == 1) {
 			mes "Perfect!";
 			mes "Perfect!";
 			mes "Heh heh!";
 			mes "Heh heh!";
@@ -771,12 +741,12 @@ function	script	refinemain	{
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
 		mes "I can refine this to the safe limit or a desired number of times. It's your choice.";
 		mes "I can refine this to the safe limit or a desired number of times. It's your choice.";
 		next;
 		next;
-		set .@menu2,select("To the safe limit, please.","I'll decide how many times.","I've changed my mind...");
+		.@menu2 = select("To the safe limit, please.","I'll decide how many times.","I've changed my mind...");
 	} else
 	} else
-		set .@menu2,2;
+		.@menu2 = 2;
 	switch(.@menu2){
 	switch(.@menu2){
 	case 1: 
 	case 1: 
-		set .@refinecnt,.@safe - getequiprefinerycnt(.@part);
+		.@refinecnt = .@safe - getequiprefinerycnt(.@part);
 		break;
 		break;
 	case 2:
 	case 2:
 		next;
 		next;
@@ -784,14 +754,14 @@ function	script	refinemain	{
 		mes "How many times would you like me to refine your item?";
 		mes "How many times would you like me to refine your item?";
 		next;
 		next;
 		input .@refinecnt;
 		input .@refinecnt;
-		set .@refinecheck,.@refinecnt + getequiprefinerycnt(.@part);
+		.@refinecheck = .@refinecnt + getequiprefinerycnt(.@part);
 		if (.@refinecnt < 1 || .@refinecheck > 10) {
 		if (.@refinecnt < 1 || .@refinecheck > 10) {
 			mes "["+ .@npc_name$ +"]";
 			mes "["+ .@npc_name$ +"]";
 			mes "I can't refine this item that many times.";
 			mes "I can't refine this item that many times.";
 			close;
 			close;
 		}
 		}
 		if(.@refinecheck > .@safe) {
 		if(.@refinecheck > .@safe) {
-			set .@refinecheck,.@refinecheck - .@safe;
+			.@refinecheck = .@refinecheck - .@safe;
 			mes "["+ .@npc_name$ +"]";
 			mes "["+ .@npc_name$ +"]";
 			mes "This will try to refine the equipment " + .@refinecheck + " times past the safe limit. Your equipment may be destroyed... is that ok?";
 			mes "This will try to refine the equipment " + .@refinecheck + " times past the safe limit. Your equipment may be destroyed... is that ok?";
 			next;
 			next;
@@ -808,7 +778,7 @@ function	script	refinemain	{
 		mes "You said so... So be it.";
 		mes "You said so... So be it.";
 		close;
 		close;
 	}
 	}
-	set .@fullprice,.@price * .@refinecnt;
+	.@fullprice = .@price * .@refinecnt;
 	mes "["+ .@npc_name$ +"]";
 	mes "["+ .@npc_name$ +"]";
 	mes "That will cost you " + .@refinecnt + " " + getitemname(.@material) + " and " + .@fullprice + " Zeny. Is that ok?";
 	mes "That will cost you " + .@refinecnt + " " + getitemname(.@material) + " and " + .@fullprice + " Zeny. Is that ok?";
 	next;
 	next;
@@ -822,7 +792,7 @@ function	script	refinemain	{
 		mes "Is that all you got? Unfortunately I can't work for you at a lower price. Try putting yourself in my shoes.";
 		mes "Is that all you got? Unfortunately I can't work for you at a lower price. Try putting yourself in my shoes.";
 		close;
 		close;
 	}
 	}
-	set Zeny, Zeny - .@fullprice;
+	Zeny = Zeny - .@fullprice;
 	delitem .@material,.@refinecnt;
 	delitem .@material,.@refinecnt;
 	while(.@refinecnt){
 	while(.@refinecnt){
 		if (getequipisequiped(.@part) == 0) {
 		if (getequipisequiped(.@part) == 0) {
@@ -843,17 +813,17 @@ function	script	refinemain	{
 			emotion e_omg;
 			emotion e_omg;
 			mes "["+ .@npc_name$ +"]";
 			mes "["+ .@npc_name$ +"]";
 			mes "WAHHHH!!! I'm so sorry... I warned you this could happen...";
 			mes "WAHHHH!!! I'm so sorry... I warned you this could happen...";
-			set .@refinecnt,.@refinecnt - 1;
+			.@refinecnt = .@refinecnt - 1;
 			if(.@refinecnt == 0) close;
 			if(.@refinecnt == 0) close;
 			mes "Here's the unused Zeny and materials back...";
 			mes "Here's the unused Zeny and materials back...";
 			getitem .@material,.@refinecnt;
 			getitem .@material,.@refinecnt;
-			set .@fullprice,.@refinecnt * .@price;
-			set Zeny, Zeny + .@fullprice;
+			.@fullprice = .@refinecnt * .@price;
+			Zeny = Zeny + .@fullprice;
 			close;
 			close;
 		}
 		}
 		successrefitem .@part;
 		successrefitem .@part;
 		emotion e_no1;
 		emotion e_no1;
-		set .@refinecnt,.@refinecnt - 1;
+		.@refinecnt = .@refinecnt - 1;
 		next;
 		next;
 	}
 	}
 	mes "["+ .@npc_name$ +"]";
 	mes "["+ .@npc_name$ +"]";
@@ -913,12 +883,12 @@ function	script	phramain	{
 	next;
 	next;
 	switch(select("Phracon - 200 Zeny:Emveretarcon - 1000 Zeny:Ask about other Metals")) {
 	switch(select("Phracon - 200 Zeny:Emveretarcon - 1000 Zeny:Ask about other Metals")) {
 	case 1:
 	case 1:
-		set .@material,1010;
-		set .@price,200;
+		.@material = 1010;
+		.@price = 200;
 		break;
 		break;
 	case 2:
 	case 2:
-		set .@material,1011;
-		set .@price,1000;
+		.@material = 1011;
+		.@price = 1000;
 		break;
 		break;
 	case 3:
 	case 3:
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
@@ -951,7 +921,7 @@ function	script	phramain	{
 			break;
 			break;
 		}
 		}
 	}
 	}
-	set .@sell,.@input * .@price;
+	.@sell = .@input * .@price;
 	if (Zeny < .@sell) {
 	if (Zeny < .@sell) {
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
 		mes "Err...";
 		mes "Err...";
@@ -967,7 +937,7 @@ function	script	phramain	{
 		close;
 		close;
 	}
 	}
 	getitem .@material,.@input;
 	getitem .@material,.@input;
-	set Zeny, Zeny-.@sell;
+	Zeny = Zeny-.@sell;
 	mes "["+ .@npc_name$ +"]";
 	mes "["+ .@npc_name$ +"]";
 	mes "Here you are!";
 	mes "Here you are!";
 	mes "Thank you for";
 	mes "Thank you for";
@@ -1151,7 +1121,7 @@ sch_gld,340,80,7	script	Repairman#sch_gld	86,{
 // Equipment Repair Function
 // Equipment Repair Function
 //============================================================
 //============================================================
 function	script	repairmain	{
 function	script	repairmain	{
-	set .@repairprice,5000;
+	.@repairprice = 5000;
 	.@npc_name$ = getarg(0);
 	.@npc_name$ = getarg(0);
 	mes "["+ .@npc_name$ +"]";
 	mes "["+ .@npc_name$ +"]";
 	mes "Hey there!";
 	mes "Hey there!";
@@ -1162,14 +1132,14 @@ function	script	repairmain	{
 	next;
 	next;
 	switch(select("Actually, I do have some items...:None at the moment.")) {
 	switch(select("Actually, I do have some items...:None at the moment.")) {
 	case 1:
 	case 1:
-		set .@checkitem,1;
+		.@checkitem = 1;
 		while (1) {
 		while (1) {
 			if (getbrokenid(.@checkitem) == 0) {
 			if (getbrokenid(.@checkitem) == 0) {
 				break;
 				break;
 			}
 			}
-			set .@checkitem,.@checkitem+1;
+			.@checkitem = .@checkitem+1;
 		}
 		}
-		set .@checkitem,.@checkitem-1;
+		.@checkitem = .@checkitem-1;
 		if (!.@checkitem) {
 		if (!.@checkitem) {
 			mes "["+ .@npc_name$ +"]";
 			mes "["+ .@npc_name$ +"]";
 			mes "Oh wow, this is incredible!";
 			mes "Oh wow, this is incredible!";
@@ -1186,7 +1156,7 @@ function	script	repairmain	{
 		mes "" + .@checkitem + " are damaged.";
 		mes "" + .@checkitem + " are damaged.";
 		mes "Would you like to repair?";
 		mes "Would you like to repair?";
 		next;
 		next;
-		set .@totalcost,.@repairprice*.@checkitem;
+		.@totalcost = .@repairprice*.@checkitem;
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
 		mes "Each repair costs " + .@repairprice + " Zeny. So to repair all your damaged items would cost " + .@totalcost + " Zeny! Would you like to repair the items?";
 		mes "Each repair costs " + .@repairprice + " Zeny. So to repair all your damaged items would cost " + .@totalcost + " Zeny! Would you like to repair the items?";
 		next;
 		next;
@@ -1198,19 +1168,19 @@ function	script	repairmain	{
 				mes "Check your wallet before you receive the repair bill! I can't repair anything because you don't have enough Zeny.";
 				mes "Check your wallet before you receive the repair bill! I can't repair anything because you don't have enough Zeny.";
 				close;
 				close;
 			}
 			}
-			set .@checkitem2,1;
+			.@checkitem2 = 1;
 			while (1) {
 			while (1) {
 				if (getbrokenid(.@checkitem2) == 0) {
 				if (getbrokenid(.@checkitem2) == 0) {
 					break;
 					break;
 				}
 				}
-				set .@checkitem2,.@checkitem2+1;
+				.@checkitem2 = .@checkitem2+1;
 			}
 			}
-			set .@checkitem2,.@checkitem2-1;
+			.@checkitem2 = .@checkitem2-1;
 			if (.@checkitem == .@checkitem2) {
 			if (.@checkitem == .@checkitem2) {
-				set Zeny, Zeny-.@totalcost;
+				Zeny = Zeny-.@totalcost;
 				while (.@checkitem) {
 				while (.@checkitem) {
 					repair(.@checkitem);
 					repair(.@checkitem);
-					set .@checkitem,.@checkitem-1;
+					.@checkitem = .@checkitem-1;
 				}
 				}
 				mes "["+ .@npc_name$ +"]";
 				mes "["+ .@npc_name$ +"]";
 				mes "Okay! All done. Now, try to be a little more careful. Items have lives too you know.";
 				mes "Okay! All done. Now, try to be a little more careful. Items have lives too you know.";

+ 7 - 19
npc/re/merchants/advanced_refiner.txt

@@ -1,21 +1,12 @@
 //===== rAthena Script =======================================
 //===== rAthena Script =======================================
 //= Advanced Refiner
 //= Advanced Refiner
-//===== By: ==================================================
-//= Euphy
-//===== Current Version: =====================================
-//= 1.0
-//===== Compatible With: =====================================
-//= rAthena Project
 //===== Description: =========================================
 //===== Description: =========================================
 //= [Official Conversion]
 //= [Official Conversion]
 //= Refiner that uses Enriched ores to increase upgrade success.
 //= Refiner that uses Enriched ores to increase upgrade success.
-//= After a conversation with Doddler, it's been established that
-//= the advanced refiner works similar the the "Bubble Gum" item.
-//= The success percentage is not "increased" however, if it fails
-//= You get a second try. This tries twice at the same time,
-//= effectively giving you a re-roll on your attempt.
-//===== Additional Comments: =================================
+//===== Changelog: ===========================================
 //= 1.0 Added Malangdo Refiner "Holink". [Euphy]
 //= 1.0 Added Malangdo Refiner "Holink". [Euphy]
+//= 1.1 Removed re-roll behavior. [Secret]
+//= 1.2 Added db-based material ID [Secret]
 //============================================================
 //============================================================
 
 
 // Main NPC :: mal_jerun
 // Main NPC :: mal_jerun
@@ -79,35 +70,32 @@ malangdo,221,174,6	script	Holink#mal_cash	559,{
 		close;
 		close;
 	}
 	}
 	mes "[Holink]";
 	mes "[Holink]";
+	// TODO: Price is different to Suhnbi of Payon. Intended? [Secret]
+	.@material = getequiprefinecost(.@part, REFINE_COST_ENRICHED, REFINE_MATERIAL_ID);
 	switch(getequipweaponlv(.@part)) {
 	switch(getequipweaponlv(.@part)) {
 	default:
 	default:
 	case 0: // Armor
 	case 0: // Armor
 		set .@price,15000;
 		set .@price,15000;
-		set .@material,7619; //Enriched_Elunium
 		set .@type$,"armor";
 		set .@type$,"armor";
 		mes "You have chosen an armor, meow~";
 		mes "You have chosen an armor, meow~";
 		break;
 		break;
 	case 1: // Level 1 Weapon
 	case 1: // Level 1 Weapon
 		set .@price,500;
 		set .@price,500;
-		set .@material,7620; //Enriched_Oridecon
 		set .@type$,"weapon";
 		set .@type$,"weapon";
 		mes "A level 1 weapon...?";
 		mes "A level 1 weapon...?";
 		break;
 		break;
 	case 2: // Level 2 Weapon
 	case 2: // Level 2 Weapon
 		set .@price,2000;
 		set .@price,2000;
-		set .@material,7620; //Enriched_Oridecon
 		set .@type$,"weapon";
 		set .@type$,"weapon";
 		mes "Meow, a level 2 weapon...?";
 		mes "Meow, a level 2 weapon...?";
 		break;
 		break;
 	case 3: // Level 3 Weapon
 	case 3: // Level 3 Weapon
 		set .@price,20000;
 		set .@price,20000;
-		set .@material,7620; //Enriched_Oridecon
 		set .@type$,"weapon";
 		set .@type$,"weapon";
 		mes "Meow Meow~~ A level 3 weapon~~";
 		mes "Meow Meow~~ A level 3 weapon~~";
 		break;
 		break;
 	case 4: // Level 4 Weapon
 	case 4: // Level 4 Weapon
 		set .@price,50000;
 		set .@price,50000;
-		set .@material,7620; //Enriched_Oridecon
 		set .@type$,"weapon";
 		set .@type$,"weapon";
 		mes "Me-Meow!... A level 4 weapon...!";
 		mes "Me-Meow!... A level 4 weapon...!";
 		mes "I've only seen it twice while";
 		mes "I've only seen it twice while";
@@ -123,7 +111,7 @@ malangdo,221,174,6	script	Holink#mal_cash	559,{
 		mes "You don't belive in refine master Holink, meow?~";
 		mes "You don't belive in refine master Holink, meow?~";
 		close;
 		close;
 	}
 	}
-	if (getequippercentrefinery(.@part) < 100) {
+	if (getequippercentrefinery(.@part, true) < 100) {
 		mes "[Holink]";
 		mes "[Holink]";
 		mes "Meow!!";
 		mes "Meow!!";
 		if (.@type$ == "armor")
 		if (.@type$ == "armor")
@@ -160,7 +148,7 @@ malangdo,221,174,6	script	Holink#mal_cash	559,{
 	}
 	}
 	delitem .@material,1;
 	delitem .@material,1;
 	set Zeny, Zeny-.@price;
 	set Zeny, Zeny-.@price;
-	if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) {
+	if (getequippercentrefinery(.@part, true) > rand(100)) {
 		successrefitem .@part;
 		successrefitem .@part;
 		mes "[Holink]";
 		mes "[Holink]";
 		mes "Me~ Me~ Meow! Fun fun refining~";
 		mes "Me~ Me~ Meow! Fun fun refining~";

+ 3 - 8
npc/re/merchants/blessed_refiner.txt

@@ -1,11 +1,5 @@
 //===== rAthena Script ======================================= 
 //===== rAthena Script ======================================= 
 //= Blessed Refiner
 //= Blessed Refiner
-//===== By: ==================================================
-//= Euphy
-//===== Current Version: =====================================
-//= 1.0
-//===== Compatible With: =====================================
-//= rAthena Project
 //===== Description: =========================================
 //===== Description: =========================================
 //= [Official Conversion]
 //= [Official Conversion]
 //= Refiners that use Blessed ores to refine equipment.
 //= Refiners that use Blessed ores to refine equipment.
@@ -13,8 +7,9 @@
 //= rate is identical to that for Enriched ores.
 //= rate is identical to that for Enriched ores.
 //= - "Blacksmith Dister" only refines from +6~12.
 //= - "Blacksmith Dister" only refines from +6~12.
 //= NOTE: This NPC is currently disabled on official servers.
 //= NOTE: This NPC is currently disabled on official servers.
-//===== Additional Comments: =================================
+//===== Changelog: ===========================================
 //= 1.0 First version. [Euphy]
 //= 1.0 First version. [Euphy]
+//= 1.1 Removed re-roll behavior. [Secret]
 //============================================================
 //============================================================
 
 
 // Main NPC :: new_smelting612
 // Main NPC :: new_smelting612
@@ -141,7 +136,7 @@
 	set Zeny, Zeny-.@price;
 	set Zeny, Zeny-.@price;
 	mes "[Blacksmith Dister]";
 	mes "[Blacksmith Dister]";
 	mes "Tac! Tac! Tac!";
 	mes "Tac! Tac! Tac!";
-	if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) {
+	if (getequippercentrefinery(.@part, true) > rand(100)) {
 		specialeffect EF_BLESSING;
 		specialeffect EF_BLESSING;
 		successrefitem .@part;
 		successrefitem .@part;
 		next;
 		next;

+ 12 - 29
npc/re/merchants/hd_refiner.txt

@@ -1,11 +1,5 @@
 //===== rAthena Script ======================================= 
 //===== rAthena Script ======================================= 
 //= HD Refiners
 //= HD Refiners
-//===== By: ==================================================
-//= Euphy
-//===== Current Version: =====================================
-//= 1.0
-//===== Compatible With: =====================================
-//= rAthena Project
 //===== Description: =========================================
 //===== Description: =========================================
 //= [Official Conversion]
 //= [Official Conversion]
 //= Refiners that use HD ores to refine equipment. Upon
 //= Refiners that use HD ores to refine equipment. Upon
@@ -14,8 +8,9 @@
 //= to that for Enriched ores.
 //= to that for Enriched ores.
 //= - "Blacksmith Mighty Hammer" only refines from +7~9.
 //= - "Blacksmith Mighty Hammer" only refines from +7~9.
 //= - "Basta" only refines from +10 and up.
 //= - "Basta" only refines from +10 and up.
-//===== Additional Comments: =================================
+//===== Changelog: ===========================================
 //= 1.0 First version. [Euphy]
 //= 1.0 First version. [Euphy]
+//= 1.1 Removed re-roll behavior. [Secret]
 //============================================================
 //============================================================
 
 
 // Blacksmith Mighty Hammer (+7~9) :: cash_smelting79
 // Blacksmith Mighty Hammer (+7~9) :: cash_smelting79
@@ -78,20 +73,10 @@
 		mes "I only handle items with refine levels from +7 to +9.";
 		mes "I only handle items with refine levels from +7 to +9.";
 		close;
 		close;
 	}
 	}
-	switch(getequipweaponlv(.@part)) {
-	default:
-	case 0:
-		set .@price,20000;
-		set .@material,6241; //HD_Elunium
-		break;
-	case 1:
-	case 2:
-	case 3:
-	case 4:
-		set .@price,20000;
-		set .@material,6240; //HD_Oridecon
-		break;
-	}
+	
+	.@price = getequiprefinecost(.@part, REFINE_COST_HD, REFINE_ZENY_COST);
+	.@material = getequiprefinecost(.@part, REFINE_COST_HD, REFINE_MATERIAL_ID);
+	
 	mes "[Blacksmith Mighty Hammer]";
 	mes "[Blacksmith Mighty Hammer]";
 	mes "In order to refine the gear you selected you need ^ff9999"+getitemname(.@material)+"^000000 and 20,000 zeny as a fee.";
 	mes "In order to refine the gear you selected you need ^ff9999"+getitemname(.@material)+"^000000 and 20,000 zeny as a fee.";
 	mes "Do you have them ready?";
 	mes "Do you have them ready?";
@@ -122,7 +107,7 @@
 	set Zeny, Zeny-.@price;
 	set Zeny, Zeny-.@price;
 	mes "[Blacksmith Mighty Hammer]";
 	mes "[Blacksmith Mighty Hammer]";
 	mes "Tac! Tac! Tac!";
 	mes "Tac! Tac! Tac!";
-	if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) {
+	if (getequippercentrefinery(.@part, true) > rand(100)) {
 		successrefitem .@part;
 		successrefitem .@part;
 		next;
 		next;
 		emotion e_no1;
 		emotion e_no1;
@@ -215,25 +200,23 @@ lhz_in02,280,19,3	duplicate(MightyHammer)	Mighty Hammer#lhz	826
 		mes "This weapon is perfect, no need to refine it anymore~";
 		mes "This weapon is perfect, no need to refine it anymore~";
 		close;
 		close;
 	}
 	}
+	.@price = getequiprefinecost(.@part, REFINE_COST_OVER10_HD, REFINE_ZENY_COST);
+	.@material = getequiprefinecost(.@part, REFINE_COST_OVER10_HD, REFINE_MATERIAL_ID);
 	switch(getequipweaponlv(.@part)) {
 	switch(getequipweaponlv(.@part)) {
 	default:
 	default:
 	case 0:
 	case 0:
-		set .@price,100000;
-		set .@material,6225; //HD_Carnium
 		set .@type$,"armor";
 		set .@type$,"armor";
 		break;
 		break;
 	case 1:
 	case 1:
 	case 2:
 	case 2:
 	case 3:
 	case 3:
 	case 4:
 	case 4:
-		set .@price,100000;
-		set .@material,6226; //HD_Bradium
 		set .@type$,"weapon";
 		set .@type$,"weapon";
 		break;
 		break;
 	}
 	}
 	mes "[Basta]";
 	mes "[Basta]";
 	mes "Hmm... is this the one you want to refine?";
 	mes "Hmm... is this the one you want to refine?";
-	mes "To refine this equipment, I need 1 ^ff9999"+getitemname(.@material)+"^000000 and 100,000 zeny as a fee.";
+	mes "To refine this equipment, I need 1 ^ff9999"+getitemname(.@material)+"^000000 and " + callfunc("F_InsertComma",.@price) + " zeny as a fee.";
 	mes "Do you really want to refine this?";
 	mes "Do you really want to refine this?";
 	next;
 	next;
 	if(select("Yes:No") == 2) {
 	if(select("Yes:No") == 2) {
@@ -241,7 +224,7 @@ lhz_in02,280,19,3	duplicate(MightyHammer)	Mighty Hammer#lhz	826
 		mes "Okay. If that's what you want...";
 		mes "Okay. If that's what you want...";
 		close;
 		close;
 	}
 	}
-	if (getequippercentrefinery(.@part) < 100) {
+	if (getequippercentrefinery(.@part, true) < 100) {
 		mes "[Basta]";
 		mes "[Basta]";
 		mes "This "+.@type$+" has already been refined pretty high.";
 		mes "This "+.@type$+" has already been refined pretty high.";
 		mes "If you try to refine it more, the refine level could decrease.";
 		mes "If you try to refine it more, the refine level could decrease.";
@@ -271,7 +254,7 @@ lhz_in02,280,19,3	duplicate(MightyHammer)	Mighty Hammer#lhz	826
 	delitem .@material,1;
 	delitem .@material,1;
 	set Zeny, Zeny-.@price;
 	set Zeny, Zeny-.@price;
 	mes "Pow! Pow! Pow! Pow!";
 	mes "Pow! Pow! Pow! Pow!";
-	if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) {
+	if (getequippercentrefinery(.@part, true) > rand(100)) {
 		successrefitem .@part;
 		successrefitem .@part;
 		next;
 		next;
 		emotion e_no1;
 		emotion e_no1;

+ 43 - 52
npc/re/merchants/refine.txt

@@ -58,19 +58,19 @@ function	script	refinenew	{
 	next;
 	next;
 
 
 	setarray .@indices[1], EQI_HEAD_TOP, EQI_ARMOR, EQI_HAND_L, EQI_HAND_R, EQI_GARMENT, EQI_SHOES, EQI_ACC_L, EQI_ACC_R, EQI_HEAD_MID, EQI_HEAD_LOW;
 	setarray .@indices[1], EQI_HEAD_TOP, EQI_ARMOR, EQI_HAND_L, EQI_HAND_R, EQI_GARMENT, EQI_SHOES, EQI_ACC_L, EQI_ACC_R, EQI_HEAD_MID, EQI_HEAD_LOW;
-	for(set .@i,1; .@i<=10; set .@i,.@i+1) {
+	for(.@i = 1; .@i<=10; ++.@i) {
 		if (getequipisequiped(.@indices[.@i])) {
 		if (getequipisequiped(.@indices[.@i])) {
-			set .@menu$, .@menu$ + F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]";
-			set .@equipped,1;
+			.@menu$ = .@menu$ + F_getpositionname(.@indices[.@i]) + "-[" + getequipname(.@indices[.@i]) + "]";
+			.@equipped = 1;
 		}
 		}
-		set .@menu$, .@menu$ + ":";
+		.@menu$ = .@menu$ + ":";
 	}
 	}
 	if (.@equipped == 0) {
 	if (.@equipped == 0) {
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
 		mes "I don't think I can refine any items you have...";
 		mes "I don't think I can refine any items you have...";
 		close;
 		close;
 	}
 	}
-	set .@part, .@indices[ select(.@menu$) ];
+	.@part = .@indices[ select(.@menu$) ];
 
 
 	if (!getequipisequiped(.@part)) { //custom check
 	if (!getequipisequiped(.@part)) { //custom check
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
@@ -98,27 +98,24 @@ function	script	refinenew	{
 		mes "refined as it gets!";
 		mes "refined as it gets!";
 		close;
 		close;
 	}
 	}
-	set .@refineitemid, getequipid(.@part); // save id of the item
-	set .@refinerycnt, getequiprefinerycnt(.@part); //save refinery count
+	.@refineitemid = getequipid(.@part); // save id of the item
+	.@refinerycnt = getequiprefinerycnt(.@part); //save refinery count
+	.@price = getequiprefinecost(.@part, REFINE_COST_OVER10, REFINE_ZENY_COST);
+	.@material = getequiprefinecost(.@part, REFINE_COST_OVER10, REFINE_MATERIAL_ID);
+	.@safe = 10;
+
 	if ((getequipweaponlv(.@part) >= 1) && (getequipweaponlv(.@part) <= 4)) {
 	if ((getequipweaponlv(.@part) >= 1) && (getequipweaponlv(.@part) <= 4)) {
-		set .@type$,"weapon";
-		set .@material,6224; //Bradium
-		set .@price,100000;
-		set .@safe,10;
-		mes "["+ .@npc_name$ +"]";
-		mes "Hmm a weapon, is that ok?";
-		mes "If you want to refine this weapon,";
-		mes "I will need 1 ^003366Bradium^000000 and 100,000 zeny.";
+		.@article$ = "a";
+		.@type$ = "weapon";
 	} else {
 	} else {
-		set .@type$,"armor";
-		set .@material,6223; //Carnium
-		set .@price,100000;
-		set .@safe,10;
-		mes "["+ .@npc_name$ +"]";
-		mes "Hmm an armor, is that ok?";
-		mes "If you want to refine this armor,";
-		mes "I will need 1 ^003366Carnium^000000 and 100,000 zeny.";
+		.@article$ = "an";
+		.@type$ = "armor";
 	}
 	}
+	
+	mes "["+ .@npc_name$ +"]";
+	mes "Hmm " + .@article$ + " " + .@type$ + ", is that ok?";
+	mes "If you want to refine this armor,";
+	mes "I will need 1 ^003366" + getitemname(.@material) + "^000000 and " + callfunc("F_InsertComma",.@price) + " zeny.";
 	mes "Are you sure you want to continue?";
 	mes "Are you sure you want to continue?";
 	next;
 	next;
 	if(select("Yes:No") == 2){
 	if(select("Yes:No") == 2){
@@ -154,7 +151,7 @@ function	script	refinenew	{
 			mes "Please come back when you have them.";
 			mes "Please come back when you have them.";
 			close;
 			close;
 		}
 		}
-		set Zeny,Zeny - .@price;
+		Zeny = Zeny - .@price;
 		delitem .@material,1;
 		delitem .@material,1;
 
 
 		// anti-hack
 		// anti-hack
@@ -216,26 +213,26 @@ function	script	refinenew	{
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
 		mes "I can refine this to the safe limit or a desired number of times. It's your choice.";
 		mes "I can refine this to the safe limit or a desired number of times. It's your choice.";
 		next;
 		next;
-		set .@menu2,select("To the safe limit, please.","I'll decide how many times.","I've changed my mind...");
+		.@menu2 = select("To the safe limit, please.","I'll decide how many times.","I've changed my mind...");
 	} else
 	} else
-		set .@menu2,2;
+		.@menu2 = 2;
 	switch(.@menu2){
 	switch(.@menu2){
 	case 1: 
 	case 1: 
-		set .@refinecnt,.@safe - getequiprefinerycnt(.@part);
+		.@refinecnt = .@safe - getequiprefinerycnt(.@part);
 		break;
 		break;
 	case 2:
 	case 2:
 		mes "["+ .@npc_name$ +"]";
 		mes "["+ .@npc_name$ +"]";
 		mes "How many times would you like me to refine your item?";
 		mes "How many times would you like me to refine your item?";
 		next;
 		next;
 		input .@refinecnt;
 		input .@refinecnt;
-		set .@refinecheck,.@refinecnt + getequiprefinerycnt(.@part);
+		.@refinecheck = .@refinecnt + getequiprefinerycnt(.@part);
 		if (.@refinecnt < 1 || .@refinecheck > 20) {
 		if (.@refinecnt < 1 || .@refinecheck > 20) {
 			mes "["+ .@npc_name$ +"]";
 			mes "["+ .@npc_name$ +"]";
 			mes "I can't refine this item that many times.";
 			mes "I can't refine this item that many times.";
 			close;
 			close;
 		}
 		}
 		if (.@refinecheck > .@safe) {
 		if (.@refinecheck > .@safe) {
-			set .@refinecheck,.@refinecheck - .@safe;
+			.@refinecheck = .@refinecheck - .@safe;
 			mes "["+ .@npc_name$ +"]";
 			mes "["+ .@npc_name$ +"]";
 			mes "This will try to refine the equipment " + .@refinecheck + " times past the safe limit. Your equipment may be destroyed... is that ok?";
 			mes "This will try to refine the equipment " + .@refinecheck + " times past the safe limit. Your equipment may be destroyed... is that ok?";
 			next;
 			next;
@@ -251,7 +248,7 @@ function	script	refinenew	{
 		mes "You said so... So be it.";
 		mes "You said so... So be it.";
 		close;
 		close;
 	}
 	}
-	set .@fullprice,.@price * .@refinecnt;
+	.@fullprice = .@price * .@refinecnt;
 	mes "["+ .@npc_name$ +"]";
 	mes "["+ .@npc_name$ +"]";
 	mes "That will cost you " + .@refinecnt + " " + getitemname(.@material) + " and " + .@fullprice + " Zeny. Is that ok?";
 	mes "That will cost you " + .@refinecnt + " " + getitemname(.@material) + " and " + .@fullprice + " Zeny. Is that ok?";
 	next;
 	next;
@@ -266,7 +263,7 @@ function	script	refinenew	{
 		mes "Please come back when you have them.";
 		mes "Please come back when you have them.";
 		close;
 		close;
 	}
 	}
-	set Zeny,Zeny - .@fullprice;
+	Zeny = Zeny - .@fullprice;
 	delitem .@material,.@refinecnt;
 	delitem .@material,.@refinecnt;
 	while(.@refinecnt){
 	while(.@refinecnt){
 		if (getequipisequiped(.@part) == 0) {
 		if (getequipisequiped(.@part) == 0) {
@@ -284,7 +281,7 @@ function	script	refinenew	{
 		if (getequippercentrefinery(.@part) > rand(100)) {
 		if (getequippercentrefinery(.@part) > rand(100)) {
 			mes "Clang! Clang! Clang! Clang!";
 			mes "Clang! Clang! Clang! Clang!";
 			successrefitem .@part;
 			successrefitem .@part;
-			set .@refinecnt,.@refinecnt - 1;
+			.@refinecnt = .@refinecnt - 1;
 			next;
 			next;
 		} else {
 		} else {
 			if (rand(100) < 80) {
 			if (rand(100) < 80) {
@@ -362,7 +359,7 @@ function	script	refinenew	{
 	}
 	}
 	if (countitem(.@i[0]) >= .@i[1] && Zeny >= 50000) {
 	if (countitem(.@i[0]) >= .@i[1] && Zeny >= 50000) {
 		delitem .@i[0],.@i[1];
 		delitem .@i[0],.@i[1];
-		set Zeny, Zeny - 50000;
+		Zeny = Zeny - 50000;
 		getitem .@i[2],1;
 		getitem .@i[2],1;
 		mes "[Austri]";
 		mes "[Austri]";
 		if (.@i[0] == 6090) {
 		if (.@i[0] == 6090) {
@@ -396,9 +393,9 @@ malangdo,224,172,6	script	Clink#mal_normal	544,{
 	mes "Yes!!! You!! You want to refine?";
 	mes "Yes!!! You!! You want to refine?";
 	next;
 	next;
 	setarray .@indices[1], EQI_HEAD_TOP, EQI_ARMOR, EQI_HAND_L, EQI_HAND_R, EQI_GARMENT, EQI_SHOES, EQI_ACC_L, EQI_ACC_R, EQI_HEAD_MID, EQI_HEAD_LOW;
 	setarray .@indices[1], EQI_HEAD_TOP, EQI_ARMOR, EQI_HAND_L, EQI_HAND_R, EQI_GARMENT, EQI_SHOES, EQI_ACC_L, EQI_ACC_R, EQI_HEAD_MID, EQI_HEAD_LOW;
-	for(set .@i,1; .@i<=10; set .@i,.@i+1)
-		set .@menu$, .@menu$ + ( getequipisequiped(.@indices[.@i]) ? getequipname(.@indices[.@i]) : F_getpositionname(.@indices[.@i]) +"-[Empty]" ) +":";
-	set .@part, .@indices[ select(.@menu$) ];
+	for(.@i = 1; .@i<=10; set .@i,.@i+1)
+		.@menu$ = .@menu$ + ( getequipisequiped(.@indices[.@i]) ? getequipname(.@indices[.@i]) : F_getpositionname(.@indices[.@i]) +"-[Empty]" ) +":";
+	.@part = .@indices[ select(.@menu$) ];
 	if (!getequipisequiped(.@part)) {
 	if (!getequipisequiped(.@part)) {
 		mes "[Clink]";
 		mes "[Clink]";
 		switch(.@part) {
 		switch(.@part) {
@@ -441,38 +438,32 @@ malangdo,224,172,6	script	Clink#mal_normal	544,{
 		mes "Perfect refining. Did I do this for you?";
 		mes "Perfect refining. Did I do this for you?";
 		close;
 		close;
 	}
 	}
+	
+	.@price = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_ZENY_COST);
+	.@material = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_MATERIAL_ID);
+	
 	mes "[Clink]";
 	mes "[Clink]";
 	switch(getequipweaponlv(.@part)) {
 	switch(getequipweaponlv(.@part)) {
 	default:
 	default:
 	case 0: // Armor
 	case 0: // Armor
-		set .@price,2000;
-		set .@material,985; //Elunium
-		set .@type$,"armor";
+		.@type$ = "armor";
 		mes "Hmm, an armor refine? Someone like you?";
 		mes "Hmm, an armor refine? Someone like you?";
 		break;
 		break;
 	case 1: // Level 1 Weapon
 	case 1: // Level 1 Weapon
-		set .@price,50;
-		set .@material,1010; //Phracon
-		set .@type$,"weapon";
+		.@type$ = "weapon";
 		mes "A level 1 weapon?";
 		mes "A level 1 weapon?";
 		mes "Urr... Annoying... Okay, let's try...";
 		mes "Urr... Annoying... Okay, let's try...";
 		break;
 		break;
 	case 2: // Level 2 Weapon
 	case 2: // Level 2 Weapon
-		set .@price,200;
-		set .@material,1011; //Emveretarcon
-		set .@type$,"weapon";
+		.@type$ = "weapon";
 		mes "A level 2 weapon?";
 		mes "A level 2 weapon?";
 		break;
 		break;
 	case 3: // Level 3 Weapon
 	case 3: // Level 3 Weapon
-		set .@price,20000;
-		set .@material,984; //Oridecon
-		set .@type$,"weapon";
+		.@type$ = "weapon";
 		mes "Woot!! A level 3 weapon? Impressive~";
 		mes "Woot!! A level 3 weapon? Impressive~";
 		break;
 		break;
 	case 4: // Level 4 Weapon
 	case 4: // Level 4 Weapon
-		set .@price,50000;
-		set .@material,984; //Oridecon
-		set .@type$,"weapon";
+		.@type$ = "weapon";
 		mes "Wow!... A level 4 weapon~!!";
 		mes "Wow!... A level 4 weapon~!!";
 		break;
 		break;
 	}
 	}
@@ -510,7 +501,7 @@ malangdo,224,172,6	script	Clink#mal_normal	544,{
 		close;
 		close;
 	}
 	}
 	delitem .@material,1;
 	delitem .@material,1;
-	set Zeny, Zeny-.@price;
+	Zeny = Zeny-.@price;
 	if (getequippercentrefinery(.@part) <= rand(100)) {
 	if (getequippercentrefinery(.@part) <= rand(100)) {
 		failedrefitem .@part;
 		failedrefitem .@part;
 		mes "[Clink]";
 		mes "[Clink]";

+ 143 - 0
npc/re/merchants/shadow_refiner.txt

@@ -0,0 +1,143 @@
+//===== rAthena Script =======================================
+//= Shadow Blacksmith
+//===== Description: =========================================
+//= [Official Conversion]
+//= Shadow equipments refining NPC.
+//===== Changelog: ===========================================
+//= 1.0 First version [Aleos]
+//= 1.1 Removed re-roll behavior and fetch materials from db 
+//=     [Secret]
+//============================================================
+-	script	::ShadowBlacksmith	-1,{
+	.@zeny_cost = 200000; // Zeny cost is 200,000 according to official script [Secret]
+	disable_items;
+	mes "[Shadow Blacksmith]";
+	mes "Do you want to refine a shadow item? Pick yer poison!";
+	next;
+	setarray .@indices[1], EQI_SHADOW_ARMOR, EQI_SHADOW_WEAPON, EQI_SHADOW_SHIELD, EQI_SHADOW_SHOES, EQI_SHADOW_ACC_R, EQI_SHADOW_ACC_L;
+	for(.@i = 1; .@i <= EQI_SHADOW_ACC_L; .@i++)
+		.@menu$ = .@menu$ + (getequipisequiped(.@indices[.@i]) ? getequipname(.@indices[.@i]) : F_getpositionname(.@indices[.@i]) +"-[Not equipped]") +":";
+	.@menu$ = .@menu$ + "Refine info";
+	.@part = .@indices[select(.@menu$)];
+
+	if (.@part == EQI_SHADOW_ACC_L + 1) { // Refine info
+		mes "[Shadow Blacksmith]";
+		mes "When a shadow item is refined, it gains extra bonuses very much like normal items.";
+		next;
+		mes "[Shadow Blacksmith]";
+		mes "Weapon: ATK, MATK + 1 increase for each +1 refine success.";
+		mes "Etc: HP + 10 increase for each +1 refine success.";
+		next;
+		mes "[Shadow Blacksmith]";
+		mes "All types of Oridecon and Elunium can be used to refine shadow items. Each attempt will also cost 20,000 zeny.";
+		next;
+		mes "[Shadow Blacksmith]";
+		mes "HD ores can be used for gear that is at least refine level +7 and will prevent breaking as long as you stay talking to me.";
+		close;
+	}
+	while(1) {
+		mes "[Shadow Blacksmith]";
+		mes "I require " + callfunc("F_InsertComma", .@zeny_cost) + " zeny as a fee for EACH refine attempt.";
+		mes "Choose your Ore and start refining.";
+		next;
+		.@isNormalEqp = 0;
+		if (.@part != EQI_SHADOW_WEAPON)
+			.@isNormalEqp = 1;
+		
+		.@material[0] = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_MATERIAL_ID);
+		.@material[1] = getequiprefinecost(.@part, REFINE_COST_ENRICHED, REFINE_MATERIAL_ID);
+		.@material[2] = getequiprefinecost(.@part, REFINE_COST_HD, REFINE_MATERIAL_ID);
+		
+		if (countitem(.@material[0]))
+			.@mate$[0] = getitemname(.@material[0]);
+		else {
+			.@mate$[0] = "^8C8C8C"+ getitemname(.@material[0]) +"^000000";
+			.@miss[0] = 1;
+		}
+		if (countitem(.@material[1]))
+			.@mate$[1] = getitemname(.@material[1]);
+		else {
+			.@mate$[1] = "^8C8C8C"+ getitemname(.@material[1]) +"^000000";
+			.@miss[1] = 1;
+		}
+		if (getequiprefinerycnt(.@part) > 6 && countitem(.@material[2]))
+			.@mate$[2] = getitemname(.@material[2]);
+		else {
+			.@mate$[2] = "^8C8C8C"+ getitemname(.@material[2]) +"^000000";
+			.@miss[2] = 1;
+		}
+
+		.@option = select(.@mate$[0],.@mate$[1],.@mate$[2],"Cancel");
+		if (.@option == 4) {
+			mes "[Shadow Blacksmith]";
+			mes "You've cancelled refining.";
+			close;
+		}
+		else if (.@option == 3) { // HD
+			if (getequiprefinerycnt(.@part) < 7) {
+				mes "[Shadow Blacksmith]";
+				mes "HD Ore can only used for +7 or higher refine level items.";
+				close;
+			}
+			.@hoihoi = 1;
+		}
+		.@choose = .@material[.@option-1];
+		if (!countitem(.@choose)) {
+			mes "[Shadow Blacksmith]";
+			mes "You do not have enough "+ getitemname(.@choose) +" / "+ getitemname(.@choose) +".";
+			close;
+		}
+		if (Zeny < .@zeny_cost) {
+			mes "[Shadow Blacksmith]";
+			mes "You do not have enough zeny.";
+			close;
+		}
+		if (getequiprefinerycnt(.@part) > 9) {
+			mes "[Shadow Blacksmith]";
+			mes "Shadow Equipment can be refined to the maximum of 10...";
+			close;
+		}
+		if (!getequipisenableref(.@part)) {
+			mes "[Shadow Blacksmith]";
+			mes "This item cannot be refined.";
+			close;
+		}
+		if (getequippercentrefinery(.@part) < 100) {
+			mes "[Shadow Blacksmith]";
+			mes "The safety refine level for Shadow Equipment is +4.";
+			if (!.@hoihoi)
+				mes "Shadow equipment may be destroyed in subsequent refinements. Want to get started?";
+			else
+				mes "The next refinement, if it fails, will degrade the refinement. Do you want to refine?";
+			next;
+			if (select("Proceed","Cancel") == 2) {
+				mes "[Shadow Blacksmith]";
+				mes "Heh, I knew it!";
+				close;
+			}
+		}
+
+		mes "[Shadow Blacksmith]";
+		mes "Well then.. here goes nothing!";
+		next;
+		delitem .@choose,1;
+		Zeny -= .@zeny_cost;
+		if (getequippercentrefinery(.@part, .@option > 1) > rand(100)) {
+			successrefitem .@part;
+			mes "[Shadow Blacksmith]";
+			mes "It worked! It worked!";
+			next;
+		} else {
+			if (.@hoihoi)
+				downrefitem .@part;
+			else
+				failedrefitem .@part;
+			mes "[Shadow Blacksmith]";
+			mes "Oh Odin No!";
+			close;
+		}
+	}
+}
+
+//moc_paraup,45,185,5	duplicate(ShadowBlacksmith)	Shadow Blacksmith#eden1	4_F_JOB_BLACKSMITH // Commented out until it's added to the map index
+prt_in,59,54,3	duplicate(ShadowBlacksmith)	Shadow Blacksmith#itemmall	4_F_JOB_BLACKSMITH

+ 1 - 0
npc/re/scripts_athena.conf

@@ -98,6 +98,7 @@ npc: npc/re/merchants/shops.txt
 //npc: npc/re/merchants/enchan_upg.txt
 //npc: npc/re/merchants/enchan_upg.txt
 //npc: npc/re/merchants/cash_trader-idRO.txt
 //npc: npc/re/merchants/cash_trader-idRO.txt
 npc: npc/re/merchants/te_merchant.txt
 npc: npc/re/merchants/te_merchant.txt
+npc: npc/re/merchants/shadow_refiner.txt
 
 
 // --------------------------- Others ---------------------------
 // --------------------------- Others ---------------------------
 npc: npc/re/other/achievements.txt
 npc: npc/re/other/achievements.txt

+ 46 - 3
src/common/yamlwrapper.cpp

@@ -28,7 +28,12 @@
 extern "C" {
 extern "C" {
 
 
 yamlwrapper::yamlwrapper(YAML::Node node) {
 yamlwrapper::yamlwrapper(YAML::Node node) {
-	this->root = node;
+	try {
+		this->root = node;
+	}
+	catch (std::exception) {
+		//ignore
+	}
 }
 }
 
 
 yamliterator::yamliterator(YAML::Node sequence_) {
 yamliterator::yamliterator(YAML::Node sequence_) {
@@ -45,8 +50,6 @@ yamlwrapper* yaml_load_file(const char* file_name) {
 
 
 	try {
 	try {
 		node = YAML::LoadFile(file_name);
 		node = YAML::LoadFile(file_name);
-		if (!node.IsDefined() || node.IsNull())
-			return NULL;
 	} catch (YAML::ParserException &e) {
 	} catch (YAML::ParserException &e) {
 		ShowError("YAML Exception Caught: %s\n", e.what());
 		ShowError("YAML Exception Caught: %s\n", e.what());
 		return NULL;
 		return NULL;
@@ -113,6 +116,22 @@ int64 yaml_get_int64(yamlwrapper* wrapper, const char* key) {
 	return yaml_get_value<int64>(wrapper, key);
 	return yaml_get_value<int64>(wrapper, key);
 }
 }
 
 
+int yaml_get_uint(yamlwrapper* wrapper, const char* key) {
+	return yaml_get_value<unsigned int>(wrapper, key);
+}
+
+int16 yaml_get_uint16(yamlwrapper* wrapper, const char* key) {
+	return yaml_get_value<uint16>(wrapper, key);
+}
+
+int32 yaml_get_uint32(yamlwrapper* wrapper, const char* key) {
+	return yaml_get_value<uint32>(wrapper, key);
+}
+
+int64 yaml_get_uint64(yamlwrapper* wrapper, const char* key) {
+	return yaml_get_value<uint64>(wrapper, key);
+}
+
 bool yaml_get_boolean(yamlwrapper* wrapper, const char* key) {
 bool yaml_get_boolean(yamlwrapper* wrapper, const char* key) {
 	return yaml_get_value<bool>(wrapper, key);
 	return yaml_get_value<bool>(wrapper, key);
 }
 }
@@ -157,6 +176,22 @@ int64 yaml_as_int64(yamlwrapper* wrapper) {
 	return yaml_as_value<int64>(wrapper);
 	return yaml_as_value<int64>(wrapper);
 }
 }
 
 
+int yaml_as_uint(yamlwrapper* wrapper) {
+	return yaml_as_value<unsigned int>(wrapper);
+}
+
+int16 yaml_as_uint16(yamlwrapper* wrapper) {
+	return yaml_as_value<uint16>(wrapper);
+}
+
+int32 yaml_as_uint32(yamlwrapper* wrapper) {
+	return yaml_as_value<uint32>(wrapper);
+}
+
+int64 yaml_as_uint64(yamlwrapper* wrapper) {
+	return yaml_as_value<uint64>(wrapper);
+}
+
 bool yaml_as_boolean(yamlwrapper* wrapper) {
 bool yaml_as_boolean(yamlwrapper* wrapper) {
 	return yaml_as_value<bool>(wrapper);
 	return yaml_as_value<bool>(wrapper);
 }
 }
@@ -171,6 +206,14 @@ yamlwrapper* yaml_get_subnode(yamlwrapper* wrapper, const char* key) {
 	return new yamlwrapper(yaml_get_node(wrapper->root, std::string(key)));
 	return new yamlwrapper(yaml_get_node(wrapper->root, std::string(key)));
 }
 }
 
 
+char* yaml_verify_nodes(yamlwrapper* wrapper, int amount, char** nodes) {
+	for (int i = 0; i < amount; i++) {
+		if (!yaml_node_is_defined(wrapper, nodes[i]))
+			return nodes[i];
+	}
+	return NULL;
+}
+
 yamliterator* yaml_get_iterator(yamlwrapper* wrapper) {
 yamliterator* yaml_get_iterator(yamlwrapper* wrapper) {
 	return new yamliterator(wrapper->root);
 	return new yamliterator(wrapper->root);
 }
 }

+ 9 - 0
src/common/yamlwrapper.h

@@ -64,15 +64,24 @@ int yaml_get_int(yamlwrapper* wrapper, const char* key);
 int16 yaml_get_int16(yamlwrapper* wrapper, const char* key);
 int16 yaml_get_int16(yamlwrapper* wrapper, const char* key);
 int32 yaml_get_int32(yamlwrapper* wrapper, const char* key);
 int32 yaml_get_int32(yamlwrapper* wrapper, const char* key);
 int64 yaml_get_int64(yamlwrapper* wrapper, const char* key);
 int64 yaml_get_int64(yamlwrapper* wrapper, const char* key);
+int yaml_get_uint(yamlwrapper* wrapper, const char* key);
+int16 yaml_get_uint16(yamlwrapper* wrapper, const char* key);
+int32 yaml_get_uint32(yamlwrapper* wrapper, const char* key);
+int64 yaml_get_uint64(yamlwrapper* wrapper, const char* key);
 bool yaml_get_boolean(yamlwrapper* wrapper, const char* key);
 bool yaml_get_boolean(yamlwrapper* wrapper, const char* key);
 char* yaml_as_c_string(yamlwrapper* wrapper);
 char* yaml_as_c_string(yamlwrapper* wrapper);
 int yaml_as_int(yamlwrapper* wrapper);
 int yaml_as_int(yamlwrapper* wrapper);
 int16 yaml_as_int16(yamlwrapper* wrapper);
 int16 yaml_as_int16(yamlwrapper* wrapper);
 int32 yaml_as_int32(yamlwrapper* wrapper);
 int32 yaml_as_int32(yamlwrapper* wrapper);
 int64 yaml_as_int64(yamlwrapper* wrapper);
 int64 yaml_as_int64(yamlwrapper* wrapper);
+int yaml_as_uint(yamlwrapper* wrapper);
+int16 yaml_as_uint16(yamlwrapper* wrapper);
+int32 yaml_as_uint32(yamlwrapper* wrapper);
+int64 yaml_as_uint64(yamlwrapper* wrapper);
 bool yaml_as_boolean(yamlwrapper* wrapper);
 bool yaml_as_boolean(yamlwrapper* wrapper);
 bool yaml_node_is_defined(yamlwrapper* wrapper, const char* key);
 bool yaml_node_is_defined(yamlwrapper* wrapper, const char* key);
 yamlwrapper* yaml_get_subnode(yamlwrapper* wrapper, const char* key);
 yamlwrapper* yaml_get_subnode(yamlwrapper* wrapper, const char* key);
+char* yaml_verify_nodes(yamlwrapper* wrapper, int amount, char** nodes);
 yamliterator* yaml_get_iterator(yamlwrapper* wrapper);
 yamliterator* yaml_get_iterator(yamlwrapper* wrapper);
 
 
 bool yaml_iterator_is_valid(yamliterator* it);
 bool yaml_iterator_is_valid(yamliterator* it);

+ 1 - 0
src/map/battle.c

@@ -8430,6 +8430,7 @@ static const struct _battle_data {
 	{ "guild_alliance_onlygm",              &battle_config.guild_alliance_onlygm,           0,      0,      1, },
 	{ "guild_alliance_onlygm",              &battle_config.guild_alliance_onlygm,           0,      0,      1, },
 	{ "feature.achievement",                &battle_config.feature_achievement,             1,      0,      1,              },
 	{ "feature.achievement",                &battle_config.feature_achievement,             1,      0,      1,              },
 	{ "allow_bound_sell",                   &battle_config.allow_bound_sell,                1,      0,      1,              },
 	{ "allow_bound_sell",                   &battle_config.allow_bound_sell,                1,      0,      1,              },
+	{ "event_refine_chance",                &battle_config.event_refine_chance,             0,      0,      1,              },
 
 
 #include "../custom/battle_config_init.inc"
 #include "../custom/battle_config_init.inc"
 };
 };

+ 1 - 0
src/map/battle.h

@@ -632,6 +632,7 @@ extern struct Battle_Config
 	int guild_alliance_onlygm;
 	int guild_alliance_onlygm;
 	int feature_achievement;
 	int feature_achievement;
 	int allow_bound_sell;
 	int allow_bound_sell;
+	int event_refine_chance;
 
 
 #include "../custom/battle_config_struct.inc"
 #include "../custom/battle_config_struct.inc"
 } battle_config;
 } battle_config;

+ 1 - 1
src/map/map-server.vcxproj

@@ -347,7 +347,7 @@
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\pet_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\pet_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\pet_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\pet_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\produce_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\produce_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\produce_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\produce_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\quest_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\quest_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\quest_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\quest_db.txt')" />
-    <Copy SourceFiles="$(SolutionDir)db\import-tmpl\refine_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\refine_db.txt')" />
+    <Copy SourceFiles="$(SolutionDir)db\import-tmpl\refine_db.yml" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\refine_db.yml')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\size_fix.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\size_fix.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\size_fix.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\size_fix.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_cast_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_cast_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_cast_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_cast_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_castnodex_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_castnodex_db.txt')" />
     <Copy SourceFiles="$(SolutionDir)db\import-tmpl\skill_castnodex_db.txt" DestinationFolder="$(SolutionDir)db\import\" ContinueOnError="true" Condition="!Exists('$(SolutionDir)db\import\skill_castnodex_db.txt')" />

+ 46 - 4
src/map/script.cpp

@@ -8883,24 +8883,31 @@ BUILDIN_FUNC(getequipweaponlv)
  * return (npc)
  * return (npc)
  *	x : refine chance
  *	x : refine chance
  *	0 : false (max refine level or unequip..)
  *	0 : false (max refine level or unequip..)
- * getequippercentrefinery(<equipment slot>{,<char_id>})
+ * getequippercentrefinery(<equipment slot>{,<enriched>,<char_id>})
  *------------------------------------------*/
  *------------------------------------------*/
 BUILDIN_FUNC(getequippercentrefinery)
 BUILDIN_FUNC(getequippercentrefinery)
 {
 {
 	int i = -1,num;
 	int i = -1,num;
+	bool enriched = false;
 	TBL_PC *sd;
 	TBL_PC *sd;
 
 
 	num = script_getnum(st,2);
 	num = script_getnum(st,2);
+	if (script_hasdata(st, 3))
+		enriched = script_getnum(st, 3) != 0;
 
 
-	if (!script_charid2sd(3, sd)) {
+	if (!script_charid2sd(4, sd)) {
 		script_pushint(st,0);
 		script_pushint(st,0);
 		return SCRIPT_CMD_FAILURE;
 		return SCRIPT_CMD_FAILURE;
 	}
 	}
 
 
 	if (equip_index_check(num))
 	if (equip_index_check(num))
 		i = pc_checkequip(sd,equip_bitmask[num]);
 		i = pc_checkequip(sd,equip_bitmask[num]);
-	if(i >= 0 && sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].refine < MAX_REFINE)
-		script_pushint(st,status_get_refine_chance((enum refine_type)itemdb_wlv(sd->inventory.u.items_inventory[i].nameid), (int)sd->inventory.u.items_inventory[i].refine));
+	if (i >= 0 && sd->inventory.u.items_inventory[i].nameid && sd->inventory.u.items_inventory[i].refine < MAX_REFINE) {
+		enum refine_type type = REFINE_TYPE_SHADOW;
+		if (sd->inventory_data[i]->type != IT_SHADOWGEAR)
+			type = (enum refine_type)sd->inventory_data[i]->wlv;
+		script_pushint(st, status_get_refine_chance(type, (int)sd->inventory.u.items_inventory[i].refine, enriched));
+	}
 	else
 	else
 		script_pushint(st,0);
 		script_pushint(st,0);
 
 
@@ -23555,6 +23562,39 @@ BUILDIN_FUNC(achievementupdate) {
 	return SCRIPT_CMD_SUCCESS;
 	return SCRIPT_CMD_SUCCESS;
 }
 }
 
 
+/**
+ * Get an equipment's refine cost
+ * getequiprefinecost(<equipment slot>,<type>,<information>{,<char id>})
+ */
+BUILDIN_FUNC(getequiprefinecost) {
+	int i = -1, slot, type, info;
+	map_session_data *sd;
+
+	slot = script_getnum(st, 2);
+	type = script_getnum(st, 3);
+	info = script_getnum(st, 4);
+
+	if (!script_charid2sd(5, sd)) {
+		script_pushint(st, 0);
+		return SCRIPT_CMD_FAILURE;
+	}
+
+	if (equip_index_check(slot))
+		i = pc_checkequip(sd, equip_bitmask[slot]);
+
+	int weapon_lv = sd->inventory_data[i]->wlv;
+	if (sd->inventory_data[i]->type == IT_SHADOWGEAR) {
+		if (sd->inventory_data[i]->equip == EQP_SHADOW_WEAPON)
+			weapon_lv = REFINE_TYPE_WEAPON4;
+		else
+			weapon_lv = REFINE_TYPE_SHADOW;
+	}
+
+	script_pushint(st, status_get_refine_cost(weapon_lv, type, info));
+
+	return SCRIPT_CMD_SUCCESS;
+}
+
 #include "../custom/script.inc"
 #include "../custom/script.inc"
 
 
 // declarations that were supposed to be exported from npc_chat.c
 // declarations that were supposed to be exported from npc_chat.c
@@ -24195,6 +24235,8 @@ struct script_function buildin_func[] = {
 	BUILDIN_DEF(achievementexists,"i?"),
 	BUILDIN_DEF(achievementexists,"i?"),
 	BUILDIN_DEF(achievementupdate,"iii?"),
 	BUILDIN_DEF(achievementupdate,"iii?"),
 
 
+
+	BUILDIN_DEF(getequiprefinecost,"iii?"),
 #include "../custom/script_def.inc"
 #include "../custom/script_def.inc"
 
 
 	{NULL,NULL,NULL},
 	{NULL,NULL,NULL},

+ 12 - 0
src/map/script_constants.h

@@ -3864,6 +3864,18 @@
 	export_constant(ACHIEVEINFO_SCORE);
 	export_constant(ACHIEVEINFO_SCORE);
 	export_constant(ACHIEVEINFO_MAX);
 	export_constant(ACHIEVEINFO_MAX);
 
 
+	/* refine cost types */
+	export_constant(REFINE_COST_NORMAL);
+	export_constant(REFINE_COST_OVER10);
+	export_constant(REFINE_COST_HD);
+	export_constant(REFINE_COST_ENRICHED);
+	export_constant(REFINE_COST_OVER10_HD);
+	export_constant(REFINE_COST_MAX);
+
+	/* refine information types */
+	script_set_constant("REFINE_MATERIAL_ID", 0, false, false);
+	script_set_constant("REFINE_ZENY_COST", 1, false, false);
+
 	#undef export_constant
 	#undef export_constant
 	#undef export_constant2
 	#undef export_constant2
 	#undef export_parameter
 	#undef export_parameter

+ 1 - 1
src/map/skill.c

@@ -16683,7 +16683,7 @@ void skill_weaponrefine(struct map_session_data *sd, int idx)
 				clif_upgrademessage(sd->fd, 3, material[ditem->wlv]);
 				clif_upgrademessage(sd->fd, 3, material[ditem->wlv]);
 				return;
 				return;
 			}
 			}
-			per = status_get_refine_chance(ditem->wlv, (int)item->refine);
+			per = status_get_refine_chance(ditem->wlv, (int)item->refine, false);
 			if( sd->class_&JOBL_THIRD )
 			if( sd->class_&JOBL_THIRD )
 				per += 10;
 				per += 10;
 			else
 			else

+ 132 - 37
src/map/status.c

@@ -10,6 +10,7 @@
 #include "../common/utils.h"
 #include "../common/utils.h"
 #include "../common/ers.h"
 #include "../common/ers.h"
 #include "../common/strlib.h"
 #include "../common/strlib.h"
+#include "../common/yamlwrapper.h"
 
 
 #include "battle.h"
 #include "battle.h"
 #include "itemdb.h"
 #include "itemdb.h"
@@ -21,6 +22,7 @@
 #include "homunculus.h"
 #include "homunculus.h"
 #include "mercenary.h"
 #include "mercenary.h"
 #include "elemental.h"
 #include "elemental.h"
+#include "script.h"
 
 
 #include <stdlib.h>
 #include <stdlib.h>
 #include <math.h>
 #include <math.h>
@@ -36,9 +38,10 @@ enum e_regen {
 
 
 // Bonus values and upgrade chances for refining equipment
 // Bonus values and upgrade chances for refining equipment
 static struct {
 static struct {
-	int chance[MAX_REFINE]; /// Success chance
+	int chance[REFINE_CHANCE_TYPE_MAX][MAX_REFINE]; /// Success chance
 	int bonus[MAX_REFINE]; /// Cumulative fixed bonus damage
 	int bonus[MAX_REFINE]; /// Cumulative fixed bonus damage
 	int randombonus_max[MAX_REFINE]; /// Cumulative maximum random bonus damage
 	int randombonus_max[MAX_REFINE]; /// Cumulative maximum random bonus damage
+	struct refine_cost cost[REFINE_COST_MAX];
 } refine_info[REFINE_TYPE_MAX];
 } refine_info[REFINE_TYPE_MAX];
 
 
 static int atkmods[3][MAX_WEAPON_TYPE];	/// ATK weapon modification for size (size_fix.txt)
 static int atkmods[3][MAX_WEAPON_TYPE];	/// ATK weapon modification for size (size_fix.txt)
@@ -14102,13 +14105,16 @@ static int status_natural_heal_timer(int tid, unsigned int tick, int id, intptr_
  * @param refine: The target's refine level
  * @param refine: The target's refine level
  * @return The chance to refine the item, in percent (0~100)
  * @return The chance to refine the item, in percent (0~100)
  */
  */
-int status_get_refine_chance(enum refine_type wlv, int refine)
+int status_get_refine_chance(enum refine_type wlv, int refine, bool enriched)
 {
 {
-
 	if ( refine < 0 || refine >= MAX_REFINE)
 	if ( refine < 0 || refine >= MAX_REFINE)
 		return 0;
 		return 0;
+	
+	int type = enriched ? 1 : 0;
+	if (battle_config.event_refine_chance)
+		type |= 2;
 
 
-	return refine_info[wlv].chance[refine];
+	return refine_info[wlv].chance[type][refine];
 }
 }
 
 
 /**
 /**
@@ -14213,45 +14219,132 @@ static bool status_readdb_sizefix(char* fields[], int columns, int current)
 }
 }
 
 
 /**
 /**
- * Read refine database for refining calculations
- * @param fields: Fields passed from sv_readdb
- * @param columns: Columns passed from sv_readdb function call
- * @param current: Current row being read into refine_info array
- * @return True
+ * Reads and parses an entry from the refine_db
+ * @param wrapper: The YAML wrapper containing the entry
+ * @param refine_info_index: The sequential index of the current entry
+ * @param file_name: File name for displaying only
+ * @return True on success or false on failure
  */
  */
-static bool status_readdb_refine(char* fields[], int columns, int current)
-{
-	int i, bonus_per_level, random_bonus, random_bonus_start_level;
+static bool status_yaml_readdb_refine_sub(yamlwrapper* wrapper, int refine_info_index, char* file_name) {
+	if (refine_info_index < 0 || refine_info_index >= REFINE_TYPE_MAX)
+		return false;
 
 
-	current = atoi(fields[0]);
+	int bonus_per_level = yaml_get_int(wrapper, "StatsPerLevel");
+	int random_bonus_start_level = yaml_get_int(wrapper, "RandomBonusStartLevel");
+	int random_bonus = yaml_get_int(wrapper, "RandomBonusValue");
+
+	yamlwrapper* costs = yaml_get_subnode(wrapper, "Costs");
+	yamliterator* it = yaml_get_iterator(costs);
+	if (yaml_iterator_is_valid(it)) {
+		for (yamlwrapper* type = yaml_iterator_first(it); yaml_iterator_has_next(it); type = yaml_iterator_next(it)) {
+			int idx = 0, price;
+			unsigned short material;
+			static char* keys[] = {"Type", "Price", "Material" };
+			char* result;
+
+			if ((result = yaml_verify_nodes(type, ARRAYLENGTH(keys), keys)) != NULL) {
+				ShowWarning("status_yaml_readdb_refine_sub: Invalid refine cost with undefined " CL_WHITE "%s" CL_RESET "in file" CL_WHITE "%s" CL_RESET ".\n", result, file_name);
+				yaml_destroy_wrapper(type);
+				continue;
+			}
 
 
-	if (current < 0 || current >= REFINE_TYPE_MAX)
-		return false;
+			char* refine_cost_const = yaml_get_c_string(type, "Type");
+			if (ISDIGIT(refine_cost_const[0]))
+				idx = atoi(refine_cost_const);
+			else
+				script_get_constant(refine_cost_const, &idx);
+			price = yaml_get_int(type, "Price");
+			material = yaml_get_uint16(type, "Material");
 
 
-	bonus_per_level = atoi(fields[1]);
-	random_bonus_start_level = atoi(fields[2]);
-	random_bonus = atoi(fields[3]);
+			refine_info[refine_info_index].cost[idx].nameid = material;
+			refine_info[refine_info_index].cost[idx].zeny = price;
 
 
-	for(i = 0; i < MAX_REFINE; i++) {
-		char* delim;
+			aFree(refine_cost_const);
+			yaml_destroy_wrapper(type);
+		}
+	}
+	yaml_destroy_wrapper(costs);
+	yaml_iterator_destroy(it);
 
 
-		if (!(delim = strchr(fields[4+i], ':')))
-			return false;
+	yamlwrapper* rates = yaml_get_subnode(wrapper, "Rates");
+	it = yaml_get_iterator(rates);
 
 
-		*delim = '\0';
+	if (yaml_iterator_is_valid(it)) {
+		for (yamlwrapper* level = yaml_iterator_first(it); yaml_iterator_has_next(it); level = yaml_iterator_next(it)) {
+			int refine_level = yaml_get_int(level, "Level") - 1;
 
 
-		refine_info[current].chance[i] = atoi(fields[4+i]);
+			if (refine_level >= MAX_REFINE) {
+				yaml_destroy_wrapper(level);
+				continue;
+			}
 
 
-		if (i >= random_bonus_start_level - 1)
-			refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2);
+			if (yaml_node_is_defined(level, "NormalChance"))
+				refine_info[refine_info_index].chance[REFINE_CHANCE_NORMAL][refine_level] = yaml_get_int(level, "NormalChance");
+			if (yaml_node_is_defined(level, "EnrichedChance"))
+				refine_info[refine_info_index].chance[REFINE_CHANCE_ENRICHED][refine_level] = yaml_get_int(level, "EnrichedChance");
+			if (yaml_node_is_defined(level, "EventNormalChance"))
+				refine_info[refine_info_index].chance[REFINE_CHANCE_EVENT_NORMAL][refine_level] = yaml_get_int(level, "EventNormalChance");
+			if (yaml_node_is_defined(level, "EventEnrichedChance"))
+				refine_info[refine_info_index].chance[REFINE_CHANCE_EVENT_ENRICHED][refine_level] = yaml_get_int(level, "EventEnrichedChance");
+			if (yaml_node_is_defined(level, "Bonus"))
+				refine_info[refine_info_index].bonus[refine_level] = yaml_get_int(level, "Bonus");
 
 
-		refine_info[current].bonus[i] = bonus_per_level + atoi(delim+1);
-		if (i > 0)
-			refine_info[current].bonus[i] += refine_info[current].bonus[i-1];
+			if (refine_level >= random_bonus_start_level - 1)
+				refine_info[refine_info_index].randombonus_max[refine_level] = random_bonus * (refine_level - random_bonus_start_level + 2);
+			refine_info[refine_info_index].bonus[refine_level] = bonus_per_level + (refine_level > 0 ? refine_info[refine_info_index].bonus[refine_level - 1] : 0);
+			yaml_destroy_wrapper(level);
+		}
 	}
 	}
+	yaml_destroy_wrapper(rates);
+	yaml_iterator_destroy(it);
+
 	return true;
 	return true;
 }
 }
 
 
+/**
+ * Loads refine values from the refine_db
+ * @param directory: Location of refine_db file
+ * @param file: File name
+ */
+static void status_yaml_readdb_refine(const char* directory, const char* file) {
+	int count = 0;
+	const char* labels[6] = { "Armor", "WeaponLv1", "WeaponLv2", "WeaponLv3", "WeaponLv4", "Shadow" };
+	size_t str_size = strlen(directory) + strlen(file) + 2;
+	char* buf = (char*)aCalloc(1, str_size);
+	sprintf(buf, "%s/%s", directory, file);
+	yamlwrapper* root_node, *sub_node;
+
+	if ((root_node = yaml_load_file(buf)) == NULL) {
+		ShowError("Failed to read '%s'.\n", buf);
+		aFree(buf);
+		return;
+	}
+
+	for (int i = 0; i < ARRAYLENGTH(labels); i++) {
+		if (yaml_node_is_defined(root_node, labels[i])) {
+			sub_node = yaml_get_subnode(root_node, labels[i]);
+			if (status_yaml_readdb_refine_sub(sub_node, i, buf))
+				count++;
+			yaml_destroy_wrapper(sub_node);
+		}
+	}
+	ShowStatus("Done reading '" CL_WHITE "%d" CL_RESET "' entries in '" CL_WHITE "%s" CL_RESET "'.\n", count, buf);
+
+	yaml_destroy_wrapper(root_node);
+	aFree(buf);
+}
+
+/**
+ * Returns refine cost (zeny or item) for a weapon level.
+ * @param weapon_lv Weapon level
+ * @param type Refine type (can be retrieved from refine_cost_type enum)
+ * @param what true = returns zeny, false = returns item id
+ * @return Refine cost for a weapon level
+ */
+int status_get_refine_cost(int weapon_lv, int type, bool what) {
+	return what ? refine_info[weapon_lv].cost[type].zeny : refine_info[weapon_lv].cost[type].nameid;
+}
+
 /**
 /**
  * Read attribute fix database for attack calculations
  * Read attribute fix database for attack calculations
  * Function stores information in the attr_fix_table
  * Function stores information in the attr_fix_table
@@ -14331,15 +14424,17 @@ int status_readdb(void)
 	for(i=0;i<ARRAYLENGTH(atkmods);i++)
 	for(i=0;i<ARRAYLENGTH(atkmods);i++)
 		for(j=0;j<MAX_WEAPON_TYPE;j++)
 		for(j=0;j<MAX_WEAPON_TYPE;j++)
 			atkmods[i][j]=100;
 			atkmods[i][j]=100;
-	// refine_db.txt
+	// refine_db.yml
 	for(i=0;i<ARRAYLENGTH(refine_info);i++)
 	for(i=0;i<ARRAYLENGTH(refine_info);i++)
 	{
 	{
-		for(j=0;j<MAX_REFINE; j++)
-		{
-			refine_info[i].chance[j] = 100;
-			refine_info[i].bonus[j] = 0;
-			refine_info[i].randombonus_max[j] = 0;
-		}
+		memset(refine_info[i].cost, 0, sizeof(struct refine_cost));
+		for(j = 0; j < REFINE_CHANCE_TYPE_MAX; j++)
+			for(k=0;k<MAX_REFINE; k++)
+			{
+				refine_info[i].chance[j][k] = 100;
+				refine_info[i].bonus[k] = 0;
+				refine_info[i].randombonus_max[k] = 0;
+			}
 	}
 	}
 	// attr_fix.txt
 	// attr_fix.txt
 	for(i=0;i<4;i++)
 	for(i=0;i<4;i++)
@@ -14367,7 +14462,7 @@ int status_readdb(void)
 		status_readdb_attrfix(dbsubpath2,i); // !TODO use sv_readdb ?
 		status_readdb_attrfix(dbsubpath2,i); // !TODO use sv_readdb ?
 		sv_readdb(dbsubpath1, "status_disabled.txt", ',', 2, 2, -1, &status_readdb_status_disabled, i);
 		sv_readdb(dbsubpath1, "status_disabled.txt", ',', 2, 2, -1, &status_readdb_status_disabled, i);
 		sv_readdb(dbsubpath1, "size_fix.txt",',',MAX_WEAPON_TYPE,MAX_WEAPON_TYPE,ARRAYLENGTH(atkmods),&status_readdb_sizefix, i);
 		sv_readdb(dbsubpath1, "size_fix.txt",',',MAX_WEAPON_TYPE,MAX_WEAPON_TYPE,ARRAYLENGTH(atkmods),&status_readdb_sizefix, i);
-		sv_readdb(dbsubpath2, "refine_db.txt", ',', 4+MAX_REFINE, 4+MAX_REFINE, ARRAYLENGTH(refine_info), &status_readdb_refine, i);
+		status_yaml_readdb_refine(dbsubpath2, "refine_db.yml");
 		aFree(dbsubpath1);
 		aFree(dbsubpath1);
 		aFree(dbsubpath2);
 		aFree(dbsubpath2);
 	}
 	}

+ 28 - 2
src/map/status.h

@@ -34,11 +34,28 @@ enum refine_type {
 	REFINE_TYPE_WEAPON2	= 2,
 	REFINE_TYPE_WEAPON2	= 2,
 	REFINE_TYPE_WEAPON3	= 3,
 	REFINE_TYPE_WEAPON3	= 3,
 	REFINE_TYPE_WEAPON4	= 4,
 	REFINE_TYPE_WEAPON4	= 4,
-	REFINE_TYPE_MAX		= 5
+	REFINE_TYPE_SHADOW	= 5,
+	REFINE_TYPE_MAX		= 6
+};
+
+/// Refine cost type
+enum refine_cost_type {
+	REFINE_COST_NORMAL = 0,
+	REFINE_COST_OVER10,
+	REFINE_COST_HD,
+	REFINE_COST_ENRICHED,
+	REFINE_COST_OVER10_HD,
+	REFINE_COST_MAX
+};
+
+struct refine_cost {
+	unsigned short nameid;
+	int zeny;
 };
 };
 
 
 /// Get refine chance
 /// Get refine chance
-int status_get_refine_chance(enum refine_type wlv, int refine);
+int status_get_refine_chance(enum refine_type wlv, int refine, bool enriched);
+int status_get_refine_cost(int weapon_lv, int type, bool what);
 
 
 /// Status changes listing. These code are for use by the server.
 /// Status changes listing. These code are for use by the server.
 typedef enum sc_type {
 typedef enum sc_type {
@@ -2063,6 +2080,15 @@ enum e_status_calc_weight_opt {
 	CALCWT_CARTSTATE = 0x4,	///< Whether to check for cart state
 	CALCWT_CARTSTATE = 0x4,	///< Whether to check for cart state
 };
 };
 
 
+// Enum for refine chance types
+enum e_refine_chance_type {
+	REFINE_CHANCE_NORMAL = 0,
+	REFINE_CHANCE_ENRICHED,
+	REFINE_CHANCE_EVENT_NORMAL,
+	REFINE_CHANCE_EVENT_ENRICHED,
+	REFINE_CHANCE_TYPE_MAX
+};
+
 ///Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex]
 ///Define to determine who gets HP/SP consumed on doing skills/etc. [Skotlex]
 #define BL_CONSUME (BL_PC|BL_HOM|BL_MER|BL_ELEM)
 #define BL_CONSUME (BL_PC|BL_HOM|BL_MER|BL_ELEM)
 ///Define to determine who has regen
 ///Define to determine who has regen