[XP] Blacksmith System (New Configuration Program!)

Started by ForeverZer0, April 21, 2010, 04:50:15 pm

Previous topic - Next topic

ForeverZer0

Blacksmith Shop
Authors: ForeverZer0
Version: 2.0
Type: Custom Shop
Key Term: Custom Shop System



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
Forge Screen: ShowHide

Extract Screen: ShowHide

Enchant Screen: ShowHide


Configuration Application
Spoiler: ShowHide

Spoiler: ShowHide

Spoiler: ShowHide



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.
Spoiler: ShowHide
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# 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

KK20 wrote a bugfix. It mainly addresses the enchantment system and displays of the windows. Get it here: http://pastebin.com/AFrMCa2f


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!
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Ravenith

Very nice. The "Extract" feature explores a nice design space that few scripts had (directly) explored in the past.

Nadim13

It seems cool.
I'll try it this afternoon and I let you know. 8)

Agckuu Coceg


;) New interesting script. But maybe add a little more customization, something like for example the old Prexcraft? It would be nice.
I'm not retarded, but I'm busy. Sorry for patience.


Nadim13

Ok, that's a cool (and very simple to customize) script, good work! ;)
But I suggest you to edit the extract part: it would be better that, when you extract materials from your weapon/armor, you'll receive less quantity of them instead the same number of the creation part.

Ex.
3 Gold Ore => Gold Sword
and, during the extraction
Gold Sword => 2 Gold Ore

By the way, once again... good work! 8)

lonely_cubone

I like this script, but one thing that would be really helpful is if you could create and extract things in bulk. For example, when you select Forge Iron Sword, and you have enough materials to make 12 of them, it will let you choose how many to make. Other than that, I think this script is quite useful. :D

ForeverZer0

Thanks for the feedback everybody.
I'll see about adding the new features. I was already thinking about a few of them...
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

13579

Sorry to say, found a bug. When extracting items from a weapon, keep going until there are no more weapons left to extract items from. Keep clicking the extract button on the blank, and even though nothing is there, it will keep extracting and giving you minerals from the last weapon that was in the slot. When I exited the blacksmith system and went into the menu I had 99 gold ore. When I attempted to go back into the system to do it some more, I got this error:

 Script 'Blacksmith System' line 622: NoMethodError occurred.
undefined method 'each_index' for nil:NilClass


Sorry, I'm a noob scripter and have no idea how to fix this. Over the past 4 days I've gone over this entire forums script database for RPGXP, downloaded what interested me, and am slowly learning how to make things work by looking at others scripts. Just happened to find this when I was bored. Other than that, this is a really useful script.

ForeverZer0

@13579
Don't be sorry, I welcome people to find bugs so I can fix them. It is very difficult to completely de-bug an entire script and think of everything, so it is helpful for others to let me know what they find.

I'll check this problem and have it fixed soon. Thanks!
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

XaineC

I've got an error for you. Line 647 NoMethodError occured. undefined method `each_index' for 1:Fixnum

ForeverZer0

Quote from: XaineC on August 24, 2010, 12:30:38 pm
I've got an error for you. Line 647 NoMethodError occured. undefined method `each_index' for 1:Fixnum


When and how did it occur. That would really help narrow it down.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

XaineC

Nevermind. I screwed up the script call, that's it.

ForeverZer0

Quote from: XaineC on August 24, 2010, 07:59:49 pm
Nevermind. I screwed up the script call, that's it.


Okay.  ;) Thanks anyway.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Ninjason

December 16, 2010, 02:38:11 pm #13 Last Edit: December 16, 2010, 02:39:34 pm by Ninjason
Hey, great script, quite the thing I was looking for.

I inserted it, configured it - but upon using it, I get this error message every time I would get the item #434 among other things out of a deconstruction:



What could that be?
there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

Taiine

Error. It happens if you have no items that you can extract materials from but still go to the menu and try to 'extract' from the blank listing.




ForeverZer0

I will check it out. This is one of my earlier scripts, I think it is ready for a complete re-write. I learned quite a bit since writing it, so just old off a little bit and I will release a completely new and improved version of it. I'll add some new features as well, such as configurable extracted materials, etc.

Any other requests before I get started?
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Ninjason

December 20, 2010, 04:10:42 pm #16 Last Edit: December 20, 2010, 04:13:42 pm by Ninjason
Actually, yes - When you extract items from the weapon/armor on the very bottom of your list and deplete your stock, you have the possibility, to stay on that empty slot and keep extracting even though you have no more items left.

But it works nevertheless - you can get an infinite number of extracted items by that.

Here's a screenshot to help my explanation (did it with your demo):
there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

Ninjason

Btw i cleared my error message - I used a dot (.) instead of a comma (,) in the formulas. :ninja:
there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

ForeverZer0

I know already of the the extraction error, but thanks for making sure.  ;)

When I said "requests", I meant more of added features one may like in the next version. Fixing bugs will be my top priority obviously. The error you mentioned will be definitely fixed, though.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

SilverShadow737

Pretty sweet script,  maybe a feature to add would be to show how many materials the player has before forging either by pushing a button, or simply in the confirm menu.  Also you could try to space stats a little better because the + or - overlap the letters.  My final suggestion is maybe you could add item creation such as two ingredients create a potion, or iron + coal = steel?
Ginyu Force Rules

Ninjason

I'd have one too:

At the moment it is just possible to build Weapons/Armors with items.

How about inserting weapons and armors into the creationprocess?

Like "steel sword" (weapon) + "Gold" (Item) = Gold Sword?

By that you could enhance Weapons...
there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

ForeverZer0

Yeah, I was planning on icluding some sort of "enchant" feature. Maybe use items such as gems or whatever to add state and element efficiency to a weapons and armors. For example, you enchant a steel sword with a "Fire Stone", and it gains fire efficiency. The current system could allow for this, but I would like to make it so that you are not forced to create a bunch of weapons and armors that it has to change to. Just have the system keep track of what pieces have been enchanted with what, and have the system create the actual weapons/armors in the database.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Taiine

December 22, 2010, 03:41:08 pm #22 Last Edit: December 22, 2010, 03:51:57 pm by Taiine
I'm waiting for this to be fixed up. This honestly looks to be a lot better then the system I had in place. My game don't use gear per say, but rather status stones that boost stats (only yeah that is technically still gear >.>;;;) and some of the bigger improved items can only be crafted. I was doing an event that if player has this and that in invatory option to make new item. Big BIG messy event. This looks much more clean.

Only thing is, when it comes it extracting, it lists every item rather you can extract from it or not, how about it just list items you can extract? Perhaps also a setting for items that when crafted, can't be reextracted?

Ninjason

I'll second that - some crafted Items should not be able to be deconstructed.
there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

Ninjason

I have another one:

How about a function to deconstruct more than 1 (eg: Iron sword) if you have more than one in stock?
there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

SBR*

I have never leveled you up for this, Zero! My bad :D. Maybe I didn't level up in these days yet? Ah, w/e... Anyway, I will level you up now for the making, and might level you again for the remaking later :D.

Cya :urgh:!

ForeverZer0

It's been slow-going over the holiday week here, but I do have the base system finished.  Still need to tweak it a little bit and re-write the scene. I will include a way to multi-forge and multi-extract if player's item quantities permit and remove the limitation on number of items that will display on-screen, etc.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

mroedesigns

Awesome script! Can't wait for the re-release

ForeverZer0

Might be little longer than I first thought. I got too many things going on as it is that are unfinished. I can't seem to find the spare time to get what I want to do done.

Be patient though, I promise I will release it sometime in the near future.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Taiine

/sits and waits for update
/grabs popcorn
/throws in movie

ForeverZer0

Sorry, I've been caught up working on a C# project that's taking a longer than expected. When its done I'll likely start do this. I've been having a hard time getting into RGSS anymore, it's kind of losing my interest, but I'll be updating a few last things before I officially call it quits "retire" as Blizz did.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Taiine

