Envision, Create, Share

Welcome to HBGames, a leading amateur game development forum and Discord server. All are welcome, and amongst our ranks you will find experts in their field from all aspects of video game design and development.

PrexCraft - Crafting Script

PrexCraft
Version: 2.0

Introduction

Similar to Axe Man Deke's crafting script, this is PrexCraft

Allows you to generate any number of recipes, quickly and easily. Offers multiple components, one result, consumable and non-consumable components, and a quick and simple interface.

V1.01: Fixed a small bug allowing for the same recipe to be learned more than once.

V1.02: Removed the Elements module, as it was brought to my attention that I could use $data_system.elements[]

v2.0: Added many new features. These are listed below in the Features section.

Features
  • Quick and Easy!
  • Multiple Components
  • Built-In Interface!
New in 2.0!
  • Recipe Types! You can now separate cooking recipes from smithing, tailoring, or anything you wish!
  • Recipe and Trade Levels! You can now apply trade levels to your party, allowing you to level up skills and be capable of new recipes!
  • Icons! You can now enable and disable icons in each of the three Craft windows.

Demo

Version 1.0 Demo hosted at rm-dev.org (Out of Date!)

Version 2.0 Demo hosted at rm-dev.org

Script

Code:
#===============================================================================

# Module Craft by Prexus

#  - Version 2.0 (12.31.06)

#-------------------------------------------------------------------------------

# This is the primary module of the PrexCraft script. Be sure to read the

# instructions to learn how to create new recipes. Do not change any of the

# constants in the DO NOT TOUCH section.

#===============================================================================

 

module Craft

  #=============================================================================

  # CONSTANTS :: DO NOT TOUCH

  #=============================================================================

  ITEM = 0; ARMOR = 1; WEAPON = 2

  NOT_CONSUMED = false; CONSUMED = true;

  

  #=============================================================================

  # CONSTANTS :: PLEASE TOUCH THESE.. BABY!

  #=============================================================================

  USE_LEVELS           = true  # Use Levels for skills.

  SHOW_COLORS          = true  # Use colorcoding (only for Levels)

  SHOW_LEVELS          = true  # Show recipe level display

  SHOW_LEVEL_UP        = true  # Show level up window

  SHOW_LIST_ICONS      = true  # Show icons in recipe list

  SHOW_RESULT_ICON     = true  # Show icons in result window

  SHOW_COMPONENT_ICONS = true  # Show icons in component window

  

  #=============================================================================

  # TRADE :: OFFSET LEVEL RANGE (edit with caution) (For use with levels only)

  #=============================================================================

  TRADE_LEVEL_OFFSET = 10

  

  #=============================================================================

  # COLORS :: EDIT WITH CAUTION (For use with Levels only)

  #=============================================================================

  TRIVIAL    = Color.new( 64,  64,  64, 255)

  LOW        = Color.new(  0, 255,   0, 255)

  MID        = Color.new(255, 255,   0, 255)

  HIGH       = Color.new(255, 128,   0, 255)

  IMPOSSIBLE = Color.new(255,   0,   0, 255)

  

  #=============================================================================

  # RECIPES :: Follow Instructions

  #-----------------------------------------------------------------------------

  # FORMAT :

  # {'NAME' => 'RECIPE NAME AS STRING',

  #  'TYPE' => 'RECIPE TYPE AS STRING',

  #  'LEVEL' => LEVEL_AS_INTEGER,  << Not Necessary with USE_LEVELS set to False

  #  'RESULT' => [TYPE, ID, VALUE],

  #  'COMPONENTS' => [

  #    [TYPE, ID, VALUE, CONSUMED?],

  #    [TYPE, ID, VALUE, CONSUMED?],

  #    ...

  #  ]

  # }

  #-----------------------------------------------------------------------------

  # To setup a recipe, follow the example below:

  #-----------------------------------------------------------------------------

  # {'NAME' => 'Cold Iron Sword',

  #  'TYPE' => 'Blacksmith',

  #  'LEVEL' => 10,

  #  'RESULT' => [WEAPON, 1, 1],

  #  'COMPONENTS' => [

  #    [ITEM, 1, 1, CONSUMED],

  #    [ITEM, 2, 1, CONSUMED],

  #    [WEAPON, 3, 1, NOT_CONSUMED]

  #  ]

  # } # End Recipe [WEAPON, 1, 1]

  #=============================================================================

  RECIPES = [

    {'NAME' => 'Cold Sword',

     'TYPE' => 'Blacksmith',

     'LEVEL' => 1,

     'RESULT' => [WEAPON, 33, 1],

     'COMPONENTS' => [

       [ITEM, 33, 1, CONSUMED],

       [WEAPON, 1, 1, CONSUMED]

     ]

    },

    {'NAME' => 'Tempered Sword',

     'TYPE' => 'Blacksmith',

     'LEVEL' => 20,

     'RESULT' => [WEAPON, 34, 1],

     'COMPONENTS' => [

       [ITEM, 38, 1, NOT_CONSUMED],

       [WEAPON, 1, 1, CONSUMED]

     ]

    },

    {'NAME' => 'Apple Pie',

     'TYPE' => 'Cook',

     'LEVEL' => 1,

     'RESULT' => [ITEM, 36, 1],

     'COMPONENTS' => [

       [ITEM, 34, 1, NOT_CONSUMED],

       [ITEM, 35, 3, CONSUMED]

     ]

    }

  ]

  

  #=============================================================================

  # Craft Methods

  #-----------------------------------------------------------------------------

  # valid_recipe? : name

  # Checks if the recipe name given exists in the recipe data store.

  #=============================================================================

  def self.valid_recipe?(name)

    for recipe in RECIPES

      return true if name == recipe['NAME']

    end

    return false

  end

  

  #=============================================================================

  # Craft Methods

  #-----------------------------------------------------------------------------

  # can_make? : name

  # Checks if the recipe is possible to make. First finds if the recipe given is

  # valid, then checks if there are enough components in your inventory.

  #=============================================================================

  def self.can_make?(name)

    return false unless self.valid_recipe?(name)

    for r in RECIPES

      next unless name == r['NAME']

      recipe = r

    end

    return false unless recipe

    for component in recipe['COMPONENTS']

      case component[0]

      when 0 # ITEM

        return false unless $game_party.item_number(component[1]) >= component[2]

      when 1 # ARMOR

        return false unless $game_party.armor_number(component[1]) >= component[2]

      when 2 # WEAPON

        return false unless $game_party.weapon_number(component[1]) >= component[2]

      end

    end

    return true

  end

  

  #=============================================================================

  # Craft Methods

  #-----------------------------------------------------------------------------

  # get_recipe : name

  # Returns the hash object containing the data information for the recipe if

  # the recipe is valid. Else returns nil.

  #=============================================================================

  def self.get_recipe(name)

    return nil unless self.valid_recipe?(name)

    for recipe in RECIPES

      return recipe if recipe['NAME'] == name

    end

    return nil

  end

  

  #=============================================================================

  # Craft Methods for LEVELS

  #-----------------------------------------------------------------------------

  # color_chart : diff

  # Returns the color suited for the recipe based on the difference between the

  # recipe level and your party's skill level

  #=============================================================================

  def self.color_chart(diff)

    if diff < 0

      return IMPOSSIBLE

    elsif (0...TRADE_LEVEL_OFFSET).to_a.include?(diff)

      return HIGH

    elsif (TRADE_LEVEL_OFFSET...TRADE_LEVEL_OFFSET * 2).to_a.include?(diff)

      return MID

    elsif (TRADE_LEVEL_OFFSET * 2...TRADE_LEVEL_OFFSET * 3).to_a.include?(diff)

      return LOW

    else

      return TRIVIAL

    end

  end

  

  #=============================================================================

  # Craft Methods for LEVELS

  #-----------------------------------------------------------------------------

  # level_skill : skill, diff

  # Raises the level of the skill based on the difference between the recipe

  # level and the party's skill level.

  #=============================================================================

  def self.level_skill(skill, diff)

    if (0...TRADE_LEVEL_OFFSET).to_a.include?(diff)

      if rand(10) >= 1

        $game_party.trade_level_up(skill, 1)

        return true

      else

        return false

      end

    elsif (TRADE_LEVEL_OFFSET...TRADE_LEVEL_OFFSET * 2).to_a.include?(diff)

      if rand(10) >= 3

        $game_party.trade_level_up(skill, 1)

        return true

      else

        return false

      end

    elsif (TRADE_LEVEL_OFFSET * 2...TRADE_LEVEL_OFFSET * 3).to_a.include?(diff)

      if rand(10) >= 6

        $game_party.trade_level_up(skill, 1)

        return true

      else

        return false

      end

    else

      return false

    end

  end

