Jump to content
New account registrations are disabed. This website is now an archive. Read more here.

Recommended Posts

Blacksmith Shop

Authors: ForeverZer0

Version: 2.0

Type: Custom Shop


Introduction

 

Will allow you to create a complete blacksmith system. The player will be able to forge equipment/items by using combinations of weapons, armors, and items in their possession. Also includes a "Enchantment" feature that will allow the player to use special items to add stats, elemental efficiencies, and state altering to weapons and armor. The extraction feature allows for the breaking down of current equipment and items into other ones.


Features

 

  • Completely configurable item requirements for every item.
  • Configurable blacksmith 'fees' for every weapon/armor/item
  • Can use as many different items, with different quantities for each piece of equipment.
  • Variable "skill" levels for Blacksmith shops, which lets you decide which features the Blacksmith can do.
  • Only have to use a single script call to for the Blacksmith's shop.
  • Can recycle old equipment by extracting items from weapons/armors


Screenshots

 

Script

 

Blacksmith2.png

 

 

Blacksmith3.png

 

 

Blacksmith1.png

 

 

Configuration Application

 

BS_APP_FORGE.png

 

 

BS_APP_MISC.png

 

 

BS_APP_SCRIPT.png

 


Configuration Application

 

I have written a small application that can be used to make your configurations with a user-friendly GUI instead of typing out confusing arrays in the script. If you choose to download the application, you need not get anything else. All the scripts and the demo can be output from the application. Due to the increased file size and possible instability of embedding Ruby or IronRuby in the application to read your game's Marshaled .rxdata files, I left it out, but have included a one-time script to run in your game that will output a file to use with the program so that you need not copy your database into it. Here are the easy instructions:

 

  • Open application and go to the "Miscellaneous" tab.
  • Click the button to for the BlacksmithCache script, and copy the text anywhere in your script editor.
  • Run the game once, a file will be output.
  • Drag and Drop the file onto the anvil in the bottom-right corner of the application and you are done.

 

The application requires Microsoft's .NET 2.0 Framework or higher to run. If you do not have it and cannot run the application, you can download it here.

 

Blacksmith Configuration 1.1 (1.05 MB)

 


Demo

 

Demo Link


Script

 

Click here for the script.

 

#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# Blacksmith Shop
# Author: ForeverZer0
# Type: Custom Shop System
# Date: 4.23.2011
# Version: v.2.0
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
#
# Explanation:
#   Will allow you to create a complete blacksmithing system. The player will be
#   able to forge equipment/items by using combinations of weapons, armors, and
#   items in their possession. Also includes a "Enchantment" feature that will
#   allow the player to use special items to add stats, elementel efficiencies,
#   and state altering to weapons and armor. The extraction feature allows for
#   the breaking down of current equipment and items into other ones.
#
# Features:
#   - Completely configurable item requirements for every item.
#   - Configurable blacksmith 'fees' for every weapon/armor
#   - Can use as many different items, with different quantities for each piece
#     of equipment.
#   - Variable "skill" levels for Blacksmith shops, which lets you decide
#     which features the Blacksmith can do.
#   - Only have to use a single script call to for the Blacksmith's shop.
#   - Can recycle old equipment by extracting items from weapons/armors/items.
#
# Instructions:
#   - Place script below debug and above main
#   - Configuration and instructions for each are below
#   - To call blacksmith shop, this script call:
#
#         w = [ WEAPON_IDS ]    (Use as many as needed, seperate with commas)
#         a = [ ARMOR_IDS ] 
#         i = [ ITEM_IDS ]
#         $scene = Scene_BlackSmith.new(w, a, i)
#
#   - All IDs that you included in the script call for items will be be 
#     available for forging in that shop.
#   - You can also include a fourth argument to the call to set the Blacksmith's
#     "skill level". Just make an array of true/false elemenets, set up like
#     this:
#
#             [CAN_FORGE?, CAN_EXTRACT?, CAN_ENCHANT?]
#
#     If you are not using the Enchant feature, omit the last option. Just make
#     sure that if you do include this argument that the array has a value for 
#     each skill.
#
# Credits/Thanks:
#   - ForeverZer0, for the script.
#   - RoseSkye, huge thanks for beta-testing and demo map.
#
# Author's Notes:
#   Please report any bugs/issues at www.chaos-project.com
#
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:

module Blacksmith