Quote from: ForeverZer0 on February 06, 2011, 01:31:32 am
Sorry, I've been caught up working on a C# project that's taking a longer than expected. When its done I'll likely start do this. I've been having a hard time getting into RGSS anymore, it's kind of losing my interest, but I'll be updating a few last things before I officially call it quits "retire" as Blizz did.


Nooo.. Man all the good scripters are poofing it seems... leaving behind a lot of immature people who don't know a script from an event. :(

Blizzard

Yeah, it's a bit of a tricky situation. Most people with some skill simply move on.
Check out Daygames and our games:

King of Booze 2      King of Booze: Never Ever
Drinking Game for Android      Never have I ever for Android
Drinking Game for iOS      Never have I ever for iOS


Quote from: winkioI do not speak to bricks, either as individuals or in wall form.

Quote from: Barney StinsonWhen I get sad, I stop being sad and be awesome instead. True story.

Futendra

Howd you make the Splash screen?

Ninjason

Sorry, I'm not meaning to "bump" this, as I think, bumping is quite impolite but I'm seriously concerned, that you might scrap this whole post at some point/ have done it already and I'm the one, who kinda got this one here reactivated because I REALLY REALLY like this idea and where you were aiming to go with it.

Please don't scrap this script, it really has a lot potential as I think the blacksmith-part in general hasn't got its fill yet in the variety of scripts available for the RPG XP.
there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

Kyra

I am so going to use this.

I wonder if it can be worked into a loot bazaar system such as the one from FFXII.

ForeverZer0

If you added enough detail to the config it could be.  The hardest part will be finding the right balance.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

RoseSkye

Found a huge glitch: Extracting from equipment until there is 0 left will leave a black space -yet- it will still give you the items from the last weapon.

ForeverZer0

Oh, shit, I thought I fixed that.
Forgot that I did it in the unfinished re-write that wasn't released. I knew I remembered doing it...

I will finish this. I know this has been said, and I always get side-tracked, but this time I will actually do it. Give me a few days.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

PhoenixFire

If it helps with your motivation, I too plan on using it in my game, and incorporating it.. Yes, it will be modded, but due credit will be given :)
Quote from: Subsonic_Noise on July 01, 2011, 02:42:19 amNext off, how to create a first person shooter using microsoft excel.

Quote from: Zeriab on September 09, 2011, 02:58:58 pm<Remember when computers had turbo buttons?

ForeverZer0

I'm actually working on it at this very moment. It's being rewritten from scratch, so it will be slightly different.

Here's the features so far:

  • Ability to forge/extract weapons, armors, and items

  • All new ability to enchant items to make them more powerful, with option to disable this feature

  • User defined extracted materials per item, or have it done automatically using forge materials

  • Define prices for forging, extracting, and enchanting separately

  • Improved coding

  • Fix some bugs, namely the "infinite extract" one

I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Ninjason

there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

ForeverZer0

Okay I have implemented the enchantment system, which is much more than I had first planned on. The script has turned out to be a more massive expansion of the original, but should address all the known issues and have many more feature, while maintaining the same basic layout.

Each feature I add is giving me ideas for more, but I'm not sure when they will be added, since I have some other things I am working on, but I am leaving room for easy adding of future updates. I may even create a simple GUI like I did for CCTS someday, which will make configuration mush less tedious, and less error-prone.

Will post new version up within a day.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

RoseSkye

Know what'd be really cool? A refining store that upgrades weapons stats.

ForeverZer0

Already got it.
You can define items that can alter stats, states, and elements on weapons and armors. You can apply have it alter as much or as little as you want, too.

For your making me a map for the demo, you can have first look. It is still being created, but the current version is stable. Check your PM.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Jragyn

What're the chances of implementing "Item" creation into this system, along-side of the weapons and armor?

ie: Smithing, Enchanting, Extracting, /Alchemize/   (or in any order you feel the need for)

After implementing your enchanting aspect, and leveling aspect... the lack of standard item-creation aspect is the only thing keeping me from using this system :(
A bright light can either illuminate or blind, but how will you know which until you open your eyes?

ForeverZer0

What do you mean? This version does have item creation. You can make/extract items the same as you can weapons and armors, hence the added configuration for it.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Jragyn

April 25, 2011, 12:59:22 pm #47 Last Edit: April 25, 2011, 01:53:10 pm by jragyn00
>.< I read the top and for some reason I looked over the "weapon/armor/ITEM"...

Haha, sorry.
I haven't actually tested this since it was upgraded to 2.0.


EDIT:: Derp, you a clever man, sneakin' it in like that.
Is there a way that perhaps you can setup a "shop" to have only the 'extract' option, or only the 'enchant' option visible?
ie usage:
    "Hi im a wizard and I enchant stuff." (no need to have 'forge' option available)
    "Hi im a smith and I forge stuff."  (no need to have 'enchant' option available)

Considering utilizing this system for its unique extraction and enchantment aspect, but I have another system to do the actual item creation. (May mess with this system and its leveling ideas to see if I can modify it for my uses if you can't/won't)
A bright light can either illuminate or blind, but how will you know which until you open your eyes?

ForeverZer0

You can do that. Its in the instructions, you provide a 4th argument to the scene call:

[FORGE?, EXTRACT?, ENCHANT?]

...where each value is a true/false if that ability is available.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

RoseSkye

Is there a way to change the weapon/armor/item name when you enchant it?

ForeverZer0

I actually started on that, but didn't finish it. I'll add it sometime soon. I still have the windows for it I made I think...
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Jragyn

Add a fourth arguement?
I read that as a reference to adding skill level requirements to the ability to forge etc.

But even so, I can't really figure out how to arrange it.
This is what I came up with:

w = []
a = []
i = []
$scene =
Scene_Blacksmith.new
(w,a,i,
[CAN_FORGE?=false,
CAN_EXTRACT?=false,
CAN_ENCHANT?=true])


In my script call was that, and it drops syntax error :\
Am I doin' it wrong?
A bright light can either illuminate or blind, but how will you know which until you open your eyes?

ForeverZer0

You are supposed to replace the all-caps WORDS with the actual value. Here is an example script call of a Blacksmith that can only do forging and encganting, but not extractions:

w = [1, 2, 3, 4]
a = [3, 8]
i = [54]
l = [true, false, true]
$scene = Scene_Blacksmith.new(w,a,i,l)
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Jragyn

ahh, add a fourth variable arguement like that X_X Go figure.
Well, thank you kindly for that info.

...but if thats how that works, then how do you apply "levels" and gain said levels, for creation?

Again, lost... though I know how to make this script work in the way I can use it now :)
A bright light can either illuminate or blind, but how will you know which until you open your eyes?

ForeverZer0

April 26, 2011, 08:35:13 pm #54 Last Edit: April 26, 2011, 08:37:12 pm by ForeverZer0
There is no "level" system. You could event one I suppose, but it was made to simply call the Blacksmith with what items he has available.

I'll work on configuration program. I'll see if I can get it out fast, but I do have some other priorities that need taken care of, like ARC, so if it turns into a more expansive endeavor than I first thought, I may have to put it on hold.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Jragyn

If it came between this and ARC, I pray you choose ARC first.
I can do editting and modifications of some scripts, but I'm vastly more interested in the production of a newer and well... "upgraded" RMXP like you've got going.

So don't sweat this, it was obviously a misinterpretation on my behalf, and thank you for your support.
:D

--J
A bright light can either illuminate or blind, but how will you know which until you open your eyes?

Shalaren

s:
it lets you enchant a weapon even when you got 0 of that meterial.
also a suggestion, to make a failur % and a success %, and if it fails it totally screws the item xD
like, first time using the ore is 100%, second time is 80% and so on, it goes down and down until its almost and impossible, like 12%.

ForeverZer0

Are you using the new version?
The extraction bug was from version 1.0.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Shalaren


ForeverZer0

Uploaded my newly created configuration application, which can be found in the original post. Be sure to check it out if you plan on using this system!

@shalaren:
I don't really know what you are talking about. I just checked it out, and a material doesn't even show up on the "Enchant" screen if it isn't in your inventory. If you use the last one, it refreshes properly and is no longer displayed as well.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Ninjason