end

 

#===============================================================================

# Scene Craft

#-------------------------------------------------------------------------------

# This is the main interface for the crafting system. You can run it by using

# the callscript command '$scene = Scene_Craft.new' or by adding it to your own

# code in the same manner.

#===============================================================================

 

class Scene_Craft

  def initialize(type = nil)

    @type = type

  end

  def main

    @recipe_list = Window_RecipeList.new(@type)

    @result_info = Window_ResultInfo.new(@recipe_list.data)

    @result_comp = Window_ResultComponents.new(@recipe_list.data)

    Graphics.transition

    loop do

      Graphics.update

      Input.update

      update

      break if $scene != self

    end

    Graphics.freeze

    @recipe_list.dispose

    @result_info.dispose

    @result_comp.dispose

    @level_window.dispose if @level_window

  end

  #-----------------------------------------------------------------------------

  def update

    @recipe_list.update

    @result_info.update(@recipe_list.data)

    @result_comp.update(@recipe_list.data)

    if @level_window

      @level_window.update

      @level_window.opacity -= 2

      @level_window.contents_opacity -= 2

      if @level_window.opacity == 0

        @level_window.dispose

        @level_window = nil

      end

    end

    if Input.trigger?(Input::B)

      $game_system.se_play($data_system.cancel_se)

      $scene = Scene_Map.new

      return

    end

    if Input.trigger?(Input::C)

      if craft(@recipe_list.data)

        $game_system.se_play($data_system.decision_se)

      else

        $game_system.se_play($data_system.buzzer_se)

      end

      @recipe_list.refresh

      @result_info.refresh

      @result_comp.refresh

      return

    end

  end

  #-----------------------------------------------------------------------------

  def craft(recipe)

    return false unless Craft.can_make?(recipe)

    recipe = Craft.get_recipe(@recipe_list.data)

    if Craft::USE_LEVELS

      skill = (recipe['TYPE'] ? recipe['TYPE'] : nil)

      level = (recipe['LEVEL'] ? recipe['LEVEL'] : 1)

      if skill

        return unless $game_party.trade_check?(skill, level)

        diff = ($game_party.trade_skills[skill] - level).abs

        old_level = $game_party.trade_skills[skill]

        if Craft.level_skill(skill, diff)

          if Craft::SHOW_LEVEL_UP

            if @level_window

              @level_window.dispose

              @level_window = nil

            end

            @level_window = Window_Base.new(0, 0, 256, 64)

            @level_window.contents = Bitmap.new(224, 32)

            @level_window.x = 320 - @level_window.width / 2

            @level_window.y = 240 - @level_window.height / 2

            @level_window.z = 9998

            @level_window.contents.draw_text(4, 0, 224, 32,

              "#{skill} +#{($game_party.trade_skills[skill] - old_level).abs}", 1)

          end

        end

      end

    end

    for component in recipe['COMPONENTS']

      case component[0]

      when 0 # Item

        $game_party.lose_item(component[1], component[2]) if component[3]

      when 1 # Armor

        $game_party.lose_armor(component[1], component[2]) if component[3]

      when 2 # Weapon

        $game_party.lose_weapon(component[1], component[2]) if component[3]

      end

    end

    case recipe['RESULT'][0]

    when 0 # Item

      $game_party.gain_item(recipe['RESULT'][1], recipe['RESULT'][2])

    when 1 # Armor

      $game_party.gain_armor(recipe['RESULT'][1], recipe['RESULT'][2])

    when 2 # Weapon

      $game_party.gain_weapon(recipe['RESULT'][1], recipe['RESULT'][2])

    end

    return true

  end