#===============================================================================
#                          BEGIN CONFIGURATION
#===============================================================================

 FORGE_SE = ['006-System06', 80, 100]
 # SE played when an item is forged. ['FILENAME', VOLUME, PITCH]
 EXTRACT_SE = ['020-Teleport03', 80, 100]
 # SE played when an item extraction is performed. ['FILENAME', VOLUME, PITCH]
 ENCHANT_SE = ['020-Teleport03', 80, 100]
 # SE played when an item enchantment is performed. ['FILENAME', VOLUME, PITCH]

 USE_ENCHANTMENTS = true
 # Set to true to enable the "Enchant" feature of the system.

 NO_ENCHANT_WEAPONS = []
 NO_ENCHANT_ARMORS = []
 # Include IDs of any equipment that cannot be enchanted in the respective
 # arrays, seperating by commas. Ignore these if not using enchant feature.

 # Define the colors used for the text in the Blacksmith shop.
 PLUS_COLOR = Color.new(128, 255, 128)
 MINUS_COLOR = Color.new(255, 128, 128)

 MAP_BACK = true
 # Set to true if you would like slightly opaque windows with the map showing
 # through.

 #-----------------------------------------------------------------------------
 # FORGE DATABASE
 #-----------------------------------------------------------------------------
 # Define the materials used for each weapon/armor/item that can be forged and
 # extracted. They configuration is slightly different than what it was in the
 # first version of the script. You can seperately define materials that are 
 # given during extraction if you like, or ignore it and it will simply return
 # the same materials it takes to forge them. It works like this:
 #
 # STEP 1:
 #   Create a new "case" in the appropriate method below for the type of item
 #   you are trying to define. There are three of them, one each for weapons, 
 #   armors, and items. Just use this syntax:
 #       
 #          when DATABASE_ID then []
 #
 # STEP 2:
 #   Now you can begin to add materials to forge the item. Each material has
 #   an number which defines what type of item is is. Here is the "key":
 #
 #       0 = Weapon
 #       1 = Armor
 #       2 = Item
 # 
 #   To define a material for an item, you simply create a three element array 
 #   using this format: 
 #                       [iTEM_TYPE, DATABASE_ID, QUANTITY]
 #
 #   ...and add it the appropriate empty array in the case statement you made
 #   in Step 1. You can add as many different items as you please to forge an
 #   weapon/armor/item, simply seperate the material arrays with commas. See 
 #   below for a few examples.
 #-----------------------------------------------------------------------------
 def self.weapon_forges(id)
   return case id
   when 1 then [[2, 33, 3], [2, 42, 1]]            # Bronze Sword
   when 2 then [[0, 1, 1], [2, 34, 2], [2, 42, 1]] # Iron Sword
   when 3 then [[0, 2, 1], [2, 34, 10]]            # Steel Sword
   when 4 then [[0, 2, 2], [2, 35, 3], [2, 41, 1]] # Mythril Sword
   when 5 then [[2, 33, 5], [2, 43, 1]]            # Bronze Spear
   when 6 then [[2, 34, 4], [0, 5, 1], [2, 43, 1]] # Iron Spear
   when 7 then [[0, 6, 2], [2, 34, 2], [2, 43, 1]] # Steel Spear
   when 8 then [[2, 35, 8], [2, 43, 1]]            # Mythril Spear
   end
 end

 def self.armor_forges(id)
   return case id
   when 1 then []
   when 2 then []
   when 3 then []
   when 4 then []
   when 5 then []
   end
 end

 def self.item_forges(id)
   return case id
   when 2 then [[2, 1, 5]]
   when 3 then [[2, 2, 5]]
   when 5 then [[2, 4, 5]]
   when 6 then [[2, 5, 5]]
   end
 end

 #-----------------------------------------------------------------------------
 # EXTRACT DATABASE
 #-----------------------------------------------------------------------------
 # Here you can define the items received when a specific item is extracted.
 # It can be setup the same as way as above. Items left undefined will return
 # the same items that are required to forge it. You can define an item with an
 # empty array to have it return no items, though it can still return gold.
 #-----------------------------------------------------------------------------
 def self.weapon_extractions(id)
   return case id
   when 1 then [[2, 33, 1], [2, 42, 1]]
   when 2 then [[2, 34, 1], [2, 41, 1]]
   when 3 then [[2, 34, 2], [0, 1, 1]]
   when 4 then [[2, 33, 5], [2, 34, 5], [2, 41, 1]]
   when 5 then [[2, 33, 1], [2, 43, 1]]
   when 6 then [[2, 34, 1], [2, 43, 1]]
   when 7 then [[2, 34, 2], [0, 5, 1]]
   when 8 then [[2, 33, 5], [2, 34, 5], [2, 43, 1]]
   else
     self.weapon_forges(id)
   end

 end

 def self.armor_extractions(id)
   return case id
   when 1 then []
   when 2 then []
   when 3 then []
   when 4 then []
   when 5 then []
   else
     self.weapon_forges(id)
   end
 end

 def self.item_extractions(id)
   return case id
   when 1 then []                     # Potion
   when 2 then [[2, 1, 2]]            # High Potion
   when 3 then [[2, 2, 2], [2, 1, 2]] # Full Potion
   when 4 then []                     # Perfume
   when 5 then [[2, 4, 2]]            # High Perfume
   when 6 then [[2, 4, 2], [2, 5, 2]] # Full Perfume
   else
     self.item_forges(id)
   end
 end

 #-----------------------------------------------------------------------------
 # GOLD DATABASE
 #-----------------------------------------------------------------------------
 # Here you can define the amount of gold that is required to forge an item, 
 # and the amount that is given if extracted. There are three methods, one each
 # for weapons, armors, and items. Simply follow this pattern for each 
 # category:
 #
 #     when DATABASE_ID then [FORGE_PRICE, EXTRACT_GOLD,]
 #-----------------------------------------------------------------------------
 def self.weapon_gold(id)
   return case id
   when 1 then [200, 50]
   when 2 then [450, 225]
   when 3 then [1000, 525]
   when 4 then [1200, 200]
   when 5 then [300, 75]
   when 6 then [550, 275]
   when 7 then [1200, 600]
   when 8 then [1500, 650]
   else
     [0, 0]
   end
 end

 def self.armor_gold(id)
   return case id
   when 1 then []
   when 2 then []
   when 3 then []
   when 4 then []
   when 5 then []
   else
     [0, 0]
   end
 end

 def self.item_gold(id)
   return case id
   when 1 then [100, 0]
   when 2 then [50, 25]
   when 3 then [250, 25]
   when 4 then [100, 0]
   when 5 then [50, 25]
   when 6 then [250, 25]
   else
     [0, 0]
   end
 end

 #-----------------------------------------------------------------------------
 # ENCHANT DATABASE
 #-----------------------------------------------------------------------------

 #-----------------------------------------------------------------------------
 # Here you can define what items will alter stats when used to enchant with.
 # You need to create a two element array, and add it to the respective array
 # below that corresponds with the desired item.
 #
 # ex.
 #     when ITEM_ID then [[KEYWORD, VALUE], [KEYWORD, VALUE]]
 #
 #     KEYWORD: See below for a list of possible keywords. Stat changes that
 #              can affect only weapons will have no effect on armors, and
 #              vice-versa.
 #     VALUE : The amount by which to change the stat. Negative values will
 #             lower the stat.
 #-----------------------------------------------------------------------------
 # KEYWORDS:
 #
 #   'ATK' (Weapon Only)           'DEX'               'PDEF'
 #   'EVA' (Armor Only)            'AGI'               'MDEF'
 #   'STR'                         'INT'    
 #
 #   ** Keywords have to be written EXACTLY as they appear.
 #-----------------------------------------------------------------------------
 def self.enchant_stats(item_id)
   return case item_id
   when 39 then [['AGI', 5]]              # Carrot
   when 40 then [['STR', 15], ['ATK', 5]] # Behemoth Juice
   end
 end

 #-----------------------------------------------------------------------------
 # Define state altering enchantments. 
 #
 # ex.
 #     when ITEM_ID then [[VALUE, STATE_ID], [VALUE, STATE_ID]]
 #
 #     VALUE: One of three different values to represent states efficiency.
 #              -1 = Minus state (Does nothing on armors)
 #               0 = Neutral
 #               1 = Plus state 
 #     STATE_ID: The ID in the database of the state.
 #-----------------------------------------------------------------------------
 def self.enchant_states(item_id)
   return case item_id
   when 38 then [[1, 2], [1, 4], [1, 6]] # Chaos Orb
   end
 end

 #-----------------------------------------------------------------------------
 # Define element altering enchantments. 
 #
 # ex.
 #     when ITEM_ID then [[VALUE, ELEMENT_ID], [VALUE, ELEMENT_ID]]
 #
 #     VALUE: One of two different values to represent element efficiency.
 #              true  = Uses element
 #              false = Doesn't use element (Negates element if present)
 #     ELEMENT_ID: The ID in the database of the element.
 #-----------------------------------------------------------------------------
 def self.enchant_elements(item_id)
   return case item_id
   when 36 then [[true, 3], [false, 5]] # Amethyst
   when 37 then [[true, 1]]             # Ruby ;)
   end
 end  

 #-----------------------------------------------------------------------------
 # Define the amount of gold it takes to enchant a weapon or armor with the
 # item.
 #-----------------------------------------------------------------------------
 def self.enchant_gold(item_id)
   return case item_id
   when 36 then 1500
   when 37 then 1100
   when 38 then 1337
   when 39 then 250
   when 40 then 7500
   else
     0
   end
 end