Zer0 you are a GOD among us mortals.

especially that application got me bursting "kraaasser Scheiß!"

which roughly translates to "insaaaane Shit!"  :ninja:

I am stunned. Thank you.
there's only one Ninja an these are the scripts he currently uses:
* Easy Party Switcher by Blizzard (v2.43b)
* Universal Message System (v1.8.0) by Ccoa
* Active-Time-Battle by MakirouAru
* Catergorized Items Menu (v1.3) by albertfish
* Law's Custom Equipment Screen (v2.?) by The Law G14
* Advanced Shop Status Window (v2.0) by RPG Advocate, edited by Fantasist
* Blacksmith Shop (v2.0) by ForeverZer0
* Quest Log System (v3.0) by game_guy
* Enemy HP & MP Bars by Asandril
* Map Location (v1.0) by Hunter x
* Switch Checker by Night_Runners (made for me specifically)
* Redd's TitleIcons by Redd
* Journal (v2.4) by ForeverZer0
* Drago Smooth Scroller (v2.02) by LiTTleDRAgo

ForeverZer0

Thank you, I'm glad you like it. I understand that configuring such a script can be confusing and tedious, at best. Especially for a large game. I hope that the program will help alleviate a lot of that.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

GrieverSoft

You know, that's just- that's just frakkin' awesome.  This blacksmith system is pretty damn good, I personally couldn't ask for more.

Okay, I'm lying, just one tidbit that's just bugging me and I'm dying to ask.  One feature suggestion:

*In the script call, the user can specify not only the items, but their price (or if they're free)

For example, if someone (like me, for instance) implemented a system where you can kiss a vendor's ass for lower prices, or had in-menu item crafting skills (Use the "Leatherworking" skill in menu to open a crafting scene) in which it wouldn't make sense for items to even have prices.

How does that sound?

8)
I like pie.  The pie is also evil.

ForeverZer0

I could, but it would require re-writing a pretty large amount of script. I didn't really put the fore-thought into allowing the prices be dynamic. One alternative, though kind of crappy one, would be to create duplicate weapons and configurations that appear to be the same but are not. You can then even use an event to decide the "ass-kissing" thing and have it split to branches that use different script calls.

I know, not a great alternative, but it would work.
I may at some later date think about it some more (I still have to add the item-naming thing), but until then this may be the way you have to do it, sorry.  :shy:
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

GrieverSoft

I thought of that alternative, too.  And you're right, crappy it be.

How's the item-naming thing gonna work?  Like on Final Fantasy X (named automatically) or the Elder Scrolls (you get to name it)?
I like pie.  The pie is also evil.

ForeverZer0

Likely a Name Edit screen will pop up when a new item is created. As it is now, a duplicate of that weapon is placed in the inventory. It is kept separate, but you makes it hard to distinguish them if the wrong CMS is used, since the differences in stats and/or states and elements is not seen.

It works by actually creating new items in the database. If you mess around and create some new items, then close-reopen the editor, you will see that they have been added to your database.

This kinda of makes it hard for creating extractions for items once they have been enchanted though, since they are no longer in the actual original item, but one with a whole new ID, therefore cannot be defined in the configuration ahead of time.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

GrieverSoft

How does that differ from the creation system?
I like pie.  The pie is also evil.

ForeverZer0

The forging simply requires pre-defined items to create pre-defined other items. Same with extraction. Enchanting creates a whole new item, not yet defined in the database. Basically a replica of the original, but with the added effects given to it by the item that enchanted it.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

GrieverSoft

I like pie.  The pie is also evil.

Shalaren

Script 'Window_help' line 26 Type error
err :< I keep getting an Type error, first it was inside the addons and now its there,
it has some problem with text, why does it do that? ><"~

Jragyn

If instabilities is an issue as far as ripping items etc from the project, rather than running a script thingy to output a file, why not take a gander at Blizz-ABS's config program? It reads everything thats in the project, doesn't it? And isn't it like... open-sourced or something? I'm sure he wouldn't mind if you utilized a portion of that program to make your work that much easier. :D
A bright light can either illuminate or blind, but how will you know which until you open your eyes?

ForeverZer0

May 02, 2011, 01:14:45 am #71 Last Edit: May 02, 2011, 02:39:29 am by ForeverZer0
Blizz didn't embed Ruby in the app. He actually did it in an even harder way by writing his own class that could read (at least partially) a Ruby Marshaled object. To be perfectly honest, I don't deem this script worthy of so much work. The config program would be many time more difficult to write (at least for me) if I had went that particular route. I have embedded IronRuby in C# and have been able to read the .rxdata, but it is a slightly tedious process translating between the two languages. That's why I went the simple route and have the user just run a small script in there game which will ouput a file in a universal format. It only needs to be done once, and then the data can be serialized in C# and doesn't need to be done again, so I didn't think it was that big of a deal. I doubt I will change it, unless I get bored some day and have nothing else to fiddle with.  :naughty:


EDIT:
I just noticed a couple of minor errors that need fixed with the program:

  • Will get syntax error in RMXP unless something is defined for every category

  • Price does not change properly when selecting between items

  • A ", ]" is left trailing at one of the output configurations, which will also cause an error



I will fix these very soon, probably tomorrow. Sorry for the inconvenience , everyone.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Jragyn

Haha, what Blizzard did is beyond me at this time. All I know is that his program reads all the data in your project, and then it spits out a script to use :D Anyways, I appreciate you expaining how it works, though. I too am trying to teach myself C#(for XNA purposes) and every little bit helps as far as other people trying to teach me a bit too. :)

Once again though, your scripts are impressive and I insist you keep up the good work.
A bright light can either illuminate or blind, but how will you know which until you open your eyes?

Shalaren


ForeverZer0

May 02, 2011, 10:10:46 pm #74 Last Edit: May 03, 2011, 03:04:26 am by ForeverZer0
Down for repairs at the moment. I don't want someone getting anymore of the versions with the bugs. I'm almost done. Should be back up within the hour. I'll bump when its up.

EDIT:
Sorry for the hold-up. I fixed almost everything. The gold issue is slightly more involved than I thought it would be. I have to rethink it through how it works. Basically an event is raised when the value is changed, and the proper value gets applied to the selected item. Problem is when the player moves around between tabs and different items, the program changes the value to match the new selected item, which in turn raises said event, resetting it again, but now incorrectly. Sounds like it could be fixed by simply changing the order of when things are done, but apparently not, cause I now find myself searching around trying to backtrace a bug, and find out how to fix it without having to restructure a bunch. But now I'm tired, and sleep I must, so you will all have to wait for the morrow.  ;)
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

PhoenixFire

I must wait?!?   NUUUUU!!!!

lolz.. I just reactivated my RMXP with a new trial key though, so I can start some more work on T.E.P. and I decided I'm definitely using this feature. Though, I do need to do a bit of planning for what features to use in what areas.. Like, I don't want to enable people to use enchanted items right off the start, but, I would like this feature incorporated into the Blacksmith in the first small village... grrr...


EDIT: Also, level ++ for all the work you've been putting into this, and, other scripts. They're just awesome.
Quote from: Subsonic_Noise on July 01, 2011, 02:42:19 amNext off, how to create a first person shooter using microsoft excel.

Quote from: Zeriab on September 09, 2011, 02:58:58 pm<Remember when computers had turbo buttons?

Bradley_Theory


ForeverZer0

Fixed the following bugs in the configuration program:

  • Proper Ruby syntax for every option that is not defined. No more errors with the script.

  • Fixed problem with proper value for the forge/extract price being displayed

  • Fixed error loading saved configurations. They will now load fully and remember everything you defined so far

  • Made some minor improvements and restructuring internally



See the original post for the new link.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Shalaren


ForeverZer0

Thank you for yet another vague statement. You excel at those.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

PhoenixFire

@f0 - I think he might have an issue of stuff, with some things.. Yanno, using some scripts and stuff :V: lmao...
Quote from: Subsonic_Noise on July 01, 2011, 02:42:19 amNext off, how to create a first person shooter using microsoft excel.