end

 

#===============================================================================

# Window RecipeList

#-------------------------------------------------------------------------------

# This is a standard command window which shows all the recipes known by the

# party. They will appear in White if you have the proper reagents to combine

# or grey otherwise.

#===============================================================================

 

class Window_RecipeList < Window_Selectable

  def initialize(type)

    super(0, 0, 224, 480)

    self.contents = Bitmap.new(width - 32, height - 32)

    @data = []

    @type = type

    refresh

  end

  #-----------------------------------------------------------------------------

  def data

    return @data[self.index]

  end

  #-----------------------------------------------------------------------------

  def refresh

    self.contents.clear

    @data = []

    for recipe in $game_party.recipes

      if @type

        next unless Craft.get_recipe(recipe)['TYPE'] == @type

      end

      @data.push(recipe) if Craft.valid_recipe?(recipe)

    end

    @item_max = @data.size

    self.index = [[self.index, 0].max, @item_max].min

    for i in [email=0..@data.size]0..@data.size[/email]

      data = @data[i]

      next unless data

      x = (Craft::SHOW_LIST_ICONS ? 32 : 4)

      recipe = Craft.get_recipe(data)

      if Craft::SHOW_LIST_ICONS

        case recipe['RESULT'][0]

        when 0 # ITEM

          bitmap = RPG::Cache.icon($data_items[recipe['RESULT'][1]].icon_name)

          self.contents.blt(4, i * 32 + 4, bitmap, Rect.new(0, 0, 24, 24))

        when 1 # ARMOR

          bitmap = RPG::Cache.icon($data_armors[recipe['RESULT'][1]].icon_name)

          self.contents.blt(4, i * 32 + 4, bitmap, Rect.new(0, 0, 24, 24))

        when 2 # WEAPON

          bitmap = RPG::Cache.icon($data_weapons[recipe['RESULT'][1]].icon_name)

          self.contents.blt(4, i * 32 + 4, bitmap, Rect.new(0, 0, 24, 24))

        end

      end

      if Craft::USE_LEVELS

        level = (recipe['LEVEL'] ? recipe['LEVEL'] : 1)

        diff = $game_party.trade_skills[recipe['TYPE']] - level

        if Craft::SHOW_COLORS

          self.contents.font.color = Craft.color_chart(diff)

        else

          self.contents.font.color = (Craft.can_make?(data) ? normal_color : disabled_color)

        end

        if Craft::SHOW_LEVELS

          self.contents.draw_text(x, i * 32, self.contents.width - x, 32,

            "(#{recipe['LEVEL']}) #{data}")

        else

          self.contents.draw_text(x, i * 32, self.contents.width - x, 32, data.to_s)

        end

      else

        self.contents.font.color = (Craft.can_make?(data) ? normal_color : disabled_color)

        self.contents.draw_text(x, i * 32, self.contents.width - x, 32, data.to_s)

      end

    end

  end

end

 

#===============================================================================

# Window ResultInfo

#-------------------------------------------------------------------------------

# This window displays all the information regarding the resulting item.

#===============================================================================

 