#===============================================================================
#                              END CONFIGURATION
#===============================================================================

 def self.materials?(type, id)
   # Get the required materials for the item
   materials = case type
   when 0 then [self.weapon_forges(id), self.weapon_gold(id)]
   when 1 then [self.armor_forges(id), self.armor_gold(id)]
   when 2 then [self.item_forges(id), self.item_gold(id)]
   end
   materials[0] = [] if materials[0] == nil
   # Check gold, skipping item check if there is not enough.
   if $game_party.gold >= materials[1][0] 
     # Iterate all required materials, making sure enough are in inventory.
     materials[0].each {|item|
       # Branch by the type of the item.
       result = case item[0]
       when 0 then ($game_party.weapon_number(item[1]) >= item[2])
       when 1 then ($game_party.armor_number(item[1]) >= item[2])
       when 2 then ($game_party.item_number(item[1]) >= item[2])
       end
       # End iteration and return false immidiately if missing required item.
       return false unless result
     }
     return true
   end
   return false
 end
 #-----------------------------------------------------------------------------
 def self.update_database(item)
   # Open the Weapons or Armors .rxdata file and add the created item.
   begin
     if item.is_a?(RPG::Weapon)
       file, data = 'Data/Weapons.rxdata', $data_weapons
     elsif item.is_a?(RPG::Armor)
       file, data = 'Data/Armors.rxdata', $data_armors
     else
       return
     end
     data[item.id] = item
     file = File.open(file, 'wb')
     Marshal.dump(data, file)
     file.close
   rescue
     print "Could not add #{item.name} to Database."
   end
 end
 #-----------------------------------------------------------------------------
 def self.create_item(base_item, enchant_item)
   base = base_item.clone
   # Do to clone only making shallow copies, it is necessary to also create
   # seperate clones of the element and state sets, otherwise the original
   # is affected too.
   if base_item.is_a?(RPG::Weapon)
     elem_set = base_item.element_set.clone
     plus_state_set = base_item.plus_state_set.clone
     minus_state_set = base_item.minus_state_set.clone
   else
     guard_elem_set = base_item.guard_element_set.clone
     guard_state_set = base_item.guard_state_set.clone
   end
   # Gather the enchantment data.
   stats = self.enchant_stats(enchant_item.id)
   states = self.enchant_states(enchant_item.id)
   elements = self.enchant_elements(enchant_item.id)
   # Iterate through stats
   if stats != nil
     stats.each {|stat|
       case stat[0]
       when 'ATK'
         if base.is_a?(RPG::Weapon)
           base.atk += stat[1] 
         end
       when 'EVA'
         if base.is?(RPG::Armor)
           base.eva += stat[1] 
         end
       when 'STR' then base.str_plus += stat[1]
       when 'DEX' then base.dex_plus += stat[1]
       when 'AGI' then base.agi_plus += stat[1]
       when 'INT' then base.int_plus += stat[1]
       when 'PDEF' then base.pdef_plus += stat[1]
       when 'MDEF' then base.mdef_plus += stat[1]
       end
     }
   end
   # Iterate through states
   if states != nil
     states.each {|state|
       id = state[1]
       if base.is_a?(RPG::Weapon)
         case state[0]
         when -1 
           minus_state_set.push(id) unless minus_state_set.include?(id)
           plus_state_set -= [id]
         when 0
           minus_state_set -= [id]
           plus_state_set -= [id]
         when 1
           plus_state_set.push(id) unless plus_state_set.include?(id)
           minus_state_set -= [id]
         end
       elsif base.is_a?(RPG::Armor)
         if state[0] == 0
           guard_state_set -= [id]
         elsif state[0] == 1
           guard_state_set.push(id) unless guard_state_set.inlcude?(id) 
         end
       end
     }
   end
   # Iterate through elements
   if elements != nil
     elements.each {|element|
       id = element[1]
       if base.is_a?(RPG::Weapon)
         if element[0] && !elem_set.include?(id)
           elem_set.push(id)
         else
           elem_set -= [id]
         end
       elsif base.is_a?(RPG::Armor)
         if element[0] && !guard_elem_set.include?(id)
           guard_elem_set.push(id)
         else
           guard_elem_set -= [id]
         end
       end
     }
   end
   # Give the weapon a new ID, remove the old item, and add the new one.
   if base.is_a?(RPG::Weapon)
     $game_party.lose_weapon(base_item.id, 1)
     base.id = $data_weapons.size
     base.element_set = elem_set
     base.plus_state_set = plus_state_set
     base.minus_state_set = minus_state_set
     $data_weapons[base.id] = base
     $game_party.gain_weapon(base.id, 1)
   elsif base.is_a?(RPG::Armor)
     $game_party.lose_armor(base_item.id, 1)
     base.id = $data_armors.size
     base.guard_element_set = guard_elem_set
     base.guard_state_set = guard_state_set
     $data_armors[base.id] = base
     $game_party.gain_armor(base.id, 1)
   end
   # Add new item to class equipment
   self.update_class_equipment(base_item, base)
   # Save the new item to the database.
   self.update_database(base)
 end
 #-----------------------------------------------------------------------------
 def self.update_class_equipment(old, new)
   # Adds the created item to class equipment that could equip the original
   $data_classes.each_index {|i|
     next if $data_classes[i] == nil
     if old.is_a?(RPG::Weapon) && $data_classes[i].weapon_set.include?(old.id)
       $data_classes[i].weapon_set.push(new.id)
     elsif old.is_a?(RPG::Armor) && $data_classes[i].armor_set.include?(old.id)
       $data_classes[i].armor_set.push(new.id)
     end
   }
   # Marshal the new data.
   begin
     file = File.open('Data/Classes.rxdata', 'wb')
     Marshal.dump($data_classes, file)
     file.close
   rescue
     print "Could not update RPG::Class database."
   end
 end
end


 $blacksmith = 2.0

#===============================================================================
# ** Window_BlacksmithCommand
#===============================================================================