Quote from: Zeriab on September 09, 2011, 02:58:58 pm<Remember when computers had turbo buttons?

ForeverZer0

I just think being a little more descriptive might help.

What error?
What does the error say?
When does it occur, precisely?
What other scripts do you use?
Have you tried changing the script order around?

I can't help anybody when all I have to go by is "there is error".
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Jragyn

How could an item creation system not work with Blizz-ABS?
Well, the only thing I could fathom is the part where it creates new items in the database... which can't really be pre-defined as far as range/type etc.
A bright light can either illuminate or blind, but how will you know which until you open your eyes?

Shalaren

May 04, 2011, 09:47:16 am #83 Last Edit: May 04, 2011, 10:43:40 am by Shalaren
My mistake, I figured whats wrong,

Edit:
QuoteScript 'Window_Help' line 26: Type error occurred
cannot convert nil into string

thats what i get when i call the scene
Edit: I also found out that it only happens when using Blizzard's mouse controller

Cal RPG MGS

This System is brilliant, its just what i needed for my game, keep up the good work.

But if i may make 2 suggestions, which are to do with the weapon enhance ments
(Which with out are would make my game imbalanced due to over powered Weapons)

1. Weapon specific enhancements

E.g Handgun 2 upgrade will enhance only handgun 2

2. And Enhancement limits

This is the best way i can put this one

This is a Enhancement slot: []
Handgun : [] [] [] [] ; this weapon can only have 4 enhancements
Shotgun : [] [] ;  ; this weapon can only have 2 enhancements

If this i possible i would love even more this system.

ForeverZer0

Currently, only one enchantment can be applied to each item, so basically everything has only one slot.
I would like to add a way to do something very much like what you suggested, as well as allow the user to rename newly created/enchanted items.

I'll have to find some spare time and see what I can do.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Cal RPG MGS

:) Ok cool, how about the weapon specific enhancement is it a possibility ?

ForeverZer0

We'll see.
I'll have to add a parameter or two to RPG::Weapon. The fact that enchanted weapons are actually created in the database makes it slightly tricky, since they cannot be configured by the user ahead of time.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Kirye

Alright, i'm getting a really weird effect when I enchant armors.

Say I have 1 Iron Armor in my inventory and I enchant it with an Earth Orb (+earth resistance). I'll end up having 2-3 Iron Armors all with the Earth resistance. If I equip them, save the game and then Save progress on RMXP, then load the game again.. the armors are completely gone.

Here are the Scripts i'm running:

Blacksmith
BABS 1
BABS 2
BABS 3
Winkio Party HUD
Littledrago's Info Display
Littledrago's Boss meter
Qubid's MP3 Loop
Stormtronics CMS

I'm guessing the armors disappear because i'm saving over the modified data on RMXP, but don't know why I get multiple armors from the enchant.