class Window_ResultInfo < Window_Base

  def initialize(recipe)

    super(224, 0, 640-224, 272)

    self.contents = Bitmap.new(width - 32, height - 32)

    @recipe = recipe

    refresh

  end

  #-----------------------------------------------------------------------------

  def refresh

    self.contents.clear

    recipe = Craft.get_recipe(@recipe)

    return unless recipe

    case recipe['RESULT'][0]

    when 0 # ITEM

      item = $data_items[recipe['RESULT'][1]]

      return unless item

      if Craft::SHOW_RESULT_ICON

        bitmap = RPG::Cache.icon(item.icon_name)

        self.contents.blt(4, 4, bitmap, Rect.new(0, 0, 24, 24))

        self.contents.draw_text(32,  0, self.contents.width - 36, 32, item.name.to_s)

      else

        self.contents.draw_text(4,  0, self.contents.width - 8, 32, item.name.to_s)

      end

      self.contents.draw_text(4,  0, self.contents.width - 8, 32, "#{item.price} #{$data_system.words.gold}", 2)

      if item.recover_hp_rate != 0

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "HP: #{item.recover_hp_rate}%")

      elsif item.recover_hp != 0

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "HP: #{item.recover_hp}")

      end

      if item.recover_sp_rate != 0

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "SP: #{item.recover_sp_rate}%", 1)

      elsif item.recover_sp != 0

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "SP: #{item.recover_sp}", 1)

      end

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "Hit%: #{item.hit}")

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "Variance: #{item.variance}", 2)

      case item.parameter_type

      when 1

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "Max HP: +#{item.parameter_points}", 2)

      when 2

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "Max SP: +#{item.parameter_points}", 2)

      when 3

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "STR: +#{item.parameter_points}", 2)

      when 4

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "DEX: +#{item.parameter_points}", 2)

      when 5

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "AGI: +#{item.parameter_points}", 2)

      when 6

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "INT: +#{item.parameter_points}", 2)

      end

      state_text = 'State + '

      for state in item.plus_state_set

        state_text += ', ' unless state == item.plus_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "#{state_text}")

      state_text = 'State - '

      for state in item.minus_state_set

        state_text += ', ' unless state == item.minus_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 144, self.contents.width - 8, 32, "#{state_text}")

    when 1 # ARMOR

      item = $data_armors[recipe['RESULT'][1]]

      return unless item

      if Craft::SHOW_RESULT_ICON

        bitmap = RPG::Cache.icon(item.icon_name)

        self.contents.blt(4, 4, bitmap, Rect.new(0, 0, 24, 24))

        self.contents.draw_text(32,  0, self.contents.width - 36, 32, item.name.to_s)

      else

        self.contents.draw_text(4,  0, self.contents.width - 8, 32, item.name.to_s)

      end

      self.contents.draw_text(4, 0, self.contents.width - 8, 32, "#{item.price} #{$data_system.words.gold}", 2)

      case item.kind

      when 0 # Shield

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, 'Shield')

      when 1 # Helmet

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, 'Helmet')

      when 2 # Body Armor

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, 'Body Armor')

      when 3 # Accessory

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, 'Accessory')

      end

      self.contents.draw_text(4, 48, self.contents.width - 8, 32, "EVA: #{item.eva}", 2)

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "PDEF: #{item.pdef}")

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "STR: #{item.str_plus}", 1)

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "DEX: #{item.dex_plus}", 2)

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "MDEF: #{item.mdef}")

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "AGI: #{item.agi_plus}", 1)

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "INT: #{item.int_plus}", 2)

      state_text = 'State Guard: '

      for state in item.guard_state_set

        state_text += ', ' unless state == item.guard_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 144, self.contents.width - 8, 32, "#{state_text}")

      state_text = 'Element Guard: '

      for state in item.guard_element_set

        state_text += ', ' unless state == item.guard_element_set.first

        state_text += $data_system.elements[state]

      end

      self.contents.draw_text(4, 176, self.contents.width - 8, 32, "#{state_text}")

      if item.auto_state_id != 0

        self.contents.draw_text(4, 208, self.contents.width - 8, 32, "Auto State: #{$data_states[item.auto_state_id].name}")

      end

    when 2 # WEAPON

      item = $data_weapons[recipe['RESULT'][1]]

      return unless item

      if Craft::SHOW_RESULT_ICON

        bitmap = RPG::Cache.icon(item.icon_name)

        self.contents.blt(4, 4, bitmap, Rect.new(0, 0, 24, 24))

        self.contents.draw_text(32,  0, self.contents.width - 36, 32, item.name.to_s)

      else

        self.contents.draw_text(4,  0, self.contents.width - 8, 32, item.name.to_s)

      end

      self.contents.draw_text(4, 0, self.contents.width - 8, 32, "#{item.price} #{$data_system.words.gold}", 2)

      self.contents.draw_text(4, 48, self.contents.width - 8, 32, "ATK: #{item.atk}")

      self.contents.draw_text(4, 48, self.contents.width - 8, 32, "PDEF: #{item.pdef}", 1)

      self.contents.draw_text(4, 48, self.contents.width - 8, 32, "MDEF: #{item.mdef}", 2)

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "STR: #{item.str_plus}")

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "DEX: #{item.dex_plus}", 2)

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "AGI: #{item.agi_plus}")

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "INT: #{item.int_plus}", 2)

      state_text = 'State + '

      for state in item.plus_state_set

        state_text += ', ' unless state == item.plus_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 144, self.contents.width - 8, 32, "#{state_text}")

      state_text = 'State - '

      for state in item.minus_state_set

        state_text += ', ' unless state == item.minus_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 176, self.contents.width - 8, 32, "#{state_text}")

      state_text = 'Element: '

      for state in item.element_set

        state_text += ', ' unless state == item.element_set.first

        state_text += $data_system.elements[state]

      end

      self.contents.draw_text(4, 208, self.contents.width - 8, 32, "#{state_text}")

    end

  end

  #-----------------------------------------------------------------------------

  def update(recipe)

    super()

    return unless recipe != @recipe

    @recipe = recipe

    refresh

  end

end

 

#===============================================================================

# Window ResultComponents

#-------------------------------------------------------------------------------

# This window displays all the components required for the combination, as well

# as the amount you have and the amount required of each. If an item has a *

# after the name, it will not be consumed in the combination.

#===============================================================================

 

class Window_ResultComponents < Window_Base

  def initialize(recipe)

    super(224, 272, 640-224, 208)

    self.contents = Bitmap.new(width - 32, height - 32)

    @recipe = recipe

    refresh

  end

  #-----------------------------------------------------------------------------

  def refresh

    self.contents.clear

    recipe = Craft.get_recipe(@recipe)

    return unless recipe

    i = 0

    for component in recipe['COMPONENTS']

      case component[0]

      when 0 # ITEM

        item = $data_items[component[1]]

        number = $game_party.item_number(component[1])

      when 1 # ARMOR

        item = $data_armors[component[1]]

        number = $game_party.armor_number(component[1])

      when 2 # WEAPON

        item = $data_weapons[component[1]]

        number = $game_party.weapon_number(component[1])

      end

      next unless item

      text = "#{item.name}"

      text += ' (*)' unless component[3]

      x = (Craft::SHOW_COMPONENT_ICONS ? 32 : 4)

      if Craft::SHOW_COMPONENT_ICONS

        bitmap = RPG::Cache.icon(item.icon_name)

        self.contents.blt(4, i * 32 + 4, bitmap, Rect.new(0, 0, 24, 24))

      end

      self.contents.draw_text(x, i * 32, self.contents.width - x - 4, 32, "#{text}")

      self.contents.draw_text(x, i * 32, self.contents.width - x - 4, 32, "#{number}/#{component[2]}", 2)

      i += 1

    end

  end

  #-----------------------------------------------------------------------------

  def update(recipe)

    super()

    return unless recipe != @recipe

    @recipe = recipe

    refresh

  end