class Window_BlacksmithCommand < Window_Selectable

 def initialize(level)
   super(0, 64, 480, 64)
   @level = level
   if Blacksmith::USE_ENCHANTMENTS
     @item_max = @column_max = 4
     @commands = ['Forge', 'Extract', 'Enchant', 'Exit']
   else
     @item_max = @column_max = 3
     @commands = ['Forge', 'Extract', 'Exit']
   end
   self.contents = Bitmap.new(self.width - 32, self.height - 32)
   refresh
   self.index = 0
 end
 #-----------------------------------------------------------------------------
 def refresh
   self.contents.clear
   (0...@item_max).each {|i| draw_item(i) }
 end
 #-----------------------------------------------------------------------------
 def draw_item(index)
   w = self.width / @item_max
   self.contents.font.color = @level[index] ? normal_color : disabled_color
   self.contents.draw_text(4 + (w * index), 0, w, 32, @commands[index])
 end
end

#===============================================================================
# ** Window_BlacksmithForge
#===============================================================================

class Window_BlacksmithForge < Window_Selectable

 def initialize(shop_goods)
   super(0, 128, 368, 352) 
   # Initialize window and create instance variable to store available goods.
   @shop_goods = shop_goods
   self.active = self.visible = false
   refresh
   self.index = 0
 end
 #-----------------------------------------------------------------------------
 def item
   return @data[self.index]
 end
 #-----------------------------------------------------------------------------
 def refresh(enchanting = false)
   # Dispose bitmap and set to nil if not already.
   if self.contents != nil 
     self.contents = self.contents.dispose
   end
   # Set flag for enchanting
   @enchanting = enchanting
   # Create array of equipment, depending on flag
   if @enchanting
     @data = []
     # Add weapons
     ($data_weapons - [nil]).each {|weapon| 
       if $game_party.weapon_number(weapon.id) > 0 && 
           !Blacksmith::NO_ENCHANT_WEAPONS.include?(weapon.id)
         @data.push(weapon)
       end
     }
     # Add Armor
     ($data_armors - [nil]).each {|armor| 
       if $game_party.armor_number(armor.id) > 0 && 
           !Blacksmith::NO_ENCHANT_ARMORS.include?(armor.id)
         @data.push(armor)
       end
     }
   else
     @data = @shop_goods
   end
   # Create a new bitmap, sized for available items
   @item_max = @data.size
   if @item_max > 0
     self.contents = Bitmap.new(width - 32, row_max * 32)
     (0...@item_max).each {|i| draw_item(i) }
   end
 end
 #-----------------------------------------------------------------------------
 def draw_item(index)
   item = @data[index]
   # Set a few local variables depending on the type of item.
   case item
   when RPG::Weapon
     quantity = $game_party.weapon_number(item.id)
     price, type = Blacksmith.weapon_gold(item.id)[0], 0
   when RPG::Armor
     quantity = $game_party.armor_number(item.id)
     price, type = Blacksmith.armor_gold(item.id)[0], 1
   when RPG::Item
     quantity = $game_party.item_number(item.id)
     price, type = Blacksmith.item_gold(item.id)[0], 2
   end
   # Don't check material requirments for forging wjen enchanting
   result = @enchanting ? true : Blacksmith.materials?(type, item.id)
   # Determine the color to use for drawing the item name.
   if quantity < 99 && result
     self.contents.font.color = normal_color
   else
     self.contents.font.color = disabled_color
   end
   # Draw the item name, icon, and price.
   x, y = 4, index * 32
   rect = Rect.new(x, y, self.width - 32, 32)
   self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
   bitmap = RPG::Cache.icon(item.icon_name)
   opacity = self.contents.font.color == normal_color ? 255 : 128
   self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
   self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
   if !@enchanting
     self.contents.draw_text(x + 240, y, 88, 32, price.to_s, 2)
   end
 end
 #-----------------------------------------------------------------------------
 def update_help
   @help_window.set_text(self.item == nil ? '' : self.item.description)
 end
end

#===============================================================================
# ** Window_BlacksmithExtract
#===============================================================================

class Window_BlacksmithExtract < Window_Selectable

 def initialize
   super(0, 128, 368, 352) 
   self.active = self.visible = false
   refresh
   self.index = 0
 end
 #-----------------------------------------------------------------------------
 def item
   return @data[self.index]
 end
 #-----------------------------------------------------------------------------
 def refresh
   # Dispose current bitmap if defined.
   if self.contents != nil
     self.contents = self.contents.dispose
   end
   # Create list of items in inventory 
   @data = []
   (1...$data_weapons.size).each {|i|
     result = (Blacksmith.weapon_extractions(i) != nil ||
       Blacksmith.weapon_gold(i)[1] != 0)
     if $game_party.weapon_number(i) > 0 && result
       @data.push($data_weapons[i])  
     end
   }
   (1...$data_armors.size).each {|i|
     result = (Blacksmith.armor_extractions(i) != nil ||
       Blacksmith.armor_gold(i)[1] != 0)
     if $game_party.armor_number(i) > 0 && result
       @data.push($data_armors[i])  
     end
   }
   (1...$data_items.size).each {|i|
     result = (Blacksmith.item_extractions(i) != nil ||
       Blacksmith.item_gold(i)[1] != 0)
     if $game_party.item_number(i) > 0 && result
       @data.push($data_items[i])
     end
   }
   @item_max = @data.size
   # Create a new bitmap that will contain the listed items
   if @item_max > 0
     self.contents = Bitmap.new(width - 32, row_max * 32)
     (0...@item_max).each {|i| draw_item(i) }
   end
 end
 #-----------------------------------------------------------------------------
 def draw_item(index)
   item = @data[index]
   # Set a few local variables depending on the type of item.
   quantity = case item
   when RPG::Weapon then $game_party.weapon_number(item.id)
   when RPG::Armor then $game_party.armor_number(item.id)
   when RPG::Item then $game_party.item_number(item.id)
   end
   # Draw the name, icon, and quantity of the item.
   x, y = 4, index * 32
   rect = Rect.new(x, y, self.width / @column_max - 32, 32)
   self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
   bitmap = RPG::Cache.icon(item.icon_name)
   self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
   self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
 end
 #-----------------------------------------------------------------------------
 def update_help
   @help_window.set_text(self.item == nil ? '' : self.item.description)
 end
end

#===============================================================================
# ** Window_BlacksmithMaterials
#===============================================================================