Spoiler: ShowHide
#:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:=:
# 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, 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
#   - 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, separate 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 elements, 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 = ['157-Skill01', 80, 100]
 # SE played when an item is forged. ['FILENAME', VOLUME, PITCH]
 EXTRACT_SE = ['168-Skill12', 80, 50]
 # SE played when an item extraction is performed. ['FILENAME', VOLUME, PITCH]
 ENCHANT_SE = ['087-Action02', 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 = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]
 NO_ENCHANT_ARMORS = []
 # Include IDs of any equipment that cannot be enchanted in the respective
 # arrays, separating by commas. Ignore these if not using enchant feature.

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

 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 separately 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 separate the material arrays with commas. See
 #   below for a few examples.
 #-----------------------------------------------------------------------------
 def self.weapon_forges(id)
   return case id
   when 1 then [[2, 35, 2]]  # Templar Sword
   when 2 then [[2, 39, 1], [2, 35, 5], [2, 9, 1]]  # Heavenly Might
   when 3 then [[0, 2, 1], [2, 40, 2], [2, 36, 1]]  # Ragnarok
   when 4 then [[0, 3, 1], [2, 60, 1], [2, 41, 1]]  # Excalibur
   when 5 then [[2, 35, 1]]  # King's Spear
   when 6 then [[2, 36, 5]]  # Imperial Arm
   when 7 then [[0, 6, 1], [2, 37, 2], [2, 4, 1]]  # Longinus
   when 8 then [[0, 7, 1], [2, 62, 1], [2, 39, 10]]  # Bracchio
   when 9 then [[2, 35, 1]]  # Heavy Axe
   when 10 then [[2, 40, 3], [2, 38, 1]]  # Gaia Splitter
   when 11 then [[0, 10, 1], [2, 41, 1]]  # Eruption
   when 12 then [[0, 11, 1], [2, 61, 1], [2, 38, 5]]  # Mjolnir
   when 13 then [[2, 35, 2]]  # Thief Blade
   when 14 then [[2, 37, 2], [2, 36, 2], [2, 39, 1]]  # Kunai Blade
   when 15 then [[0, 14, 1], [2, 38, 3], [2, 40, 1]]  # Dark Butterfly
   when 16 then [[0, 15, 1], [2, 56, 1], [2, 35, 20]]  # Gilgamesh
   when 17 then [[2, 35, 1]]  # Loud Roar
   when 18 then [[2, 39, 3], [2, 36, 2]]  # Longshot
   when 19 then [[0, 18, 1], [2, 37, 3], [2, 38, 2]]  # Valkyrum
   when 20 then [[0, 19, 1], [2, 59, 1], [2, 40, 5]]  # Lunar Dive
   when 21 then [[2, 35, 1]]  # Black Scythe
   when 22 then [[2, 37, 2], [2, 36, 3]]  # Reaper
   when 23 then [[0, 22, 1], [2, 40, 3], [2, 38, 3]]  # Devil's Bullova
   when 24 then [[0, 23, 1], [2, 63, 1], [2, 37, 10]]  # Grim Ascendance
   when 25 then [[2, 35, 1]]  # Air Chain
   when 26 then [[2, 36, 4]]  # Giant Anchor
   when 27 then [[0, 26, 1], [2, 37, 1], [2, 38, 1]]  # Black Pearl
   when 28 then [[0, 27, 1], [2, 57, 1], [2, 38, 5]]  # Maelstrom
   when 29 then [[2, 35, 1]]  # Cleric Staff
   when 30 then [[2, 39, 1], [2, 40, 1]]  # Arloche
   when 31 then [[0, 30, 1], [2, 38, 2], [2, 12, 1]]  # Undine's Wand
   when 32 then [[0, 31, 1], [2, 10, 1], [2, 58, 1]]  # Kerykleon
   end
 end

 def self.armor_forges(id)
   return case id
   when 1 then [[2, 35, 1]]  # Bronze Shield
   when 2 then [[2, 35, 5]]  # Iron Shield
   when 3 then [[2, 38, 1], [2, 39, 1]]  # Steel Shield
   when 4 then [[2, 36, 3], [2, 40, 2]]  # Mythirl Shield
   when 5 then [[2, 35, 1]]  # Bronze Helm
   when 6 then [[2, 35, 1], [2, 37, 1]]  # Iron Helm
   when 7 then [[2, 40, 1], [2, 35, 5]]  # Steel Helm
   when 8 then [[1, 6, 1], [2, 38, 1], [2, 37, 2]]  # Mythril Helm
   when 9 then [[2, 35, 1]]  # Cotton hat
   when 10 then [[2, 39, 1]]  # Felt Hat
   when 11 then [[2, 37, 2], [2, 7, 1]]  # Magic Hat
   when 12 then [[2, 41, 1]]  # Saint Hat
   when 13 then [[2, 35, 1]]  # Bronze Armor
   when 14 then [[2, 36, 1]]  # Iron Armor
   when 15 then [[2, 38, 2], [2, 1, 5]]  # Steel Armor
   when 16 then [[2, 37, 5]]  # Mythril Armor
   when 17 then [[2, 35, 1]]  # Bronze Plate
   when 18 then [[2, 40, 1]]  # Iron Plate
   when 19 then [[2, 39, 4]]  # Steel Plate
   when 20 then [[2, 36, 5], [2, 38, 1]]  # Mythril Plate
   when 21 then [[2, 35, 1]]  # Cotton Robe
   when 22 then [[2, 36, 1], [2, 37, 1]]  # Felt Robe
   when 23 then [[2, 40, 3], [2, 9, 5]]  # Magic Robe
   when 24 then [[2, 41, 1], [2, 38, 1]]  # Saint Robe
   when 25 then [[2, 36, 5]]  # Titan Ring
   when 26 then [[2, 38, 5]]  # Archer Ring
   when 27 then [[2, 39, 5]]  # Flash Ring
   when 28 then [[2, 40, 5]]  # Wisdom Ring
   when 29 then [[2, 49, 1], [2, 40, 2]]  # Flame Ring
   when 30 then [[2, 43, 1], [2, 38, 2]]  # Ice Ring
   when 31 then [[2, 39, 3], [2, 48, 1]]  # Thunder Ring
   when 32 then [[2, 45, 1], [2, 37, 3]]  # Aqua Ring
   when 33 then [[2, 36, 10]] #Shield
   when 34 then [[1, 4, 1], [2, 12, 3], [2, 51, 1]]  # Hero Shield
   when 35 then [[1, 8, 1], [2, 41, 1], [2, 53, 1]]  # Cross Helmet
   when 36 then [[1, 16, 1], [1, 27, 5]]  # Dragoon Armor
   when 37 then [[2, 54, 2], [2, 37, 5]]  # Raven Cloak
   when 38 then [[1, 12, 1], [1, 28, 3], [2, 54, 1]]  # Wizard Hat
   when 39 then [[1, 25, 1], [1, 26, 1], [1, 27, 1], [1, 28, 1], [1, 14, 1]]  # Battle Armor
   when 40 then [[1, 4, 1], [2, 54, 2], [2, 52, 1]]  # Magic Shield
   when 41 then [[1, 10, 1], [2, 41, 1], [2, 53, 1]]  # Boots of Abundance
   when 42 then [[2, 50, 1], [2, 44, 1], [2, 38, 5]]  # Boost Shades
   when 43 then [[2, 46, 1], [2, 47, 1], [2, 37, 5]]  # Valkyrie Shield
   end
 end

 def self.item_forges(id)
   return case id
   when 3 then [[2, 1, 1], [2, 35, 3]]  # Majilixer
   when 4 then [[2, 2, 1], [2, 36, 1]]  # Mana Tree Sap
   when 5 then [[2, 1, 1], [2, 2, 1], [2, 39, 2]]  # Manalixir
   when 6 then [[2, 41, 1], [2, 38, 1], [2, 39, 1], [2, 37, 1]]  # Great Remedy
   when 7 then [[2, 1, 4], [2, 40, 2]]  # Grand Cure
   when 8 then [[2, 2, 4], [2, 38, 2]]  # Mana Fountain
   when 10 then [[2, 53, 1]]  # Yggdrasil Leaf
   when 12 then [[2, 51, 1]]  # Siren Rain
   when 43 then [[2, 35, 10]]  # Ice Orb
   when 44 then [[2, 37, 5]]  # Dark Orb
   when 45 then [[2, 38, 5]]  # Aqua Orb
   when 46 then [[2, 36, 5]]  # Earth Orb
   when 47 then [[2, 39, 2], [2, 38, 2]]  # Wind Orb
   when 48 then [[2, 39, 5]]  # Thunder Orb
   when 49 then [[2, 40, 3]]  # Fire Orb
   when 50 then [[2, 38, 2], [2, 37, 2]]  # Light Orb
   when 51 then [[2, 52, 1]]  # Fortune Cat
   when 52 then [[2, 53, 1]]  # Hammer Charm
   when 53 then [[2, 54, 1]]  # Star Fragment
   when 54 then [[2, 51, 1]]  # Wisdom Stone
   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 self.weapon_forges(id)
 end

 def self.armor_extractions(id)
   return self.armor_forges(id)
 end

 def self.item_extractions(id)
   return self.item_forges(id)
 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 [0, 0]
 end

 def self.armor_gold(id)
   return [0, 0]
 end

 def self.item_gold(id)
   return [0, 0]
 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 38 then [['DEX', 3]]
   when 39 then [['AGI', 3]]
   when 40 then [['INT', 3]]
   when 51 then [['DEX', 3], ['AGI', 3], ['INT', 3]]
   when 52 then [['DEX', 10]]
   when 53 then [['AGI', 10]]
   when 54 then [['INT', 10]]
   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 nil  # No configuration defined
 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 43 then [[1, 2], ]
   when 44 then [[1, 8], ]
   when 45 then [[1, 4], ]
   when 46 then [[1, 5], ]
   when 47 then [[1, 6], ]
   when 48 then [[1, 3], ]
   when 49 then [[1, 1], ]
   when 50 then [[1, 7], ]
   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 100
 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 == nil
     if old.is_a?(RPG::Weapon) && $data_classes.weapon_set.include?(old.id)
       $data_classes.weapon_set.push(new.id)
     elsif old.is_a?(RPG::Armor) && $data_classes.armor_set.include?(old.id)
       $data_classes.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)  
     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)  
     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)
     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

  •        when 0
             item = $data_weapons[@materials[1]]
             enough = $game_party.weapon_number(item.id) >= @materials[2]
           when 1
             item = $data_armors[@materials[1]]
             enough = $game_party.armor_number(item.id) >= @materials[2]
           when 2
             item = $data_items[@materials[1]]
             enough = $game_party.item_number(item.id) >= @materials[2]
           end
           next if item == nil
           # Set local variable to store required amount of this item.
           required = @materials[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.x, @sprites.y = 380, 194 + (i * 64)#(i * 34)
         @sprites.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
         # 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
         if @sprites.bitmap != nil
           w = @sprites.bitmap.width / 4
           h = @sprites.bitmap.height / 4
           x = (@count / 10) * w
           @sprites.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

Spoiler: ShowHide

ForeverZer0

I will check it out right now.
I do see one error, likely with the config program. I thought I had fixed it version 1.1, but I may be wrong. See this:
  def self.enchant_elements(item_id)
    return case item_id
    when 43 then [[1, 2], ]
    when 44 then [[1, 8], ]
    when 45 then [[1, 4], ]
    when 46 then [[1, 5], ]
    when 47 then [[1, 6], ]
    when 48 then [[1, 3], ]
    when 49 then [[1, 1], ]
    when 50 then [[1, 7], ]
    end
  end


The ", " should not be at the end of each array.  I will do some testing and get back to you. I doubt that the error with the commas is causing your problem. It sounds like the .rxdata file is not being saved appropriately.

Just as a check real quick, are you using the version 1.1 of the config program?
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Kirye

Yeah, i'm using the 1.1 version. I fixed the commas anyway.

Spoiler: ShowHide

ForeverZer0

Yeah, it is still an error in the program.
I just fixed it, though I haven't re-uploaded it yet. I want to check the actual script for the problem you were having first, so tht the embedded version doesn't have the same bug.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Kirye

Alright, thanks alot for the help! This script is bad ass and I enjoy using it.

Spoiler: ShowHide

ForeverZer0

I just noticed a second problem as well. If you enchant a piece of equipment that is equipped and only have one of them, the game will not automatically change the actors equipment.

I'll see what I can do with these. It might not be till tomorrow before I get a chance to fix them and debug it all.
I also wanted to add the option to rename new equipment, so I MAY see what that is going to require and include it with the update.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

PhoenixFire

Any progress with the new patch? I'll probably download it, mess around a bit with it, and add it to T.E.P. if I can figure it all out..
Quote from: Subsonic_Noise on July 01, 2011, 02:42:19 amNext off, how to create a first person shooter using microsoft excel.

Quote from: Zeriab on September 09, 2011, 02:58:58 pm<Remember when computers had turbo buttons?

rayquaza1000

Hey! I keep on getting this error when i talk to my blacksmith! :facepalm: :???: :O.o: :P :uhm: :facepalm:

Syntax error occured while running script[/size][/b][/i][/u]

Help!!!!!!!!!!!!!
Meow

ForeverZer0

That means the script call is not set up right.  Post a screen of your blacksmith's event page, and I'll tell you where the error is.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Magus

Okay... I'm going to try out this system. You better not fail me D:::::
LEVEL ME DOWN. THE ANTI-BLIZZ GROUP IS AMONG YOU... Do it for the chick below...She watches..<br />

hyakkivn

A wonderful tool for RMXP noob user like me  :^_^':
Very easy to use and config.
ForeverZero, you and these guys in this 4rum really amazing.

Shining Riku

This script is incredible, and I've found it to be a fun addition to one of my games but I noticed an issue with the Enchantments option:

When you go into the menu and select an item to use to enchant an item, even if the item is completely run out and at 0, you can still use it to enchant a weapon or armor piece, and this can be done endlessly.

It also doesn't acknowledge the cost of using said upgrade. No money is spent even if it's configured D:

I'd edit the script and fix this myself but I don't have the knowledge for this yet.
If you could fix this, that'd be really appreciated :D
I hope I explained it well enough without seeming pretentious  :negative:

Xuroth

can you use this to create multiple recipes for an item?
for example:
to make a chaos sword (no enchantments) you need:
1 chaos essence
1 mithril sword
but if you dont have a mithril sword but you have its reqs:
3 mithril ores
1 wrapped hilt
You should be able to use:
3 mithril ores
1 wrapped hilt
1 chaos essence
For not having all the specific items (and because the smith will "forge" the sword then add the essence) you should have to pay the fee of both making the mithril sword and the chaos sword together.

Just curious...

KK20

Quote from: Xuroth on October 12, 2011, 03:52:59 am
can you use this to create multiple recipes for an item?
for example:
to make a chaos sword (no enchantments) you need:
1 chaos essence
1 mithril sword
but if you dont have a mithril sword but you have its reqs:
3 mithril ores
1 wrapped hilt
You should be able to use:
3 mithril ores
1 wrapped hilt
1 chaos essence
For not having all the specific items (and because the smith will "forge" the sword then add the essence) you should have to pay the fee of both making the mithril sword and the chaos sword together.

Just curious...
I'm not sure if it works exactly like that. I'm assuming it doesn't. But that doesn't mean you can't just forge a mithril sword and then use that sword to make a chaos sword.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Xuroth

that was a poor example of what I was asking, so I apologize. I meant more like having two separate methods to create the same thing.

KK20

According to the setup, each item/weapon/armor has only one recipe. I'm sure it's more than possible to edit the script to satisfy your needs, but at the current state of the script, no, it's not possible. (Anyone correct me if I'm wrong)

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