end

 

#===============================================================================

# Game_Party

#-------------------------------------------------------------------------------

# This is a small edit of the original Game_Party class to add recognition for

# recipes. It also adds the methods below:

#   add_recipe() : name

#     - this will teach the party the recipe, if it's valid. name is the name

#       of the recipe.

#   remove_recipe() : name

#     - this will force the party to forget the recipe, if it's known. name is

#       the name of the recipe.

#   have_recipe() : name

#     - this will return true or false, depending on if the party knows the

#       recipe. Primary used in the can_make? method of the Craft module.

# -- FOR LEVELS --

#   learn_trade() : name

#     - this will set the level of the 'trade skill' to 1, enabling it for use

#       with recipes.

#   forget_trade() : name

#     - this will reset the level of the 'trade skill' to 0.

#   trade_check() : name, level

#     - this will return true or false, depending on if the arguement 'level' is

#       less than or equal to the 'trade skill'.

#   trade_level_up() : name, value = 1

#     - this will add the value to the existing trade level. Used primary by

#       the Craft module.

#===============================================================================

 

class Game_Party

  attr_reader :recipes

  attr_reader :trade_skills

  #-----------------------------------------------------------------------------

  alias prexcraft_g_party_initialize initialize

  #-----------------------------------------------------------------------------

  def initialize

    prexcraft_g_party_initialize

    @recipes = []

    @trade_skills = Hash.new(0)

  end

  #-----------------------------------------------------------------------------

  def add_recipe(name)

    @recipes.push(name) if Craft.valid_recipe?(name) and !have_recipe(name)

  end

  #-----------------------------------------------------------------------------

  def remove_recipe(name)

    @recipes.delete(name)

  end

  #-----------------------------------------------------------------------------

  def have_recipe(name)

    return @recipes.include?(name)

  end

  #-----------------------------------------------------------------------------

  def learn_trade(name)

    @trade_skills[name] = 1

  end

  #-----------------------------------------------------------------------------

  def forget_trade(name)

    @trade_skills[name] = 0

  end

  #-----------------------------------------------------------------------------

  def trade_check?(name, level)

    return (@trade_skills[name] >= level)

  end

  #-----------------------------------------------------------------------------

  def trade_level_up(name, value = 1)

    @trade_skills[name] += value

  end

end

Code:
#===============================================================================

# Module Craft by Prexus

#  - Version 1.02 (12.24.06)

#-------------------------------------------------------------------------------

# This is the primary module of the PrexCraft script. Be sure to read the

# instructions to learn how to create new recipes. Do not change any of the

# constants in the DO NOT TOUCH section.

#===============================================================================

 

module Craft

  #=============================================================================

  # CONSTANTS :: DO NOT TOUCH

  #=============================================================================

  ITEM = 0; ARMOR = 1; WEAPON = 2

  NOT_CONSUMED = false; CONSUMED = true;

  

  #=============================================================================

  # RECIPES :: Follow Instructions

  #-----------------------------------------------------------------------------

  # FORMAT :

  # {'NAME' => 'RECIPE NAME AS STRING',

  #  'RESULT' => [TYPE, ID, VALUE],

  #  'COMPONENTS' => [

  #    [TYPE, ID, VALUE, CONSUMED?],

  #    [TYPE, ID, VALUE, CONSUMED?],

  #    ...

  #  ]

  # }

  #-----------------------------------------------------------------------------

  # To setup a recipe, follow the example below:

  #-----------------------------------------------------------------------------

  # {'NAME' => 'Cold Iron Sword',

  #  'RESULT' => [ARMOR, 1, 1],

  #  'COMPONENTS' => [

  #    [ITEM, 1, 1, CONSUMED],

  #    [ITEM, 2, 1, CONSUMED],

  #    [WEAPON, 3, 1, NOT_CONSUMED]

  #  ]

  # } # End Recipe [ARMOR, 1, 1]

  #=============================================================================

  RECIPES = [

    {'NAME' => 'Cold Sword',

     'RESULT' => [WEAPON, 33, 1],

     'COMPONENTS' => [

       [ITEM, 33, 1, CONSUMED],

       [WEAPON, 1, 1, CONSUMED]

     ]

    },

    {'NAME' => 'Apple Pie',

     'RESULT' => [ITEM, 36, 1],

     'COMPONENTS' => [

       [ITEM, 34, 1, NOT_CONSUMED],

       [ITEM, 35, 3, CONSUMED]

     ]

    }

  ]

  

  #=============================================================================

  # Craft Methods

  #-----------------------------------------------------------------------------

  # valid_recipe? : name

  # Checks if the recipe name given exists in the recipe data store.

  #=============================================================================

  def self.valid_recipe?(name)

    for recipe in RECIPES

      return true if name == recipe['NAME']

    end

    return false

  end

  

  #=============================================================================

  # Craft Methods

  #-----------------------------------------------------------------------------

  # can_make? : name

  # Checks if the recipe is possible to make. First finds if the recipe given is

  # valid, then checks if there are enough components in your inventory.

  #=============================================================================

  def self.can_make?(name)

    return false unless self.valid_recipe?(name)

    for r in RECIPES

      next unless name == r['NAME']

      recipe = r

    end

    return false unless recipe

    for component in recipe['COMPONENTS']

      case component[0]

      when 0 # ITEM

        return false unless $game_party.item_number(component[1]) >= component[2]

      when 1 # ARMOR

        return false unless $game_party.armor_number(component[1]) >= component[2]

      when 2 # WEAPON

        return false unless $game_party.weapon_number(component[1]) >= component[2]

      end

    end

    return true

  end

  

  #=============================================================================

  # Craft Methods

  #-----------------------------------------------------------------------------

  # get_recipe : name

  # Returns the hash object containing the data information for the recipe if

  # the recipe is valid. Else returns nil.

  #=============================================================================

  def self.get_recipe(name)

    return nil unless self.valid_recipe?(name)

    for recipe in RECIPES

      return recipe if recipe['NAME'] == name

    end

    return nil

  end