class Window_BlacksmithMaterials < Window_Base

 attr_accessor :active

 def initialize
   # Initialize window size and coordinates.
   super(0, 128, 368, 352) 
   self.visible = @active = false
 end 
 #-----------------------------------------------------------------------------
 def refresh(item, type = 0)
   # Clear the bitmap and set the new materials.
   if self.contents != nil 
     self.contents = self.contents.dispose
   end
   set_materials(item, type)
   # Create a new bitmap, based off the amount of materials
   if @materials != nil && @materials.size > 0
     self.contents = Bitmap.new(self.width - 32, 64 + (@materials.size * 32))
     # Draw each material and quantity required.
     self.contents.font.color = system_color
     word = type == 0 ? 'Cost' : ($data_system.words.gold + ':')
     self.contents.draw_text(4, 0, 212, 32, word, 0)
     text = type == 0 ? 'Required Materials:' : 'Extractable Materials:'
     self.contents.draw_text(4, 32, 368, 32, text, 0)
     self.contents.font.color = normal_color
     self.contents.draw_text(244, 0, 88, 32, @price.to_s, 2)
     # Enumerate through each material.
     @materials.each_index {|i|
       # Set local variable to current item, depending on type.
       case @materials[i][0]
       when 0 
         item = $data_weapons[@materials[i][1]]
         enough = $game_party.weapon_number(item.id) >= @materials[i][2]
       when 1 
         item = $data_armors[@materials[i][1]]
         enough = $game_party.armor_number(item.id) >= @materials[i][2]
       when 2 
         item = $data_items[@materials[i][1]]
         enough = $game_party.item_number(item.id) >= @materials[i][2]
       end
       next if item == nil
       # Set local variable to store required amount of this item.
       required = @materials[i][2]
       # Set color of text, draw grayed if out if forging and not enough.
       self.contents.font.color = normal_color
       if type == 0 && !enough
         self.contents.font.color = disabled_color
       end
       # Set coordinates of current line.
       x, y = 4, 64 + (i * 32)
       # Draw item name, icon, and required amount.
       rect = Rect.new(x, y, self.width - 32, 32)
       self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
       bitmap = RPG::Cache.icon(item.icon_name)
       opacity = self.contents.font.color == normal_color ? 255 : 128
       self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
       self.contents.draw_text(x + 28, y, 212, 32, item.name)
       self.contents.draw_text(x + 272, y, 48, 32, 'x', 0)
       self.contents.draw_text(x + 272, y, 48, 32, required.to_s, 2)
     }
   elsif @price > 0
     self.contents = Bitmap.new(self.width - 32, 64)
     self.contents.font.color = system_color
     self.contents.draw_text(4, 0, 212, 32, $data_system.words.gold + ':')
     self.contents.font.color = normal_color
     self.contents.draw_text(244, 0, 88, 32, @price.to_s, 2)
     self.contents.draw_text(4, 32, 368, 32, 'No Materials')
   end
 end
 #-----------------------------------------------------------------------------
 def set_materials(item, type)
   # Sets the required/extractable items for the passed item.
   id = item.id
   if item.is_a?(RPG::Weapon)
     @materials = type == 0 ? Blacksmith.weapon_forges(id) :
       Blacksmith.weapon_extractions(id)
     @price = Blacksmith.weapon_gold(id)[type]
   elsif item.is_a?(RPG::Armor)
     @materials = type == 0 ? Blacksmith.armor_forges(id) :
       Blacksmith.armor_extractions(id)
     @price = Blacksmith.armor_gold(id)[type]
   else
     if @materials != 2
       @materials = type == 0 ? Blacksmith.item_forges(id) :
         Blacksmith.item_extractions(id)
       @price = Blacksmith.item_gold(id)[type]
     end
   end
 end
 #-----------------------------------------------------------------------------
 def update
   # Allow scrolling of bitmap if materials don't fit in window.
   if @active && self.contents != nil && self.contents.height > 320
     if Input.trigger?(Input::UP) 
       if self.oy > 0
         self.oy -= 32
         $game_system.se_play($data_system.cursor_se)
       end
     elsif Input.trigger?(Input::DOWN)
       if (self.oy + 320) < self.contents.height
         self.oy += 32
         $game_system.se_play($data_system.cursor_se)
       end
     end
   end
 end
end

#===============================================================================
# ** Window_BlacksmithStatus
#===============================================================================