ForeverZer0

Currently their is only support for one combination per item. You could work around this by creating copies of the same item, but that would look kinda strange in the inventory screen.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Xuroth


ForeverZer0

No, it really doesn't work like that. There isn't any really quick edit that will change it, the configuration and all the calls to it would need to be altered to support it.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Magus

Oh, I never followed up. But without this script, I think a chunk of my game would die... D: (Simply because the use of forging to get a stronger weapon is where its at.)
LEVEL ME DOWN. THE ANTI-BLIZZ GROUP IS AMONG YOU... Do it for the chick below...She watches..<br />

ForeverZer0

Glad you like it.

When I was making it, I had dreams of creating a Vagrant Story type system. Sadly, I never got around to creating it. :'(
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

xxo60

Great script.

only one problem. I downloaded the program and went to the cache script. I pasted it in the script editor and put the file created on the anvil. Then I copied the blacksmith event from the example in my game. Also i put all the new icons (like ores) in my game folder. I added some recipes. When i try to use the blacksmith i get a pop-up box with the following text: 'NameError occured while running script. uninitialized constant Interpreter::Scene_Blacksmith'. Then Rpg-maker closes.

Could you help me solve this problem?

ForeverZer0

I think there may be a bug with the name. Do a search and replace of Scene_Blacksmith and change it to Scene_BlackSmith, with a capital "S".
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

chaucer

I know its a weird question but is it possible to only show the Weapons/Items/Armors you can make when you have all the required Materials?
like here would be the setup as an example
w = [ 12, 21 ]
a = [ 14 ]
i = [ 11 ]
$scene = Scene_Blacksmith.new(w, a, i)
and when you talk to the blacksmith without any of the required items for these recipes it will not show them on the Forge Screen?
just wondering.

ForeverZer0

It would likely be a pretty minor edit. I don't script for RMXP anymore, and I barely even still offer support on scripts I wrote. It should not be very difficult if someone else were to decide to help you out, though.

* Stares at the remaining scripters of the forum *
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

KK20

*casually walks in*
Window_BlacksmithForge: ShowHide
#===============================================================================
# ** 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
    # Keep only items that you have materials for
    @new_data = []
    @data.each{|i|
      case i
      when RPG::Weapon
        type = 0
      when RPG::Armor
        type = 1
      when RPG::Item
        type = 2
      end
      @new_data.push(i) if Blacksmith.materials?(type, i.id)
    }
    @data = @new_data
    # 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
CTRL + F for "Window_BlacksmithForge" and replace with this. It's been a while since I've looked at any programming, so I threw this together pretty quick. Obviously someone can find a way to hack this down a few lines shorter.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

chaucer


michaelsan

January 17, 2012, 12:28:34 am #115 Last Edit: January 17, 2012, 12:30:39 am by game_guy
Hi ForeverZer0 Thankz for the excellent script :) I´m sure using this on my project :) But can i ask If you could add a new feature to it? If yes then i would like (and i think many people too) If you could have an option for using an Image as layout instead of the windowskin like the mog menu or something like that :)

Thkz for the script I love it :D Hope you can make the feature :)

Re-Edited Subject to avoid confusion. ~ G_G

RPGamer5

Hi, i would really like to include this in my project (with proper credit of course), but i get an argument error if i call the Scene_BlackSmith.new:
"line 349: comparison of Fixnum with nil failed"
# Check gold, skipping item check if there is not enough.
if $game_party.gold >= materials[1][0]

Since i have no scripting knowledge, any help would be appreciated.
Btw, i also use Blizz-ABS if it matters

And i'm sorry if i dug up an old thread

Skwig

Hello, i have a problem with this script.. I did everything and copied it and such, and it says Syntax error which means i did something wrong with events
soo.. Also i use the version 2.0
Here you have the event window thing

Thanks

Taiine

Question.
Can the shop be split? As in, a call for just the forging,and another for taking things apart? I'd like to split it between two npc's, one being the smith that will forge items from parts, and another that will take items apart into their base items.

ForeverZer0

@Skwig:
Try putting the arguments on the same line: 
$scene = Scene_Blacksmith.new(w,a,i,l)


or at least the leading parenthesis:

$scene = Scene_Blacksmith.new(
w,a,i,l)


@Taiine:
Yes, it could be. It would be a relatively simple edit to the scene to change the options. 
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Taiine

Could you then please? I'll give you lots of hugs :3

KK20

February 24, 2012, 06:53:49 pm #121 Last Edit: February 24, 2012, 06:55:04 pm by KK20
Class Window_BlacksmithCommand: ShowHide
#===============================================================================
# ** Window_BlacksmithCommand
#===============================================================================

class Window_BlacksmithCommand < Window_Selectable
 
  def initialize(level, type = 0)
    super(0, 64, 480, 64)
    @level = level
    @commands = []
    # Determine which shop this is
    case type
    when 1 then @commands.push('Forge')
    when 2 then @commands.push('Extract')
    when 0
      @commands.push('Forge')
      @commands.push('Extract')
    end
    # If the game allows enchantments
    if Blacksmith::USE_ENCHANTMENTS
      @commands.push('Enchant')
    end
    @commands.push('Exit')
    @item_max = @column_max = @commands.size
   
    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
  #-----------------------------------------------------------------------------
  def at_index
    return @commands[@index]
  end
end