end

 

#===============================================================================

# Scene Craft

#-------------------------------------------------------------------------------

# This is the main interface for the crafting system. You can run it by using

# the callscript command '$scene = Scene_Craft.new' or by adding it to your own

# code in the same manner.

#===============================================================================

 

class Scene_Craft

  def main

    @recipe_list = Window_RecipeList.new

    @result_info = Window_ResultInfo.new(@recipe_list.data)

    @result_comp = Window_ResultComponents.new(@recipe_list.data)

    Graphics.transition

    loop do

      Graphics.update

      Input.update

      update

      break if $scene != self

    end

    Graphics.freeze

    @recipe_list.dispose

    @result_info.dispose

    @result_comp.dispose

  end

  #-----------------------------------------------------------------------------

  def update

    @recipe_list.update

    @result_info.update(@recipe_list.data)

    @result_comp.update(@recipe_list.data)

    if Input.trigger?(Input::B)

      $game_system.se_play($data_system.cancel_se)

      $scene = Scene_Map.new

      return

    end

    if Input.trigger?(Input::C)

      if craft(@recipe_list.data)

        $game_system.se_play($data_system.decision_se)

      else

        $game_system.se_play($data_system.buzzer_se)

      end

      @recipe_list.refresh

      @result_info.refresh

      @result_comp.refresh

      return

    end

  end

  #-----------------------------------------------------------------------------

  def craft(recipe)

    return false unless Craft.can_make?(recipe)

    recipe = Craft.get_recipe(@recipe_list.data)

    for component in recipe['COMPONENTS']

      case component[0]

      when 0 # Item

        $game_party.lose_item(component[1], component[2]) if component[3]

      when 1 # Armor

        $game_party.lose_armor(component[1], component[2]) if component[3]

      when 2 # Weapon

        $game_party.lose_weapon(component[1], component[2]) if component[3]

      end

    end

    case recipe['RESULT'][0]

    when 0 # Item

      $game_party.gain_item(recipe['RESULT'][1], recipe['RESULT'][2])

    when 1 # Armor

      $game_party.gain_armor(recipe['RESULT'][1], recipe['RESULT'][2])

    when 2 # Weapon

      $game_party.gain_weapon(recipe['RESULT'][1], recipe['RESULT'][2])

    end

    return true

  end

end

 

#===============================================================================

# Window RecipeList

#-------------------------------------------------------------------------------

# This is a standard command window which shows all the recipes known by the

# party. They will appear in White if you have the proper reagents to combine

# or grey otherwise.

#===============================================================================

 

class Window_RecipeList < Window_Selectable

  def initialize

    super(0, 0, 224, 480)

    self.contents = Bitmap.new(width - 32, height - 32)

    @data = []

    refresh

  end

  #-----------------------------------------------------------------------------

  def data

    return @data[self.index]

  end

  #-----------------------------------------------------------------------------

  def refresh

    self.contents.clear

    @data = []

    for recipe in $game_party.recipes

      @data.push(recipe) if Craft.valid_recipe?(recipe)

    end

    @item_max = @data.size

    self.index = 0

    for i in [email=0..@data.size]0..@data.size[/email]

      data = @data[i]

      next unless data

      self.contents.font.color = (Craft.can_make?(data) ? normal_color : disabled_color)

      self.contents.draw_text(4, i * 32, self.contents.width - 8, 32, data.to_s)

    end

  end

end

 

#===============================================================================

# Window ResultInfo

#-------------------------------------------------------------------------------

# This window displays all the information regarding the resulting item.

#===============================================================================

 