class Window_BlacksmithStatus < Window_Base

 def initialize
   super(368, 128, 272, 352)
   self.contents = Bitmap.new(width - 32, height - 32)
   # Create array of sprites same size as party
   @sprites = [sprite.new, Sprite.new, Sprite.new, Sprite.new]
   #@sprites = Array.new($game_party.actors.size, Sprite.new)
   # Set coordinates of each sprite
   @sprites.each_index {|i|
     @sprites[i].x, @sprites[i].y = 380, 194 + (i * 64)#(i * 34)
     @sprites[i].z = self.z + 10
   }
   self.visible = false
   # Array of flags for walking
   @walk = Array.new($game_party.actors.size, false)
   @count, @item = 0, nil
   refresh
 end
 #-----------------------------------------------------------------------------
 def refresh
   # Clear bitmap and turn off visiblity of each sprite.
   self.contents.clear
   @sprites.each {|sprite| sprite.visible = false }
   # Return if selected item index is undefined.
   return if @item == nil
   self.contents.font.size = Font.default_size + 2
   quantity = case @item
   when RPG::Item then $game_party.item_number(@item.id)
   when RPG::Weapon then $game_party.weapon_number(@item.id)
   when RPG::Armor then $game_party.armor_number(@item.id)
   end
   self.contents.font.color = system_color
   self.contents.draw_text(4, 0, 200, 32, 'Possessed:')
   self.contents.font.color = normal_color
   self.contents.draw_text(204, 0, 32, 32, quantity.to_s, 2)
   # Disable walking animation and end method if selected item is a normal item
   if @item.is_a?(RPG::Item)
     @walk.collect! {|value| false }
     return
   end
   # Change the font size.
   self.contents.font.size = Font.default_size - 1
   # Iterate each actor...
   $game_party.actors.each_index {|i|
     chr = $game_party.actors[i]
     # Set local variable to highlighted piece of equipment.
     if @item.is_a?(RPG::Weapon)
       eqp = $data_weapons[chr.weapon_id]
     else
       armors = [chr.armor1_id, chr.armor2_id, chr.armor3_id, chr.armor4_id]
       eqp = $data_armors[armors[@item.kind]]
     end
     # Draw the actor sprite.
     draw_actor_graphic(i, chr.equippable?(@item))
     # Draw message and return if unequippable.
     unless chr.equippable?(@item)
       self.contents.font.color = normal_color
       self.contents.draw_text(32, 54 + (i * 64), 150, 32, 'Cannot Equip')
       next
     else
       # Create array of stat changes.
       # [str, dex, agi, int, pdef, mdef, (atk || eva)]
       stats = [
         (@item == nil ? 0 : @item.str_plus) - (eqp == nil ? 0 : eqp.str_plus), 
         (@item == nil ? 0 : @item.dex_plus) - (eqp == nil ? 0 : eqp.dex_plus), 
         (@item == nil ? 0 : @item.agi_plus) - (eqp == nil ? 0 : eqp.agi_plus),
         (@item == nil ? 0 : @item.int_plus) - (eqp == nil ? 0 : eqp.int_plus),
         (@item == nil ? 0 : @item.pdef) - (eqp == nil ? 0 : eqp.pdef),
         (@item == nil ? 0 : @item.mdef) - (eqp == nil ? 0 : eqp.mdef)
       ]
       if @item.is_a?(RPG::Weapon)
         stats.push(
           (@item == nil ? 0 : @item.atk) - (eqp == nil ? 0 : eqp.atk))
       elsif @item.is_a?(RPG::Armor)
         stats.push(
           (@item == nil ? 0 : @item.eva) - (eqp == nil ? 0 : eqp.eva))
       end
       # Set local variable to each piece of equipments' name
       current_name = eqp == nil ? '' : eqp.name
       new_name = @item == nil ? '' : @item.name
       # If stats are all equal, show message and end method.
       if stats.all? {|stat| stat == 0 } 
         self.contents.font.color = normal_color
         if current_name != new_name
           self.contents.draw_text(32, 54 + (i * 64), 150, 32, 'No Change')
         else
           self.contents.draw_text(32, 54 + (i * 64), 150, 32, 'Equipped')
         end
         next
       end
       # Draw any stat changes, using colors to show plus/minus changes
       self.contents.font.size = (Font.default_size - 1)
       self.contents.font.color = normal_color
       self.contents.draw_text(104, 42 + (64*i), 32, 32, 'STR ') if stats[0] != 0
       self.contents.draw_text(104, 58 + (64*i), 32, 32, 'DEX ') if stats[1] != 0
       self.contents.draw_text(104, 74 + (64*i), 32, 32, 'AGI ') if stats[2] != 0
       self.contents.draw_text(176, 42 + (64*i), 32, 32, 'INT ') if stats[3] != 0
       self.contents.draw_text(32, 58 + (64*i), 32, 32, 'PDF ') if stats[4] != 0
       self.contents.draw_text(32, 74 + (64*i), 32, 32, 'MDF ') if stats[5] != 0
       if stats[-1] != 0
         # Show stats changes for atk/eva, depending on the equipment type
         stat = @item.is_a?(RPG::Weapon) ? 'ATK ' : 'EVA '
         self.contents.draw_text(32, 42 + (64 * i), 32, 32, stat) if stat != 0
       end
       # Show any stat changes
       stats.each_index {|j|
         next if stats[j] == 0
         xy = case j
         when 0 then [132, 42 + (64 * i)]
         when 1 then [132, 58 + (64 * i)]
         when 2 then [132, 74 + (64 * i)]
         when 3 then [198, 42 + (64 * i)]
         when 4 then [60, 58 + (64 * i)]
         when 5 then [60, 74 + (64 * i)]
         when 6 then [60, 42 + (64 * i)]
         end
         # Set color and operator depending on value
         if stats[j] < 0
           self.contents.font.color, sign = Blacksmith::MINUS_COLOR, '-'
         else
           self.contents.font.color, sign = Blacksmith::PLUS_COLOR, '+'
         end
         self.contents.draw_text(xy[0], xy[1], 8, 32, sign, 1)
         self.contents.draw_text(xy[0] + 10, xy[1], 24, 32, stats[j].abs.to_s)
       }
     end
   }
 end
 #-----------------------------------------------------------------------------
 def item=(item)
   if @item != item
     # Change the item variable and refresh.
     @item = item
     refresh
   end
 end
 #-----------------------------------------------------------------------------
 def draw_actor_graphic(id, equipable)
   # Draws the actor graphic
   actor = $game_party.actors[id]
   @sprites[id].bitmap = RPG::Cache.character(actor.character_name,
     actor.character_hue)
   @sprites[id].src_rect.set(0, 0, @sprites[id].bitmap.width / 4,
   @sprites[id].bitmap.height / 4)
   # Set walking animation if item is equippable.
   @walk[id] = equipable
   @sprites[id].tone = Tone.new(0, 0, 0, equipable ? 0 : 255)
   @sprites[id].visible = true
 end
 #-----------------------------------------------------------------------------
 def update
   super
   # Update the walking animation.
   @count = (@count + 1) % 40
   $game_party.actors.each_index {|i|
     next unless @walk[i]
     if @sprites[i].bitmap != nil
       w = @sprites[i].bitmap.width / 4
       h = @sprites[i].bitmap.height / 4
       x = (@count / 10) * w
       @sprites[i].src_rect.set(x, 0, w, h)
     end
   }
 end
 #-----------------------------------------------------------------------------
 def visible=(bool)
   super
   # Set visible to the actor sprites as well.
   @sprites.each {|sprite| sprite.visible = bool }
 end
 #-----------------------------------------------------------------------------
 def dispose
   super
   # Dispose the actor sprites as well.
   @sprites.each {|sprite| sprite.dispose }
 end
end


#===============================================================================
# ** Window_BlacksmithExtract
#===============================================================================

class Window_BlacksmithEnchant < Window_Selectable

 def initialize
   super(0, 128, 368, 352) 
   self.active = self.visible = false
   refresh
   self.index = 0
 end
 #-----------------------------------------------------------------------------
 def item
   return @data[self.index]
 end
 #-----------------------------------------------------------------------------
 def refresh
   # Dispose current bitmap if defined.
   if self.contents != nil
     self.contents = self.contents.dispose
   end
   # Create list of items in inventory 
   @data = []
   ($data_items - [nil]).each {|item|
     result = false
     result = true if Blacksmith.enchant_stats(item.id) != nil
     result = true if Blacksmith.enchant_states(item.id) != nil
     result = true if Blacksmith.enchant_elements(item.id) != nil
     @data.push(item) if result
   }
   @item_max = @data.size
   # Create a new bitmap that will contain the listed items
   if @item_max > 0
     self.contents = Bitmap.new(width - 32, row_max * 32)
     (0...@item_max).each {|i| draw_item(i) }
   end
 end
 #-----------------------------------------------------------------------------
 def draw_item(index)
   item = @data[index]
   # Set a few local variables depending on the type of item.
   quantity = $game_party.item_number(item.id)
   # Draw the name, icon, and quantity of the item.
   x, y = 4, index * 32
   rect = Rect.new(x, y, self.width / @column_max - 32, 32)
   self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
   bitmap = RPG::Cache.icon(item.icon_name)
   self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24))
   self.contents.draw_text(x + 28, y, 212, 32, item.name, 0)
   self.contents.draw_text(x + 240, y, 16, 32, ':', 1)
   self.contents.draw_text(x + 256, y, 24, 32, quantity.to_s, 2)
 end
 #-----------------------------------------------------------------------------
 def update_help
   @help_window.set_text(self.item == nil ? '' : self.item.description)
 end
end

#===============================================================================
# ** Scene_Blacksmith
#===============================================================================