Class Scene_Blacksmith: ShowHide
#===============================================================================
# ** Scene_Blacksmith
#===============================================================================

class Scene_Blacksmith
 
  def initialize(type = 0, 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
    @type = type
  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, @type)
    @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.at_index
    when "Forge" then 'Use materials to forge new weapons, armors, and items.'
    when "Extract" then 'Extract materials from weapons, armors, and items.'
    when "Enchant" then 'Enchant weapons, armors, and items using other items.'
    when "Exit" 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.at_index
      when "Forge"
        # 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 "Extract"
        # 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 "Enchant"
        # 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 "Exit"
        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.at_index == "Forge"
        @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.at_index == "Forge"
        @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.at_index == "Forge" ? 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


Script call has been modified to the following:
$scene = Scene_Blacksmith.new(type, weapons, armors, items, level)
where "type" refers to what shop you want. "type" is an integer. These values do the following:
0 => Forge and Extract
1 => Forge only
2 => Extract only

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Skwig

Quote from: Darth Dastardly on February 24, 2012, 05:06:41 pm
@Skwig:
Try putting the arguments on the same line: 
$scene = Scene_Blacksmith.new(w,a,i,l)


or at least the leading parenthesis:

$scene = Scene_Blacksmith.new(
w,a,i,l)



it is in one line, but the line is too long for the editor window
will try the other option, though

ForeverZer0

Alternatively you could also do this:

$scene = 
Scene_Blacksmith.new(w,a,i,l)
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Skwig

Quote from: Darth Dastardly on February 24, 2012, 08:02:15 pm
Alternatively you could also do this:

$scene = 
Scene_Blacksmith.new(w,a,i,l)


Thanks, it worked now...

@KK20 - could you do a more retard noob friendly explanation how to set up your edit of script? i have it all copied and wondering if i should replace the parts that you edited or something...
Thanks

RPGamer5

Bump
Still have the "comparison of Fixnum with nil failed" error!

LiTTleDRAgo

Quote from: RPGamer5 on February 21, 2012, 11:55:24 am
Hi, i would really like to include this in my project (with proper credit of course), but i get an argument error if i call the Scene_BlackSmith.new:
"line 349: comparison of Fixnum with nil failed"
# Check gold, skipping item check if there is not enough.
if $game_party.gold >= materials[1][0]

Since i have no scripting knowledge, any help would be appreciated.
Btw, i also use Blizz-ABS if it matters

And i'm sorry if i dug up an old thread


try changing that line to

if !materials[1][0].nil? && $game_party.gold >= materials[1][0]

Taiine

Thanks muchly *HUG*, though I forgot this had enchanting to. Can that also be split off?


KK20

Quote from: Taiine on February 25, 2012, 12:25:54 pm
Thanks muchly *HUG*, though I forgot this had enchanting to. Can that also be split off?

Class Window_BlacksmithCommand: ShowHide
#===============================================================================
# ** Window_BlacksmithCommand
#===============================================================================

class Window_BlacksmithCommand < Window_Selectable
 
  def initialize(level, type = 0)
    super(0, 64, 480, 64)
    @level = level
    @commands = []
    # Determine which shop this is
    case type
    when 1 then @commands.push('Forge')
    when 2 then @commands.push('Extract')
    when 0
      @commands.push('Forge')
      @commands.push('Extract')
    end
    # If the game allows enchantments
    if Blacksmith::USE_ENCHANTMENTS or (!Blacksmith::USE_ENCHANTMENTS and type == 3)
      @commands.push('Enchant')
    end
    @commands.push('Exit')
    @item_max = @column_max = @commands.size
   
    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
  #-----------------------------------------------------------------------------
  def at_index
    return @commands[@index]
  end
end

Class Scene_Blacksmith: ShowHide
#===============================================================================
# ** Scene_Blacksmith
#===============================================================================

class Scene_Blacksmith
 
  def initialize(type = 0, 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])
    @type = type
  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, @type)
    @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.at_index
    when "Forge" then 'Use materials to forge new weapons, armors, and items.'
    when "Extract" then 'Extract materials from weapons, armors, and items.'
    when "Enchant" then 'Enchant weapons, armors, and items using other items.'
    when "Exit" 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.at_index
      when "Forge"
        # 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 "Extract"
        # 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 "Enchant"
        # Play SE and return if option is locked.
        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
      when "Exit"
        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.at_index == "Forge"
        @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.at_index == "Forge"
        @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.at_index == "Forge" ? 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
Replace my old edit with these. Go into the configuration, set USE_ENCHANTMENTS equal to false. When calling up the blacksmith scene, set 'type' to 3. That will allow you to make an Enchantment-only shop. Leaving USE_ENCHANTMENTS equal to true will always push the enchantment as an available option, regardless of what value you set 'type' to.

Quote from: Skwig on February 25, 2012, 03:25:14 am
@KK20 - could you do a more retard noob friendly explanation how to set up your edit of script? i have it all copied and wondering if i should replace the parts that you edited or something...
Thanks

The edits I made were by request from Taiine, but if you would like the edit too, then do this.

1.)Obviously, copy and paste my edits into your game. They should be placed before 'Main' but after the original Blacksmith script(s).
2.) The NPC script call setup is still mostly the same. However, it should look a little like this:
Spoiler: ShowHide
where the letter 'T' can be any value from 0 to 3. As I posted before, the type of shop that opens up depends on what value you set 'T' to.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Skwig

@KK20 - for slower people such as me you should add these notes somewhere:
- The number that defines T can't be in [ ]s
- When using this edit, remove the line in script call that defines L
- In the final line, t should be in the beginning ( $scene = Scene_Blacksmith.new(t, w, a, i) )

That's probably all.. would speed up the process of setting it up

KK20

Quote from: Skwig on February 25, 2012, 02:37:01 pm
@KK20 - for slower people such as me you should add these notes somewhere:
- The number that defines T can't be in [ ]s
- When using this edit, remove the line in script call that defines L
- In the final line, t should be in the beginning ( $scene = Scene_Blacksmith.new(t, w, a, i) )

That's probably all.. would speed up the process of setting it up


I stated that 'type' is an integer, not an array.
[0] (an array) is not the same as 0 (an integer).

You don't have to remove "L". That's an optional parameter. It's unrelated to my edit.
I also said that the configuration has been changed to:
$scene = Scene_Blacksmith.new(type, weapon, armor, items, level)
In the world of programming, you can't change the order of the arguments and expect the system to understand what parameter each value satisfies.

But as long as you got it working, I am content.  :)

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Shining Riku

I have a problem that needs fixing, if somebody could help me sort this out I'd be STOKED, man.

The enchanting system is kinda broken at the moment because it doesn't take any of your money when you use one of the items to enchant. Also, if you have 0 of the item in question when enchanting you can still "enchant" things.

I need to be able to lock the items that aren't in the inventory and to also fix it so it actually costs you the set price of the enchantment.
As it is now somebody could run into the enchantment shop and max the stats out on their starting weapon and it's...troublesome having such a fun feature
be so broken.

I could probably word this better but, if anybody has any questions for me to answer to clear this up please ask.

BTW I HAVE gone into the script and I feel like I've pinned down where the problem is but I have limited experience fixing these things. I believe it's missing just a few lines to acknowledge the enchantment price set to each item that's used to enchant and remove said price from the player's wallet.
It also lacks the ability to lock the options or "grey them out" when the player doesn't have enough money or doesn't have the item.

sirSLR

March 16, 2012, 05:17:16 pm #133 Last Edit: March 16, 2012, 05:30:31 pm by sirSLR
uhm when i take a staff that fires magic ball when atacking and i enchant it it no more fires an energy ball but instead slashes like a sword... Any way to not change that attack type?

EDIT : and also when item number for enchanting reaches 0 i can keep enchanting.

Magus

Not sure if I posted this yet, but this is like one of the best scripts ever. It's the heart of my game and if this is removed, my game would die xD.
Seriously, I'm curious about your next releases :3
I have to say though, the idea where you can even extract the materials from the object/weapon that you find was a splendid idea. Nice.  Good thing this forum doesn't have a rating system or I'd be hated for rating a lot of people's scripts 10/10.