class Window_ResultInfo < Window_Base

  def initialize(recipe)

    super(224, 0, 640-224, 272)

    self.contents = Bitmap.new(width - 32, height - 32)

    @recipe = recipe

    refresh

  end

  #-----------------------------------------------------------------------------

  def refresh

    self.contents.clear

    recipe = Craft.get_recipe(@recipe)

    return unless recipe

    case recipe['RESULT'][0]

    when 0 # ITEM

      item = $data_items[recipe['RESULT'][1]]

      return unless item

      self.contents.draw_text(4,  0, self.contents.width - 8, 32, item.name.to_s)

      self.contents.draw_text(4,  0, self.contents.width - 8, 32, "#{item.price} #{$data_system.words.gold}", 2)

      if item.recover_hp_rate != 0

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "HP: #{item.recover_hp_rate}%")

      elsif item.recover_hp != 0

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "HP: #{item.recover_hp}")

      end

      if item.recover_sp_rate != 0

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "SP: #{item.recover_sp_rate}%", 1)

      elsif item.recover_sp != 0

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "SP: #{item.recover_sp}", 1)

      end

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "Hit%: #{item.hit}")

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "Variance: #{item.variance}", 2)

      case item.parameter_type

      when 1

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "Max HP: +#{item.parameter_points}", 2)

      when 2

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "Max SP: +#{item.parameter_points}", 2)

      when 3

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "STR: +#{item.parameter_points}", 2)

      when 4

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "DEX: +#{item.parameter_points}", 2)

      when 5

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "AGI: +#{item.parameter_points}", 2)

      when 6

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, "INT: +#{item.parameter_points}", 2)

      end

      state_text = 'State + '

      for state in item.plus_state_set

        state_text += ', ' unless state == item.plus_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "#{state_text}")

      state_text = 'State - '

      for state in item.minus_state_set

        state_text += ', ' unless state == item.minus_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 144, self.contents.width - 8, 32, "#{state_text}")

    when 1 # ARMOR

      item = $data_armors[recipe['RESULT'][1]]

      return unless item

      self.contents.draw_text(4, 0, self.contents.width - 8, 32, item.name.to_s)

      self.contents.draw_text(4, 0, self.contents.width - 8, 32, "#{item.price} #{$data_system.words.gold}", 2)

      case item.kind

      when 0 # Shield

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, 'Shield')

      when 1 # Helmet

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, 'Helmet')

      when 2 # Body Armor

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, 'Body Armor')

      when 3 # Accessory

        self.contents.draw_text(4, 48, self.contents.width - 8, 32, 'Accessory')

      end

      self.contents.draw_text(4, 48, self.contents.width - 8, 32, "EVA: #{item.eva}", 2)

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "PDEF: #{item.pdef}")

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "STR: #{item.str_plus}", 1)

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "DEX: #{item.dex_plus}", 2)

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "MDEF: #{item.mdef}")

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "AGI: #{item.agi_plus}", 1)

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "INT: #{item.int_plus}", 2)

      state_text = 'State Guard: '

      for state in item.guard_state_set

        state_text += ', ' unless state == item.guard_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 144, self.contents.width - 8, 32, "#{state_text}")

      state_text = 'Element Guard: '

      for state in item.guard_element_set

        state_text += ', ' unless state == item.guard_element_set.first

        state_text += $data_system.elements[state]

      end

      self.contents.draw_text(4, 176, self.contents.width - 8, 32, "#{state_text}")

      if item.auto_state_id != 0

        self.contents.draw_text(4, 208, self.contents.width - 8, 32, "Auto State: #{$data_states[item.auto_state_id].name}")

      end

    when 2 # WEAPON

      item = $data_weapons[recipe['RESULT'][1]]

      return unless item

      self.contents.draw_text(4, 0, self.contents.width - 8, 32, item.name.to_s)

      self.contents.draw_text(4, 0, self.contents.width - 8, 32, "#{item.price} #{$data_system.words.gold}", 2)

      self.contents.draw_text(4, 48, self.contents.width - 8, 32, "ATK: #{item.atk}")

      self.contents.draw_text(4, 48, self.contents.width - 8, 32, "PDEF: #{item.pdef}", 1)

      self.contents.draw_text(4, 48, self.contents.width - 8, 32, "MDEF: #{item.mdef}", 2)

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "STR: #{item.str_plus}")

      self.contents.draw_text(4, 80, self.contents.width - 8, 32, "DEX: #{item.dex_plus}", 2)

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "AGI: #{item.agi_plus}")

      self.contents.draw_text(4, 112, self.contents.width - 8, 32, "INT: #{item.int_plus}", 2)

      state_text = 'State + '

      for state in item.plus_state_set

        state_text += ', ' unless state == item.plus_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 144, self.contents.width - 8, 32, "#{state_text}")

      state_text = 'State - '

      for state in item.minus_state_set

        state_text += ', ' unless state == item.minus_state_set.first

        state_text += $data_states[state].name

      end

      self.contents.draw_text(4, 176, self.contents.width - 8, 32, "#{state_text}")

      state_text = 'Element: '

      for state in item.element_set

        state_text += ', ' unless state == item.element_set.first

        state_text += $data_system.elements[state]

      end

      self.contents.draw_text(4, 208, self.contents.width - 8, 32, "#{state_text}")

    end

  end

  #-----------------------------------------------------------------------------

  def update(recipe)

    super()

    return unless recipe != @recipe

    @recipe = recipe

    refresh

  end

end

 

#===============================================================================

# Window ResultComponents

#-------------------------------------------------------------------------------

# This window displays all the components required for the combination, as well

# as the amount you have and the amount required of each. If an item has a *

# after the name, it will not be consumed in the combination.

#===============================================================================

 

class Window_ResultComponents < Window_Base

  def initialize(recipe)

    super(224, 272, 640-224, 208)

    self.contents = Bitmap.new(width - 32, height - 32)

    @recipe = recipe

    refresh

  end

  #-----------------------------------------------------------------------------

  def refresh

    self.contents.clear

    recipe = Craft.get_recipe(@recipe)

    return unless recipe

    i = 0

    for component in recipe['COMPONENTS']

      case component[0]

      when 0 # ITEM

        item = $data_items[component[1]]

        number = $game_party.item_number(component[1])

      when 1 # ARMOR

        item = $data_armors[component[1]]

        number = $game_party.armor_number(component[1])

      when 2 # WEAPON

        item = $data_weapons[component[1]]

        number = $game_party.weapon_number(component[1])

      end

      next unless item

      text = "#{item.name}"

      text += ' (*)' unless component[3]

      self.contents.draw_text(4, i * 32, self.contents.width - 8, 32, "#{text}")

      self.contents.draw_text(4, i * 32, self.contents.width - 8, 32, "#{number}/#{component[2]}", 2)

      i += 1

    end

  end

  #-----------------------------------------------------------------------------

  def update(recipe)

    super()

    return unless recipe != @recipe

    @recipe = recipe

    refresh

  end

end

 

#===============================================================================

# Game_Party

#-------------------------------------------------------------------------------

# This is a small edit of the original Game_Party class to add recognition for

# recipes. It also adds the methods below:

#   add_recipe() : name

#     - this will teach the party the recipe, if it's valid. name is the name

#       of the recipe.

#   remove_recipe() : name

#     - this will force the party to forget the recipe, if it's known. name is

#       the name of the recipe.

#   have_recipe() : name

#     - this will return true or false, depending on if the party knows the

#       recipe. Primary used in the can_make? method of the Craft module.

#===============================================================================

 