class Scene_Blacksmith

 def initialize(weapons = [], armors = [], items = [], level = nil)
   # Set available goods for this shop based off passed argument.
   @goods = []
   @goods += weapons.collect {|id| $data_weapons[id] }
   @goods += armors.collect {|id| $data_armors[id] }
   @goods += items.collect {|id| $data_items[id] }
   @goods.uniq!
   # Configure the level variable
   @level = (level == nil) ? Array.new(4, true) : (level + [true])
   @enchants = Blacksmith::USE_ENCHANTMENTS
 end
 #-----------------------------------------------------------------------------
 def main
   # Create a Proc to handle confirmation of choices
   @confirm_proc = Proc.new {
     @help_window.set_text('Are you sure?')
     window = Window_Command.new(160, ['Confirm', 'Cancel'])
     window.x, window.y, window.z = 224, 192, 9999
     loop { Graphics.update; Input.update; window.update
       if Input.trigger?(Input::C) || Input.trigger?(Input::B)
         result = (Input.trigger?(Input::C) && window.index == 0)
         $game_system.se_play($data_system.cancel_se) unless result
         window.dispose
         break(result)
       end
     }
   }
   # Initialize the needed windows.
   @command_window = Window_BlacksmithCommand.new(@level)
   @forge_window = Window_BlacksmithForge.new(@goods)
   @extract_window = Window_BlacksmithExtract.new
   @materials_window = Window_BlacksmithMaterials.new
   @enchant_window = Window_BlacksmithEnchant.new
   @status_window = Window_BlacksmithStatus.new
   @dummy_window = Window_Base.new(0, 128, 640, 352)
   @gold_window = Window_Gold.new
   @gold_window.x, @gold_window.y = 480, 64  
   @help_window = Window_Help.new
   # Bind the help window to the other windows.
   @forge_window.help_window = @extract_window.help_window = @help_window
   @enchant_window.help_window = @help_window
   # Set a windows array for easier handling of all windows.
   @windows = [@command_window, @forge_window, @extract_window, @help_window,
     @materials_window, @status_window, @dummy_window, @gold_window, @enchant_window]
   # Create map sprite if configured to do so, and set window opacity
   if Blacksmith::MAP_BACK
     @spriteset = Spriteset_Map.new
     @windows.each {|window| window.opacity = 160 }
   end
   # Execute the transition and start the main loop.
   Graphics.transition
   loop {Graphics.update; Input.update; update; break if $scene != self }
   # Freeze the Graphics and dispose the windows
   Graphics.freeze
   @windows.each {|window| window.dispose }
   if Blacksmith::MAP_BACK && @spriteset != nil
     @spriteset.dispose
   end
 end
 #-----------------------------------------------------------------------------
 def update
   # Update the windows
   @windows.each {|window| window.update }
   # Branch method depending on current action.
   if @command_window.active
     update_command
   elsif @extract_window.active
     update_extract
   elsif @forge_window.active
     update_forge 
   elsif @materials_window.active
     update_materials
   elsif @enchant_window.active
     update_enchant
   end
 end
 #-----------------------------------------------------------------------------
 def back_to_map
   # Play SE and return to the map.
   $game_system.se_play($data_system.cancel_se)
   $scene = Scene_Map.new
 end
 #-----------------------------------------------------------------------------
 def update_command
   # Set help text depending on the selected index.
   help_text = case @command_window.index
   when 0 then 'Use materials to forge new weapons, armors, and items.'
   when 1 then 'Extract materials from weapons, armors, and items.'
   when 2 then !@enchants ? 'Exit the shop.' :
     'Enchant weapons, armors, and items using other items.'
   when 3 then 'Exit the shop.'
   end
   @help_window.set_text(help_text)
   # Check for Input.
   if Input.trigger?(Input::B)
     back_to_map
   elsif Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     # Branch depending on command index
     case @command_window.index
     when 0
       # Play SE and return if option is locked.
       unless @level[0]
         $game_system.se_play($data_system.buzzer_se)
         return
       end
       # Shift scene to forge phase.
       @dummy_window.visible = false
       @forge_window.refresh(false)
       @command_window.active = false
       @forge_window.active = @forge_window.visible = true
       @status_window.visible = true
     when 1
       # Play SE and return if option is locked.
       unless @level[1]
         $game_system.se_play($data_system.buzzer_se)
         return
       end
       # Shift scene to extract phase
       @extract_window.refresh
       @command_window.active = @dummy_window.visible = false
       @extract_window.active = @extract_window.visible = true
       @status_window.visible = true
     when 2
       # Play SE and return if option is locked.
       if @enchants
         unless @level[2]
           $game_system.se_play($data_system.buzzer_se)
           return
         end
         # Shift scene to enchant phase.
         @forge_window.refresh(true)
         @command_window.active = @dummy_window.visible = false
         @forge_window.active = @forge_window.visible = true
         @status_window.visible = true
       else
         back_to_map
       end
     when 3
       back_to_map
     end
   end
 end
 #-----------------------------------------------------------------------------
 def update_forge
   # Update for input when forge window is active.
   @item = @status_window.item = @forge_window.item
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @command_window.active = @dummy_window.visible = true
     @forge_window.active = @forge_window.visible = false
     @status_window.visible = false
   elsif Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     @forge_window.active = @forge_window.visible = false
     if @command_window.index == 0
       @materials_window.refresh(@item, 0)
       @materials_window.visible = @materials_window.active = true
     else
       @enchant_window.refresh
       @enchant_window.visible = @enchant_window.active = true
     end
   end
 end
 #-----------------------------------------------------------------------------
 def update_extract
   # Update for input when extraction window is active.
   @item = @status_window.item = @extract_window.item
   if Input.trigger?(Input::B)
     $game_system.se_play($data_system.cancel_se)
     @command_window.active = @dummy_window.visible = true
     @extract_window.active = @extract_window.visible = false
     @status_window.visible = false
   elsif Input.trigger?(Input::C)
     $game_system.se_play($data_system.decision_se)
     @materials_window.refresh(@item, 1)
     @extract_window.active = @extract_window.visible = false
     @materials_window.visible = @materials_window.active = true
   end
 end 
 #-----------------------------------------------------------------------------
 def update_enchant
   # Update input on the enchantment items screen.
   if Input.trigger?(Input::B)
     # Return to previous screen if cancel button is pressed.
     $game_system.se_play($data_system.cancel_se)
     @enchant_window.visible = @enchant_window.active = false
     @forge_window.active = @forge_window.visible = true
   elsif Input.trigger?(Input::C) && @confirm_proc.call
     enchant_item 
   end
 end
 #-----------------------------------------------------------------------------
 def enchant_item
   # Apply enchantment to weapon/armor using item
   $game_party.lose_item(@enchant_window.item.id, 1)
   Blacksmith.create_item(@forge_window.item, @enchant_window.item)
   # Play SE
   $game_system.se_play(RPG::AudioFile.new(*Blacksmith::ENCHANT_SE))
   # Refesh windows
   [@enchant_window, @status_window].each {|window| window.refresh }
   @forge_window.refresh(true)
   # Return to previous screen
   @enchant_window.visible = @enchant_window.active = false
   @forge_window.active = @forge_window.visible = true
 end
 #-----------------------------------------------------------------------------
 def update_materials
   # Show help text.
   text = 'Press the Action Button to proceed. Press Cancel to go back'
   @help_window.set_text(text)
   if Input.trigger?(Input::B)
     # Return to previous screen if cancel button is pressed.
     $game_system.se_play($data_system.cancel_se)
     @materials_window.visible = @materials_window.active = false
     if @command_window.index == 0
       @forge_window.active = @forge_window.visible = true
     else
       @extract_window.active = @extract_window.visible = true
     end
   elsif Input.trigger?(Input::C) && @confirm_proc.call
     @command_window.index == 0 ? forge_item : extract_item
   end
 end
 #-----------------------------------------------------------------------------
 def forge_item
   # Set local variables depending on item type.
   case @item
   when RPG::Weapon
     quantity, type = $game_party.weapon_number(@item.id), 0
     materials = Blacksmith.weapon_forges(@item.id)
     price = Blacksmith.weapon_gold(@item.id)[0]
   when RPG::Armor
     quantity, type = $game_party.armor_number(@item.id), 1
     materials = Blacksmith.armor_forges(@item.id)
     price = Blacksmith.armor_gold(@item.id)[0]
   when RPG::Item
     quantity, type = $game_party.item_number(@item.id), 2
     materials = Blacksmith.item_forges(@item.id)
     price = Blacksmith.item_gold(@item.id)[0]
   end
   # If player doesn't have the materials or gold, play SE and end method.
   unless Blacksmith.materials?(type, @item.id)
     $game_system.se_play($data_system.buzzer_se)
     return
   end
   # End method and play buzzer if inventory is full.
   return $game_system.se_play($data_system.buzzer_se) if quantity == 99
   # Play the defined SE used when forging.
   $game_system.se_play(RPG::AudioFile.new(*Blacksmith::FORGE_SE))
   # Remove required materials from inventory and subtract gold cost.
   if materials != nil
     materials.each {|material|
       case material[0]
       when 0 then $game_party.lose_weapon(material[1], material[2])
       when 1 then $game_party.lose_armor(material[1], material[2])
       when 2 then $game_party.lose_item(material[1], material[2])
       end
     }
   end
   $game_party.lose_gold(price)
   # Add forged item
   case @item
   when RPG::Weapon then $game_party.gain_weapon(@item.id, 1)
   when RPG::Armor then $game_party.gain_armor(@item.id, 1)
   when RPG::Item then $game_party.gain_item(@item.id, 1)
   end
   # Reset windows.
   @materials_window.visible = @materials_window.active = false
   @forge_window.active = @forge_window.visible = true
   # Refresh any windows that may have changed
   [@status_window, @gold_window, @extract_window, @forge_window,
     @enchant_window].each {|window| window.refresh }
 end
 #-----------------------------------------------------------------------------
 def extract_item
   # Set local variables depending on item type.
   case @item
   when RPG::Weapon
     quantity = $game_party.weapon_number(@item.id)
     materials = Blacksmith.weapon_extractions(@item.id)
     price = Blacksmith.weapon_gold(@item.id)[1]
   when RPG::Armor
     quantity = $game_party.armor_number(@item.id)
     materials = Blacksmith.armor_extractions(@item.id)
     price = Blacksmith.armor_gold(@item.id)[1]
   when RPG::Item
     quantity = $game_party.item_number(@item.id)
     materials = Blacksmith.item_extractions(@item.id)
     price = Blacksmith.item_gold(@item.id)[1]
   end
   # If nothing is defined for the extraction, return.
   if materials == nil || (materials.empty? && price == 0)
     return $game_system.se_play($data_system.buzzer_se)
   end
   # Play extraction SE
   $game_system.se_play(RPG::AudioFile.new(*Blacksmith::EXTRACT_SE))
   # Perform extraction, adding materials and increasing gold.
   materials.each {|material|
     case material[0]
     when 0 then $game_party.gain_weapon(material[1], material[2])
     when 1 then $game_party.gain_armor(material[1], material[2])
     when 2 then $game_party.gain_item(material[1], material[2])
     end
   }
   $game_party.gain_gold(price)
   # Remove extracted item from inventory
   case @item
   when RPG::Weapon then $game_party.lose_weapon(@item.id, 1)
   when RPG::Armor then $game_party.lose_armor(@item.id, 1)
   when RPG::Item then $game_party.lose_item(@item.id, 1)
   end
   # Reset windows.
   @materials_window.visible = @materials_window.active = false
   @extract_window.active = @extract_window.visible = true
   # Refresh any windows that may have changed
   [@status_window, @gold_window, @extract_window].each {|window| window.refresh }
 end