But back to what I was saying, I wasn't until recently that I noticed: "wait, wtf, wait a sec. THERE'S AN EXTRACTION SYSTEM TOO. Oshi :o"


LEVEL ME DOWN. THE ANTI-BLIZZ GROUP IS AMONG YOU... Do it for the chick below...She watches..<br />

ForeverZer0

Lol, thanks. :)

I think there is still a minor bug with the extraction part, wherein the player can continue to extract after the piece of equipment has ran out. I forgot to put an additional check in there somewhere apparently.

I really can't find the ambition to write scripts for RGSS anymore, so I haven't really even looked into fixing it. If someone would be so kind to do so, I would be very thankful. It will probably only require a "if $game_party.whatever_number(ID) > 0", so it would not take much work. I'd be sure to add a very special thanks to the re-uploaded script, too.

Anyways, thanks for your kind feedback. ;)
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

sinister678

hey i just started to look at scripts for my game and i was wonder how to activate this script im really really new at this so i have no clue what im doing

KK20

It says it right there in the script under "Instructions". At least check the demo out and see an example of how to call it.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

PhoenixFire

Quote from: KK20 on December 31, 2013, 12:40:15 am
At least check the demo out and see an example of how to call it.



Yeah. That's usually the best place to start... Usually...
Quote from: Subsonic_Noise on July 01, 2011, 02:42:19 amNext off, how to create a first person shooter using microsoft excel.

Quote from: Zeriab on September 09, 2011, 02:58:58 pm<Remember when computers had turbo buttons?

KK20

January 02, 2014, 03:10:25 pm #139 Last Edit: January 02, 2014, 03:13:20 pm by KK20
Quote from: ForeverZer0 on April 09, 2012, 05:35:33 pm
I really can't find the ambition to write scripts for RGSS anymore, so I haven't really even looked into fixing it. If someone would be so kind to do so, I would be very thankful. It will probably only require a "if $game_party.whatever_number(ID) > 0", so it would not take much work. I'd be sure to add a very special thanks to the re-uploaded script, too.

I know this was a long time ago, and I'm sorry for not getting to it sooner. I guess people just stopped talking about it for a while and I forgot about the bugs.

I fixed a lot of graphical and functional bugs.

http://pastebin.com/AFrMCa2f

Looking for feedback and any more things that should be added/fixed.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Siffers

Quote from: KK20 on January 02, 2014, 03:10:25 pm
I know this was a long time ago, and I'm sorry for not getting to it sooner. I guess people just stopped talking about it for a while and I forgot about the bugs.

I fixed a lot of graphical and functional bugs.

http://pastebin.com/AFrMCa2f

Looking for feedback and any more things that should be added/fixed.


Glad someone decided to pick this one back it, it's a really amazing script!

So I tossed the script back into my game and ended up with an error.
Made a fresh game with no scripts or changes to make sure it wasn't just an issue with my game.
Still got the error, so I thought I would post it here.

It happens when attempting to call the shop using
w = [1]
a = []
i = [1,2]
$scene = Scene_BlackSmith.new(w,a,i)

NameError occurred while running script.
uninitialized constant Interpreter::Scene_BlackSmith


ForeverZer0

There is some error in the config program that outputs the name of the class with a different capitalization. I don't think I have the source files anymore, haven't really looked. All you need to do is as LiTTleDRAgo pointed out, and change the "S" in the word.
I am done scripting for RMXP. I will likely not offer support for even my own scripts anymore, but feel free to ask on the forum, there are plenty of other talented scripters that can help you.

Siffers

Quote from: ForeverZer0 on March 03, 2014, 01:08:58 pm
There is some error in the config program that outputs the name of the class with a different capitalization. I don't think I have the source files anymore, haven't really looked. All you need to do is as LiTTleDRAgo pointed out, and change the "S" in the word.


Oh, haha well that was a simple fix!
Thank you both for the quick reply  :xD:

StorocnekXx

Heyho. :)

First of all, thank you for this great script!
Since I'd really like to use it, I'd like to ask if there is the possibility and the person who wants to do so to modify the script, that is has some kind of delayed crafting (and Lvl system).
What I'm talking about is this:
If I want to create Item1 in the forge, by using the items and paying stuff like usual, I want the player to be unable to create more things unless a certain play-time has passed. Something like a little progress bar is shown if the smithting script at exactly that smithing point, if the players opens it. That means, different forges can worke side by side, and if forge1 creates item1, forge2 can be used as normal and so on.
Maybe, at the same time it's possible to create a smithing level. Creating an Item/Weappon/Armor gives smithing-experience. If the smithing experience increases, the player gains smithing-lvls. The higher this lvl, the lower the costs of crafting, the higher the money gotten from extracting, the faster the progressing-time passes over and the better items can be crafted.
The lvl-part is not the most important thing though, but something like tha delayed-progress (see above) would really help me out a lot. :)
Thank you for reading this!
I may have a lot of ideas to use, but I have no idea how to use them.

edmondedi

Uhm, i have a problem with the script, because i'm using Bliz ABS in the same priject, and it always gives me an error message.
What should i do? Or this script is not compatibile with the Blizz ABS?  :???:

KK20

How about posting what the error message is so we can determine if it is a compatibility issue or not.
I do believe that the Enhancement part of this script is not compatible (though I think that's not too hard to fix without a little tinkering).

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Sin86

January 17, 2018, 11:26:36 pm #147 Last Edit: January 18, 2018, 12:32:47 am by Sin86
I already have the script but in order to learn from it, I need the demo and the configuration tool and I do not have those. Anybody still have the demo and configuration tool? Links no longer work.

Also, found a crash if you try to create an armor smith.

Script Blacksmith shop line 349:ArgumentError occurred

Comparison of Fixnum with nil failed

Now the lines may vary but this is with KK20's version, the most fixed version completely unedited so it should be at line 349. It happens if the code looks like this.

w = [1]
a = [1]
$scene = Scene_Blacksmith.new(w, a)


Again, this is only if I have a = whatever as well as the a after the blacksmith.new part. The w aspect is fine though.

KK20

Again, as I tell everyone, PM ForeverZer0 to see if he can reupload his dropbox links. That was seriously such a stupid move on their part that I'll never understand.

As for the error, you need to configure the gold prices for armor.

  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


You're not the first to report this either. I'll create some dummy values so people can stop reporting this.

Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!

Sin86

November 11, 2018, 10:40:05 pm #149 Last Edit: November 11, 2018, 10:54:11 pm by Sin86
Thanks for the help. Sorry that I'm months late. Anyway, I'm trying to figure this other part out.

I have a shop that is set to use weapons 1 and 3 and armor 1


w = [3,4]
a = [1]
i = 5
$scene = Scene_Blacksmith.new(w, a, i)


Shop opens up normally, but then it still allows me to extract, which I'm trying to disable. I look in the instructions and it says to use these with true/false values.

[CAN_FORGE?, CAN_EXTRACT?, CAN_ENCHANT?]

However, if I use:

w = [3,4]
a = [1]
$scene = Scene_Blacksmith.new(w, a)
[CAN_EXTRACT? = false]


I get an error. Now, I guess I am doing it wrong but the instructions are not giving me examples of how it should be done.

Wait, never mind, I found out how it is done. It has to be like this:

Quotew = [3,4]
a = [1]
i = [5]
l = [true, false, false]
$scene=Scene_Blacksmith.new(w,a,i,l)

the newguy


Drak

Hello!
I can't use this script. When I call it into the map, I receive a warning saying: unitialized constant interpreter, Scene_BlackSmith.
I'm not a programmer and just like to play with RPGM.
Can you give me some help to fix it?

Thanks!

KK20


Other Projects
RPG Maker XP Ace  Upgrade RMXP to RMVXA performance!
XPA Tilemap  Tilemap rewrite with many features, including custom resolution!

Nintendo Switch Friend Code: 8310-1917-5318
Discord: KK20 Tyler#8901

Join the CP Discord Server!