class Game_Party

  attr_reader :recipes

  #-----------------------------------------------------------------------------

  alias prexcraft_g_party_initialize initialize

  #-----------------------------------------------------------------------------

  def initialize

    prexcraft_g_party_initialize

    @recipes = []

  end

  #-----------------------------------------------------------------------------

  def add_recipe(name)

    @recipes.push(name) if Craft.valid_recipe?(name)

  end

  #-----------------------------------------------------------------------------

  def remove_recipe(name)

    @recipes.delete(name)

  end

  #-----------------------------------------------------------------------------

  def have_recipe(name)

    return @recipes.include?(name)

  end

end

Instructions for Version 2.0

When calling the Craft scene, be sure to include a parameter after the call to designate what type of trade skill you want to list.. such as:
$scene = Scene_Craft.new('Blacksmith')
Be sure that the type of skill corresponds with the skill type of the recipes.

There are instructions within the script but for quick reference:
Code:
 

 {'NAME' => 'RECIPE NAME AS STRING',

  'TYPE' => 'RECIPE TYPE AS STRING',

  'LEVEL' => RECIPE_LEVEL_AS_INTEGER,

  'RESULT' => [ITEM_TYPE, ID, VALUE],

  'COMPONENTS' => [

    [ITEM_TYPE, ID, VALUE, CONSUMED?],

    [ITEM_TYPE, ID, VALUE, CONSUMED?],

    ...

  ]

 }
ITEM_TYPE = ITEM, WEAPON, or ARMOR
ID = ID within the Database
VALUE = Amount used in combination, or as a result of combination.
CONSUMED? = CONSUMED or NOT_CONSUMED

To Learn: $game_party.add_recipe('RECIPE NAME')
To Forget: $game_party.remove_recipe('RECIPE NAME')

To Learn: $game_party.learn_trade('TRADE NAME')
To Forget: $game_party.forget_trade('TRADE NAME')
 
Pretty awesome Prexus. Nice and easy:thumb:

I tested the demo and noticed if you learn a recipe you already know, it will be on there twice. And you can do this over and over to have the same recipe 50 times. Any way to fix this?
 
Nice Script PrexusBut just to give some idea: would be great to need some xp or skill points to craft a new thingy, like:
apple pie: xp needed: 0; xp adding: 1/(actor.bakery_xp+1)
cherry pie: xp needed: 10; xp adding: 5/(actor.bakery_xp+1)
strawberry pie: ...
the higher the xp the less the xp earn, like a limited growth formula
but then it wouldn't be that simple...
 
Caldaron;121390 said:
Nice Script PrexusBut just to give some idea: would be great to need some xp or skill points to craft a new thingy, like:
apple pie: xp needed: 0; xp adding: 1/(actor.bakery_xp+1)
cherry pie: xp needed: 10; xp adding: 5/(actor.bakery_xp+1)
strawberry pie: ...
the higher the xp the less the xp earn, like a limited growth formula
but then it wouldn't be that simple...

To add to your idea there, how about with XP and levels you get better at making the item? so instead of making say a apple pie you burn it because you're to low of level in baking?
 
Italianstal1ion;121363 said:
Pretty awesome Prexus. Nice and easy:thumb:

I tested the demo and noticed if you learn a recipe you already know, it will be on there twice. And you can do this over and over to have the same recipe 50 times. Any way to fix this?

I'll fix this. It was a bit of an oversight. One or two lines of code will fix it.

Fixed.

Regarding the 'Crafting XP', please submit this as a Script Request. It is not the intention of this system.
 
Looks like a nice and user-friendly script, but I'm still wondering what the 'Consumed' option does. Maybe you can enlighten me?
 
This is, say, for example, you needed a Smith's Hammer to forge a weapon. If it is set to NOT_CONSUMED, the item is still needed for the combination, but it will still be in your inventory afterwards.
 
Added Version 2.0

See the 'Features' section for the updated features (It's a doozey!)

Special Thanks to ScriptKitty for inspiring me to update the script.
 
When ever I use this script (along with Deke's) when the menu to craft opens up all the font isn't there. I can see the icons and everything and I can still craft (game doesn't lock up or give error message) but I just simply cannot see the text. I looked over the script and I have SDK but I haven't been able to find anything plus I am not that avid of a scripter...Any help would be nice. Thanks
 
First of all, you can't use both.

Secondly, you need to buy the legal RMXP for $60 from http://www.download.com; The cause of not being able to see text is that the Illegal RMXP uses a japanese language font by default. Sorry to say, but you'll be needing to buy the legal RMXP before I or anyone else here helps you.
 
No I have the LEGAL version I paid my $60.00 I can see all the other text (i.e. scripts are in english, text = english, events = english, everything = english) But I didn't get it from Download.com though. I got it when it first came out. And I'm not using both I'm just saying that both of the Crafting Scripts(only in the crafting menu) I cannot see the text. Everything thing else in my RMXP works, just not the crafting menu.
 
Download.com was the launch website for RMXP English.

Try this: Go to the 'Main' script, and add the lines
Font.default_name = 'Verdana'
Font.default_size = '24'

before the $scene = Scene_Title.new line.
 
Hmm..ok now it works. I think I know what happened. This project file I'm using, I had before the Eng. version came out. (I was using a demo japanese one that a friend sent me) Then I bought the English version of RMXP, you think might be the source of the problem? Because now it seems to be working...<sigh> sorry about all the earlier confusion...

Edit: I'm using the same file on the Eng. ver. as I was with the Jap. ver.
 

Thank you for viewing

HBGames is a leading amateur video game development forum and Discord server open to all ability levels. Feel free to have a nosey around!

Discord

Join our growing and active Discord server to discuss all aspects of game making in a relaxed environment. Join Us

Content

  • Our Games
  • Games in Development
  • Emoji by Twemoji.
    Top