end

 


Instructions

 

Place script below Debug and above Main.

Instructions are in the script.


Compatibility

 

  • If you have a script that re-writes Window_Gold, it could cause graphical irregularities on the blacksmith screen.
  • Scripts that alter items in the database may cause issues, though not tested.


Credits and Thanks

 

  • ForeverZer0, for writing the script
  • RoseSkye, huge thanks for beta-testing and demo map


Author's Notes

 

Please report any bugs you may find at www.chaos-project.com.

Hope you enjoy!

Edited by ForeverZer0

Share this post


Link to post
Share on other sites

This script sounds very usefull. Can it be used for the VX?

 

Although I have never tested it, I'm sure it cannot due to RGSS and RGSS2 being structured differently.

I have never really used VX or written scripts specifically for it, so I am unsure of all the changes made.

Share this post


Link to post
Share on other sites

Would it be possible for you to convert the code to VX? this system seems a ton more user friendly than that of KGC :) I hate typing in Arrays aswel so this would help to no end :)

Share this post


Link to post
Share on other sites

hey, just wondering if there is a way that i could use this to mod items to make diamond tipped arrows and ammo etc, also i it would be compatible with my script, im using mr mo's abs, it sources weapon ids from the weapon database

Share this post


Link to post
Share on other sites

Hey... how can I use this with just the enchantments? Bit of a silly question, but still (:

I just want to be able to attach pre-brought gems onto weapons/armour/accessories (and be able to take them off again) at no cost, from the menu, with the same state/element change feature.

Share this post


Link to post
Share on other sites

This script is awesome but it isnt working for me (i think its my other scripts) but i can live without

but i had to say that it is BEAST :D

Share this post


Link to post
Share on other sites

Please sign in to comment

You will be able to leave a comment after signing in



Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...