From e24d30a7113835f9c33f0fb51b89acfb7e00882f Mon Sep 17 00:00:00 2001 From: Jittapan Pluemsumran Date: Mon, 18 Sep 2017 21:52:52 +0700 Subject: [PATCH] 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. --- conf/battle/items.conf | 5 + db/import-tmpl/refine_db.txt | 32 -- db/import-tmpl/refine_db.yml | 20 + db/pre-re/refine_db.txt | 41 -- db/pre-re/refine_db.yml | 235 +++++++++++ db/re/refine_db.txt | 41 -- db/re/refine_db.yml | 584 ++++++++++++++++++++++++++ doc/script_commands.txt | 29 +- npc/merchants/advanced_refiner.txt | 27 +- npc/merchants/refine.txt | 192 ++++----- npc/re/merchants/advanced_refiner.txt | 26 +- npc/re/merchants/blessed_refiner.txt | 11 +- npc/re/merchants/hd_refiner.txt | 41 +- npc/re/merchants/refine.txt | 95 ++--- npc/re/merchants/shadow_refiner.txt | 143 +++++++ npc/re/scripts_athena.conf | 1 + src/common/yamlwrapper.cpp | 49 ++- src/common/yamlwrapper.h | 9 + src/map/battle.c | 1 + src/map/battle.h | 1 + src/map/map-server.vcxproj | 2 +- src/map/script.cpp | 50 ++- src/map/script_constants.h | 12 + src/map/skill.c | 2 +- src/map/status.c | 173 ++++++-- src/map/status.h | 30 +- 26 files changed, 1445 insertions(+), 407 deletions(-) delete mode 100644 db/import-tmpl/refine_db.txt create mode 100644 db/import-tmpl/refine_db.yml delete mode 100644 db/pre-re/refine_db.txt create mode 100644 db/pre-re/refine_db.yml delete mode 100644 db/re/refine_db.txt create mode 100644 db/re/refine_db.yml create mode 100644 npc/re/merchants/shadow_refiner.txt diff --git a/conf/battle/items.conf b/conf/battle/items.conf index f7efd93d10..007024b512 100644 --- a/conf/battle/items.conf +++ b/conf/battle/items.conf @@ -110,3 +110,8 @@ default_bind_on_equip: 4 // no = Bound items are unable to be sold at Itemshops // yes = Bound items are able to be sold at Itemshops 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 diff --git a/db/import-tmpl/refine_db.txt b/db/import-tmpl/refine_db.txt deleted file mode 100644 index fcc13be56b..0000000000 --- a/db/import-tmpl/refine_db.txt +++ /dev/null @@ -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) - diff --git a/db/import-tmpl/refine_db.yml b/db/import-tmpl/refine_db.yml new file mode 100644 index 0000000000..fbe8728eec --- /dev/null +++ b/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 . +# +########################################################################### +# Custom Refine Database +########################################################################### diff --git a/db/pre-re/refine_db.txt b/db/pre-re/refine_db.txt deleted file mode 100644 index 1bec859f12..0000000000 --- a/db/pre-re/refine_db.txt +++ /dev/null @@ -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 diff --git a/db/pre-re/refine_db.yml b/db/pre-re/refine_db.yml new file mode 100644 index 0000000000..3602c72b78 --- /dev/null +++ b/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 . +# +########################################################################### +# 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 diff --git a/db/re/refine_db.txt b/db/re/refine_db.txt deleted file mode 100644 index 87a134b276..0000000000 --- a/db/re/refine_db.txt +++ /dev/null @@ -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 diff --git a/db/re/refine_db.yml b/db/re/refine_db.yml new file mode 100644 index 0000000000..f96e0d2d9a --- /dev/null +++ b/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 . +# +########################################################################### +# 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 diff --git a/doc/script_commands.txt b/doc/script_commands.txt index d11ccb06b6..4ef760762d 100644 --- a/doc/script_commands.txt +++ b/doc/script_commands.txt @@ -2719,14 +2719,17 @@ Examples: --------------------------------------- -*getequippercentrefinery({,}) +*getequippercentrefinery({,,}) This function calculates and returns the percent value chance to successfully 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 -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'. +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 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) @@ -2737,6 +2740,28 @@ random change of a refine succeeding or failing and then going through with it --------------------------------------- +*getequiprefinecost(,,{,}) + +This function returns refine cost for equipment in based on +passed arguments and . + +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 argument. + +Valid information types are: + +REFINE_ZENY_COST - Zeny +REFINE_MATERIAL_ID - Material Item ID + +--------------------------------------- + *getareadropitem("",,,,,) This function will count all the items with the specified ID number lying on the diff --git a/npc/merchants/advanced_refiner.txt b/npc/merchants/advanced_refiner.txt index d2e05c6406..63f01c8f6e 100644 --- a/npc/merchants/advanced_refiner.txt +++ b/npc/merchants/advanced_refiner.txt @@ -1,22 +1,11 @@ //===== rAthena Script ======================================= //= Advanced Refiner -//===== By: ================================================== -//= L0ne_W0lf -//===== Current Version: ===================================== -//= 1.6 -//===== Compatible With: ===================================== -//= rAthena Project //===== Description: ========================================= //= [Official Conversion] //= 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. //= - Uses the iRO position for this NPC. -//===== Additional Comments: ================================= +//===== Changelog: =========================================== //= 1.0 First Version. [L0ne_W0lf] //= 1.1 Fixed a weird carriage return. o_o [L0ne_W0lf] //= 1.2 Optimizing refine method [Zephyrus] @@ -26,6 +15,7 @@ //= 1.4b Fixed coordinates. [Euphy] //= 1.5 Some official script updates. [Euphy] //= 1.6 Added VIP features. [Euphy] +//= 1.7 Removed re-roll behavior. [Secret] //============================================================ payon,157,146,6 script Suhnbi#cash 85,{ @@ -65,19 +55,12 @@ payon,157,146,6 script Suhnbi#cash 85,{ 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 "Clang! Clang! Clang!"; - if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) { + if (getequippercentrefinery(.@part, true) > rand(100)) { successrefitem .@part; next; emotion e_no1; diff --git a/npc/merchants/refine.txt b/npc/merchants/refine.txt index 862ebd2189..176b8aced7 100644 --- a/npc/merchants/refine.txt +++ b/npc/merchants/refine.txt @@ -38,7 +38,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 986,1; // Anvil - set Zeny, Zeny-30000; + Zeny = Zeny-30000; 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."; close; @@ -49,7 +49,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 987,1; // Oridecon_Anvil - set Zeny, Zeny-120000; + Zeny = Zeny-120000; 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."; close; @@ -60,7 +60,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 988,1; // Golden_Anvil - set Zeny, Zeny-300000; + Zeny = Zeny-300000; 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."; close; @@ -101,7 +101,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ break; } } - set .@sell,.@input * 150; + .@sell = .@input * 150; if (Zeny < .@sell) { 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."; @@ -113,7 +113,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 612,.@input; // Portable_Furnace - set Zeny, Zeny-.@sell; + Zeny = Zeny-.@sell; mes "[Christopher Guillenrow]"; mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need."; close; @@ -124,7 +124,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 613,1; // Iron_Hammer - set Zeny, Zeny-1000; + Zeny = Zeny-1000; mes "[Christopher Guillenrow]"; mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need."; close; @@ -135,7 +135,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 614,1; // Golden_Hammer - set Zeny, Zeny-3000; + Zeny = Zeny-3000; mes "[Christopher Guillenrow]"; mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need."; close; @@ -146,7 +146,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 615,1; // Oridecon_Hammer - set Zeny, Zeny-5000; + Zeny = Zeny-5000; mes "[Christopher Guillenrow]"; mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need."; close; @@ -182,7 +182,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ break; } } - set .@sell,.@input * 200; + .@sell = .@input * 200; if (Zeny < .@sell) { 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."; @@ -194,7 +194,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 1010,.@input; // Phracon - set Zeny, Zeny-.@sell; + Zeny = Zeny-.@sell; mes "[Christopher Guillenrow]"; mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need."; close; @@ -220,7 +220,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ break; } } - set .@sell,.@input * 1000; + .@sell = .@input * 1000; if (Zeny < .@sell) { 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."; @@ -232,7 +232,7 @@ geffen_in,110,172,0 script Christopher#1 63,{ close; } getitem 1011,.@input; // Emveretarcon - set Zeny, Zeny-.@sell; + Zeny = Zeny-.@sell; mes "[Christopher Guillenrow]"; mes "Thank ye fer shopping at me workshop. Feel free to come anytime, whenever ye need, whenever ye want."; close; @@ -314,7 +314,7 @@ ein_in01,38,29,0 script Paul Spanner 63,{ close; } getitem 986,1; //Anvil - set Zeny, Zeny-30000; + Zeny = Zeny-30000; mes "[Paul Spanner]"; 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."; @@ -326,7 +326,7 @@ ein_in01,38,29,0 script Paul Spanner 63,{ close; } getitem 987,1; //Oridecon_Anvil - set Zeny, Zeny-120000; + Zeny = Zeny-120000; mes "[Paul Spanner]"; 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."; @@ -338,7 +338,7 @@ ein_in01,38,29,0 script Paul Spanner 63,{ close; } getitem 988,1; //Golden_Anvil - set Zeny, Zeny-300000; + Zeny = Zeny-300000; 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 "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; switch(select("Mini Furnace - 150z.:Iron Hammer - 1,000z.:Golden Hammer - 3,000z.:Oridecon Hammer - 5,000z.:Cancel.")) { 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 "You definately need this furnce to process ores!"; next; break; case 2: - set .@item,613; - set .@item_cost,1000; - set .@item_weight,200; + .@item = 613; + .@item_cost = 1000; + .@item_weight = 200; break; case 3: - set .@item,614; - set .@item_cost,3000; - set .@item_weight,300; + .@item = 614; + .@item_cost = 3000; + .@item_weight = 300; break; case 4: - set .@item,615; - set .@item_cost,5000; - set .@item_weight,400; + .@item = 615; + .@item_cost = 5000; + .@item_weight = 400; break; case 5: mes "[Paul Spanner]"; @@ -406,7 +406,7 @@ ein_in01,38,29,0 script Paul Spanner 63,{ break; } } - set .@sell,.@input * .@item_cost; + .@sell = .@input * .@item_cost; if (Zeny < .@sell) { mes "[Paul Spanner]"; 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."; close; } - set Zeny, Zeny-.@sell; + Zeny = Zeny-.@sell; getitem .@item,.@input; mes "[Paul Spanner]"; 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; switch(select("Phracon - 200z.:Emveretarcon - 1,000z.:Quit.")) { case 1: - set .@item,1010; - set .@item_price,200; + .@item = 1010; + .@item_price = 200; break; case 2: - set .@item,1011; - set .@item_price,1000; + .@item = 1011; + .@item_price = 1000; break; case 3: mes "[Paul Spanner]"; @@ -460,7 +460,7 @@ ein_in01,38,29,0 script Paul Spanner 63,{ break; } } - set .@sell,.@input * .@item_price; + .@sell = .@input * .@item_price; if (Zeny < .@sell) { mes "[Paul Spanner]"; 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; } getitem .@item,.@input; - set Zeny, Zeny-.@sell; + Zeny = Zeny-.@sell; mes "[Paul Spanner]"; mes "Thank you for using my shop. If you need anything, just let me know."; close; @@ -562,7 +562,7 @@ lhz_in02,282,20,7 script Fulerr 869,{ function script refinemain { disable_items; .@npc_name$ = getarg(0); - set .@features,getarg(1); + .@features = getarg(1); mes "["+ .@npc_name$ +"]"; mes "I'm the Armsmith."; mes "I can refine all kinds of weapons, armor and equipment, so let me"; @@ -570,19 +570,19 @@ function script refinemain { 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; - for(set .@i,1; .@i 10) { mes "["+ .@npc_name$ +"]"; mes "I can't refine this item that many times."; close; } if(.@refinecheck > .@safe) { - set .@refinecheck,.@refinecheck - .@safe; + .@refinecheck = .@refinecheck - .@safe; 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?"; next; @@ -808,7 +778,7 @@ function script refinemain { mes "You said so... So be it."; close; } - set .@fullprice,.@price * .@refinecnt; + .@fullprice = .@price * .@refinecnt; mes "["+ .@npc_name$ +"]"; mes "That will cost you " + .@refinecnt + " " + getitemname(.@material) + " and " + .@fullprice + " Zeny. Is that ok?"; 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."; close; } - set Zeny, Zeny - .@fullprice; + Zeny = Zeny - .@fullprice; delitem .@material,.@refinecnt; while(.@refinecnt){ if (getequipisequiped(.@part) == 0) { @@ -843,17 +813,17 @@ function script refinemain { emotion e_omg; mes "["+ .@npc_name$ +"]"; mes "WAHHHH!!! I'm so sorry... I warned you this could happen..."; - set .@refinecnt,.@refinecnt - 1; + .@refinecnt = .@refinecnt - 1; if(.@refinecnt == 0) close; mes "Here's the unused Zeny and materials back..."; getitem .@material,.@refinecnt; - set .@fullprice,.@refinecnt * .@price; - set Zeny, Zeny + .@fullprice; + .@fullprice = .@refinecnt * .@price; + Zeny = Zeny + .@fullprice; close; } successrefitem .@part; emotion e_no1; - set .@refinecnt,.@refinecnt - 1; + .@refinecnt = .@refinecnt - 1; next; } mes "["+ .@npc_name$ +"]"; @@ -913,12 +883,12 @@ function script phramain { next; switch(select("Phracon - 200 Zeny:Emveretarcon - 1000 Zeny:Ask about other Metals")) { case 1: - set .@material,1010; - set .@price,200; + .@material = 1010; + .@price = 200; break; case 2: - set .@material,1011; - set .@price,1000; + .@material = 1011; + .@price = 1000; break; case 3: mes "["+ .@npc_name$ +"]"; @@ -951,7 +921,7 @@ function script phramain { break; } } - set .@sell,.@input * .@price; + .@sell = .@input * .@price; if (Zeny < .@sell) { mes "["+ .@npc_name$ +"]"; mes "Err..."; @@ -967,7 +937,7 @@ function script phramain { close; } getitem .@material,.@input; - set Zeny, Zeny-.@sell; + Zeny = Zeny-.@sell; mes "["+ .@npc_name$ +"]"; mes "Here you are!"; mes "Thank you for"; @@ -1151,7 +1121,7 @@ sch_gld,340,80,7 script Repairman#sch_gld 86,{ // Equipment Repair Function //============================================================ function script repairmain { - set .@repairprice,5000; + .@repairprice = 5000; .@npc_name$ = getarg(0); mes "["+ .@npc_name$ +"]"; mes "Hey there!"; @@ -1162,14 +1132,14 @@ function script repairmain { next; switch(select("Actually, I do have some items...:None at the moment.")) { case 1: - set .@checkitem,1; + .@checkitem = 1; while (1) { if (getbrokenid(.@checkitem) == 0) { break; } - set .@checkitem,.@checkitem+1; + .@checkitem = .@checkitem+1; } - set .@checkitem,.@checkitem-1; + .@checkitem = .@checkitem-1; if (!.@checkitem) { mes "["+ .@npc_name$ +"]"; mes "Oh wow, this is incredible!"; @@ -1186,7 +1156,7 @@ function script repairmain { mes "" + .@checkitem + " are damaged."; mes "Would you like to repair?"; next; - set .@totalcost,.@repairprice*.@checkitem; + .@totalcost = .@repairprice*.@checkitem; 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?"; 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."; close; } - set .@checkitem2,1; + .@checkitem2 = 1; while (1) { if (getbrokenid(.@checkitem2) == 0) { break; } - set .@checkitem2,.@checkitem2+1; + .@checkitem2 = .@checkitem2+1; } - set .@checkitem2,.@checkitem2-1; + .@checkitem2 = .@checkitem2-1; if (.@checkitem == .@checkitem2) { - set Zeny, Zeny-.@totalcost; + Zeny = Zeny-.@totalcost; while (.@checkitem) { repair(.@checkitem); - set .@checkitem,.@checkitem-1; + .@checkitem = .@checkitem-1; } mes "["+ .@npc_name$ +"]"; mes "Okay! All done. Now, try to be a little more careful. Items have lives too you know."; diff --git a/npc/re/merchants/advanced_refiner.txt b/npc/re/merchants/advanced_refiner.txt index a6ce065a17..f89d76cd94 100644 --- a/npc/re/merchants/advanced_refiner.txt +++ b/npc/re/merchants/advanced_refiner.txt @@ -1,21 +1,12 @@ //===== rAthena Script ======================================= //= Advanced Refiner -//===== By: ================================================== -//= Euphy -//===== Current Version: ===================================== -//= 1.0 -//===== Compatible With: ===================================== -//= rAthena Project //===== Description: ========================================= //= [Official Conversion] //= 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.1 Removed re-roll behavior. [Secret] +//= 1.2 Added db-based material ID [Secret] //============================================================ // Main NPC :: mal_jerun @@ -79,35 +70,32 @@ malangdo,221,174,6 script Holink#mal_cash 559,{ close; } mes "[Holink]"; + // TODO: Price is different to Suhnbi of Payon. Intended? [Secret] + .@material = getequiprefinecost(.@part, REFINE_COST_ENRICHED, REFINE_MATERIAL_ID); switch(getequipweaponlv(.@part)) { default: case 0: // Armor set .@price,15000; - set .@material,7619; //Enriched_Elunium set .@type$,"armor"; mes "You have chosen an armor, meow~"; break; case 1: // Level 1 Weapon set .@price,500; - set .@material,7620; //Enriched_Oridecon set .@type$,"weapon"; mes "A level 1 weapon...?"; break; case 2: // Level 2 Weapon set .@price,2000; - set .@material,7620; //Enriched_Oridecon set .@type$,"weapon"; mes "Meow, a level 2 weapon...?"; break; case 3: // Level 3 Weapon set .@price,20000; - set .@material,7620; //Enriched_Oridecon set .@type$,"weapon"; mes "Meow Meow~~ A level 3 weapon~~"; break; case 4: // Level 4 Weapon set .@price,50000; - set .@material,7620; //Enriched_Oridecon set .@type$,"weapon"; mes "Me-Meow!... A level 4 weapon...!"; 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?~"; close; } - if (getequippercentrefinery(.@part) < 100) { + if (getequippercentrefinery(.@part, true) < 100) { mes "[Holink]"; mes "Meow!!"; if (.@type$ == "armor") @@ -160,7 +148,7 @@ malangdo,221,174,6 script Holink#mal_cash 559,{ } delitem .@material,1; set Zeny, Zeny-.@price; - if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) { + if (getequippercentrefinery(.@part, true) > rand(100)) { successrefitem .@part; mes "[Holink]"; mes "Me~ Me~ Meow! Fun fun refining~"; diff --git a/npc/re/merchants/blessed_refiner.txt b/npc/re/merchants/blessed_refiner.txt index 33d15be544..838b1f04e8 100644 --- a/npc/re/merchants/blessed_refiner.txt +++ b/npc/re/merchants/blessed_refiner.txt @@ -1,11 +1,5 @@ //===== rAthena Script ======================================= //= Blessed Refiner -//===== By: ================================================== -//= Euphy -//===== Current Version: ===================================== -//= 1.0 -//===== Compatible With: ===================================== -//= rAthena Project //===== Description: ========================================= //= [Official Conversion] //= Refiners that use Blessed ores to refine equipment. @@ -13,8 +7,9 @@ //= rate is identical to that for Enriched ores. //= - "Blacksmith Dister" only refines from +6~12. //= NOTE: This NPC is currently disabled on official servers. -//===== Additional Comments: ================================= +//===== Changelog: =========================================== //= 1.0 First version. [Euphy] +//= 1.1 Removed re-roll behavior. [Secret] //============================================================ // Main NPC :: new_smelting612 @@ -141,7 +136,7 @@ set Zeny, Zeny-.@price; mes "[Blacksmith Dister]"; mes "Tac! Tac! Tac!"; - if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) { + if (getequippercentrefinery(.@part, true) > rand(100)) { specialeffect EF_BLESSING; successrefitem .@part; next; diff --git a/npc/re/merchants/hd_refiner.txt b/npc/re/merchants/hd_refiner.txt index 61eaa7d464..64aa698566 100644 --- a/npc/re/merchants/hd_refiner.txt +++ b/npc/re/merchants/hd_refiner.txt @@ -1,11 +1,5 @@ //===== rAthena Script ======================================= //= HD Refiners -//===== By: ================================================== -//= Euphy -//===== Current Version: ===================================== -//= 1.0 -//===== Compatible With: ===================================== -//= rAthena Project //===== Description: ========================================= //= [Official Conversion] //= Refiners that use HD ores to refine equipment. Upon @@ -14,8 +8,9 @@ //= to that for Enriched ores. //= - "Blacksmith Mighty Hammer" only refines from +7~9. //= - "Basta" only refines from +10 and up. -//===== Additional Comments: ================================= +//===== Changelog: =========================================== //= 1.0 First version. [Euphy] +//= 1.1 Removed re-roll behavior. [Secret] //============================================================ // Blacksmith Mighty Hammer (+7~9) :: cash_smelting79 @@ -78,20 +73,10 @@ mes "I only handle items with refine levels from +7 to +9."; 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 "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?"; @@ -122,7 +107,7 @@ set Zeny, Zeny-.@price; mes "[Blacksmith Mighty Hammer]"; mes "Tac! Tac! Tac!"; - if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) { + if (getequippercentrefinery(.@part, true) > rand(100)) { successrefitem .@part; next; 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~"; close; } + .@price = getequiprefinecost(.@part, REFINE_COST_OVER10_HD, REFINE_ZENY_COST); + .@material = getequiprefinecost(.@part, REFINE_COST_OVER10_HD, REFINE_MATERIAL_ID); switch(getequipweaponlv(.@part)) { default: case 0: - set .@price,100000; - set .@material,6225; //HD_Carnium set .@type$,"armor"; break; case 1: case 2: case 3: case 4: - set .@price,100000; - set .@material,6226; //HD_Bradium set .@type$,"weapon"; break; } mes "[Basta]"; 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?"; next; 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..."; close; } - if (getequippercentrefinery(.@part) < 100) { + if (getequippercentrefinery(.@part, true) < 100) { mes "[Basta]"; mes "This "+.@type$+" has already been refined pretty high."; 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; set Zeny, Zeny-.@price; mes "Pow! Pow! Pow! Pow!"; - if (getequippercentrefinery(.@part) > rand(100) || getequippercentrefinery(.@part) > rand(100)) { + if (getequippercentrefinery(.@part, true) > rand(100)) { successrefitem .@part; next; emotion e_no1; diff --git a/npc/re/merchants/refine.txt b/npc/re/merchants/refine.txt index ad38d5aab1..5491ef3731 100644 --- a/npc/re/merchants/refine.txt +++ b/npc/re/merchants/refine.txt @@ -58,19 +58,19 @@ function script refinenew { 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; - for(set .@i,1; .@i<=10; set .@i,.@i+1) { + for(.@i = 1; .@i<=10; ++.@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) { mes "["+ .@npc_name$ +"]"; mes "I don't think I can refine any items you have..."; close; } - set .@part, .@indices[ select(.@menu$) ]; + .@part = .@indices[ select(.@menu$) ]; if (!getequipisequiped(.@part)) { //custom check mes "["+ .@npc_name$ +"]"; @@ -98,27 +98,24 @@ function script refinenew { mes "refined as it gets!"; 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)) { - 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 { - 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?"; next; if(select("Yes:No") == 2){ @@ -154,7 +151,7 @@ function script refinenew { mes "Please come back when you have them."; close; } - set Zeny,Zeny - .@price; + Zeny = Zeny - .@price; delitem .@material,1; // anti-hack @@ -216,26 +213,26 @@ function script refinenew { mes "["+ .@npc_name$ +"]"; mes "I can refine this to the safe limit or a desired number of times. It's your choice."; 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 - set .@menu2,2; + .@menu2 = 2; switch(.@menu2){ case 1: - set .@refinecnt,.@safe - getequiprefinerycnt(.@part); + .@refinecnt = .@safe - getequiprefinerycnt(.@part); break; case 2: mes "["+ .@npc_name$ +"]"; mes "How many times would you like me to refine your item?"; next; input .@refinecnt; - set .@refinecheck,.@refinecnt + getequiprefinerycnt(.@part); + .@refinecheck = .@refinecnt + getequiprefinerycnt(.@part); if (.@refinecnt < 1 || .@refinecheck > 20) { mes "["+ .@npc_name$ +"]"; mes "I can't refine this item that many times."; close; } if (.@refinecheck > .@safe) { - set .@refinecheck,.@refinecheck - .@safe; + .@refinecheck = .@refinecheck - .@safe; 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?"; next; @@ -251,7 +248,7 @@ function script refinenew { mes "You said so... So be it."; close; } - set .@fullprice,.@price * .@refinecnt; + .@fullprice = .@price * .@refinecnt; mes "["+ .@npc_name$ +"]"; mes "That will cost you " + .@refinecnt + " " + getitemname(.@material) + " and " + .@fullprice + " Zeny. Is that ok?"; next; @@ -266,7 +263,7 @@ function script refinenew { mes "Please come back when you have them."; close; } - set Zeny,Zeny - .@fullprice; + Zeny = Zeny - .@fullprice; delitem .@material,.@refinecnt; while(.@refinecnt){ if (getequipisequiped(.@part) == 0) { @@ -284,7 +281,7 @@ function script refinenew { if (getequippercentrefinery(.@part) > rand(100)) { mes "Clang! Clang! Clang! Clang!"; successrefitem .@part; - set .@refinecnt,.@refinecnt - 1; + .@refinecnt = .@refinecnt - 1; next; } else { if (rand(100) < 80) { @@ -362,7 +359,7 @@ function script refinenew { } if (countitem(.@i[0]) >= .@i[1] && Zeny >= 50000) { delitem .@i[0],.@i[1]; - set Zeny, Zeny - 50000; + Zeny = Zeny - 50000; getitem .@i[2],1; mes "[Austri]"; if (.@i[0] == 6090) { @@ -396,9 +393,9 @@ malangdo,224,172,6 script Clink#mal_normal 544,{ mes "Yes!!! You!! You want to refine?"; 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; - 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)) { mes "[Clink]"; switch(.@part) { @@ -441,38 +438,32 @@ malangdo,224,172,6 script Clink#mal_normal 544,{ mes "Perfect refining. Did I do this for you?"; close; } + + .@price = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_ZENY_COST); + .@material = getequiprefinecost(.@part, REFINE_COST_NORMAL, REFINE_MATERIAL_ID); + mes "[Clink]"; switch(getequipweaponlv(.@part)) { default: case 0: // Armor - set .@price,2000; - set .@material,985; //Elunium - set .@type$,"armor"; + .@type$ = "armor"; mes "Hmm, an armor refine? Someone like you?"; break; case 1: // Level 1 Weapon - set .@price,50; - set .@material,1010; //Phracon - set .@type$,"weapon"; + .@type$ = "weapon"; mes "A level 1 weapon?"; mes "Urr... Annoying... Okay, let's try..."; break; case 2: // Level 2 Weapon - set .@price,200; - set .@material,1011; //Emveretarcon - set .@type$,"weapon"; + .@type$ = "weapon"; mes "A level 2 weapon?"; break; case 3: // Level 3 Weapon - set .@price,20000; - set .@material,984; //Oridecon - set .@type$,"weapon"; + .@type$ = "weapon"; mes "Woot!! A level 3 weapon? Impressive~"; break; case 4: // Level 4 Weapon - set .@price,50000; - set .@material,984; //Oridecon - set .@type$,"weapon"; + .@type$ = "weapon"; mes "Wow!... A level 4 weapon~!!"; break; } @@ -510,7 +501,7 @@ malangdo,224,172,6 script Clink#mal_normal 544,{ close; } delitem .@material,1; - set Zeny, Zeny-.@price; + Zeny = Zeny-.@price; if (getequippercentrefinery(.@part) <= rand(100)) { failedrefitem .@part; mes "[Clink]"; diff --git a/npc/re/merchants/shadow_refiner.txt b/npc/re/merchants/shadow_refiner.txt new file mode 100644 index 0000000000..603ff2dd23 --- /dev/null +++ b/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 diff --git a/npc/re/scripts_athena.conf b/npc/re/scripts_athena.conf index 3013b7871a..13700f6799 100644 --- a/npc/re/scripts_athena.conf +++ b/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/cash_trader-idRO.txt npc: npc/re/merchants/te_merchant.txt +npc: npc/re/merchants/shadow_refiner.txt // --------------------------- Others --------------------------- npc: npc/re/other/achievements.txt diff --git a/src/common/yamlwrapper.cpp b/src/common/yamlwrapper.cpp index 33ab29f1b4..e6b5677220 100644 --- a/src/common/yamlwrapper.cpp +++ b/src/common/yamlwrapper.cpp @@ -28,7 +28,12 @@ extern "C" { yamlwrapper::yamlwrapper(YAML::Node node) { - this->root = node; + try { + this->root = node; + } + catch (std::exception) { + //ignore + } } yamliterator::yamliterator(YAML::Node sequence_) { @@ -45,8 +50,6 @@ yamlwrapper* yaml_load_file(const char* file_name) { try { node = YAML::LoadFile(file_name); - if (!node.IsDefined() || node.IsNull()) - return NULL; } catch (YAML::ParserException &e) { ShowError("YAML Exception Caught: %s\n", e.what()); return NULL; @@ -113,6 +116,22 @@ int64 yaml_get_int64(yamlwrapper* wrapper, const char* key) { return yaml_get_value(wrapper, key); } +int yaml_get_uint(yamlwrapper* wrapper, const char* key) { + return yaml_get_value(wrapper, key); +} + +int16 yaml_get_uint16(yamlwrapper* wrapper, const char* key) { + return yaml_get_value(wrapper, key); +} + +int32 yaml_get_uint32(yamlwrapper* wrapper, const char* key) { + return yaml_get_value(wrapper, key); +} + +int64 yaml_get_uint64(yamlwrapper* wrapper, const char* key) { + return yaml_get_value(wrapper, key); +} + bool yaml_get_boolean(yamlwrapper* wrapper, const char* key) { return yaml_get_value(wrapper, key); } @@ -157,6 +176,22 @@ int64 yaml_as_int64(yamlwrapper* wrapper) { return yaml_as_value(wrapper); } +int yaml_as_uint(yamlwrapper* wrapper) { + return yaml_as_value(wrapper); +} + +int16 yaml_as_uint16(yamlwrapper* wrapper) { + return yaml_as_value(wrapper); +} + +int32 yaml_as_uint32(yamlwrapper* wrapper) { + return yaml_as_value(wrapper); +} + +int64 yaml_as_uint64(yamlwrapper* wrapper) { + return yaml_as_value(wrapper); +} + bool yaml_as_boolean(yamlwrapper* wrapper) { return yaml_as_value(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))); } +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) { return new yamliterator(wrapper->root); } diff --git a/src/common/yamlwrapper.h b/src/common/yamlwrapper.h index d00c084d17..3a01a75945 100644 --- a/src/common/yamlwrapper.h +++ b/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); int32 yaml_get_int32(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); char* yaml_as_c_string(yamlwrapper* wrapper); int yaml_as_int(yamlwrapper* wrapper); int16 yaml_as_int16(yamlwrapper* wrapper); int32 yaml_as_int32(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_node_is_defined(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); bool yaml_iterator_is_valid(yamliterator* it); diff --git a/src/map/battle.c b/src/map/battle.c index e2d616bd9d..f279ad5656 100644 --- a/src/map/battle.c +++ b/src/map/battle.c @@ -8430,6 +8430,7 @@ static const struct _battle_data { { "guild_alliance_onlygm", &battle_config.guild_alliance_onlygm, 0, 0, 1, }, { "feature.achievement", &battle_config.feature_achievement, 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" }; diff --git a/src/map/battle.h b/src/map/battle.h index 37c86dfbb6..91729d4a40 100644 --- a/src/map/battle.h +++ b/src/map/battle.h @@ -632,6 +632,7 @@ extern struct Battle_Config int guild_alliance_onlygm; int feature_achievement; int allow_bound_sell; + int event_refine_chance; #include "../custom/battle_config_struct.inc" } battle_config; diff --git a/src/map/map-server.vcxproj b/src/map/map-server.vcxproj index 0c681feebe..5fd8020415 100644 --- a/src/map/map-server.vcxproj +++ b/src/map/map-server.vcxproj @@ -347,7 +347,7 @@ - + diff --git a/src/map/script.cpp b/src/map/script.cpp index 9e7eb61893..73915808dc 100644 --- a/src/map/script.cpp +++ b/src/map/script.cpp @@ -8883,24 +8883,31 @@ BUILDIN_FUNC(getequipweaponlv) * return (npc) * x : refine chance * 0 : false (max refine level or unequip..) - * getequippercentrefinery({,}) + * getequippercentrefinery({,,}) *------------------------------------------*/ BUILDIN_FUNC(getequippercentrefinery) { int i = -1,num; + bool enriched = false; TBL_PC *sd; 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); return SCRIPT_CMD_FAILURE; } if (equip_index_check(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 script_pushint(st,0); @@ -23555,6 +23562,39 @@ BUILDIN_FUNC(achievementupdate) { return SCRIPT_CMD_SUCCESS; } +/** + * Get an equipment's refine cost + * getequiprefinecost(,,{,}) + */ +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" // 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(achievementupdate,"iii?"), + + BUILDIN_DEF(getequiprefinecost,"iii?"), #include "../custom/script_def.inc" {NULL,NULL,NULL}, diff --git a/src/map/script_constants.h b/src/map/script_constants.h index 408f3ff646..7347570965 100644 --- a/src/map/script_constants.h +++ b/src/map/script_constants.h @@ -3864,6 +3864,18 @@ export_constant(ACHIEVEINFO_SCORE); 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_constant2 #undef export_parameter diff --git a/src/map/skill.c b/src/map/skill.c index 42d19eef9a..6bf69ade4c 100755 --- a/src/map/skill.c +++ b/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]); 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 ) per += 10; else diff --git a/src/map/status.c b/src/map/status.c index 090807c561..4f99d3e9ee 100644 --- a/src/map/status.c +++ b/src/map/status.c @@ -10,6 +10,7 @@ #include "../common/utils.h" #include "../common/ers.h" #include "../common/strlib.h" +#include "../common/yamlwrapper.h" #include "battle.h" #include "itemdb.h" @@ -21,6 +22,7 @@ #include "homunculus.h" #include "mercenary.h" #include "elemental.h" +#include "script.h" #include #include @@ -36,9 +38,10 @@ enum e_regen { // Bonus values and upgrade chances for refining equipment 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 randombonus_max[MAX_REFINE]; /// Cumulative maximum random bonus damage + struct refine_cost cost[REFINE_COST_MAX]; } refine_info[REFINE_TYPE_MAX]; 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 * @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) 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; - - current = atoi(fields[0]); - - if (current < 0 || current >= REFINE_TYPE_MAX) +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; - bonus_per_level = atoi(fields[1]); - random_bonus_start_level = atoi(fields[2]); - random_bonus = atoi(fields[3]); + 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"); - for(i = 0; i < MAX_REFINE; i++) { - char* delim; + 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 (!(delim = strchr(fields[4+i], ':'))) - return false; + 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; + } - *delim = '\0'; + 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"); - refine_info[current].chance[i] = atoi(fields[4+i]); + refine_info[refine_info_index].cost[idx].nameid = material; + refine_info[refine_info_index].cost[idx].zeny = price; - if (i >= random_bonus_start_level - 1) - refine_info[current].randombonus_max[i] = random_bonus * (i - random_bonus_start_level + 2); - - 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]; + aFree(refine_cost_const); + yaml_destroy_wrapper(type); + } } + yaml_destroy_wrapper(costs); + yaml_iterator_destroy(it); + + yamlwrapper* rates = yaml_get_subnode(wrapper, "Rates"); + it = yaml_get_iterator(rates); + + 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; + + if (refine_level >= MAX_REFINE) { + yaml_destroy_wrapper(level); + continue; + } + + 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"); + + 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; } +/** + * 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 * Function stores information in the attr_fix_table @@ -14331,15 +14424,17 @@ int status_readdb(void) for(i=0;i