#===============================================================================
# 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;
#=============================================================================
# TRADE :: OFFSET FOR LEVEL RANGE (edit with caution)
#============================================================================
TRADE_LEVEL_OFFSET = 10;
#=============================================================================
# COLORS :: EDIT WITH CAUTION
#=============================================================================
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',
# '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',
'TYPE' => 'Blacksmithing',
'LEVEL' => 1,
'RESULT' => [WEAPON, 33, 1],
'COMPONENTS' => [
[ITEM, 33, 1, CONSUMED],
[WEAPON, 1, 1, CONSUMED]
]
},
{'NAME' => 'Apple Pie',
'TYPE' => 'Cooking',
'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
def self.color_chart(diff)
if diff < 0
return IMPOSSIBLE
elsif diff < (TRADE_LEVEL_OFFSET * 1) - 1
return HIGH
elsif diff < (TRADE_LEVEL_OFFSET * 2) - 1
return MID
elsif diff < (TRADE_LEVEL_OFFSET * 3) - 1
return LOW
else
return TRIVIAL
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)
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 diff < (Craft.TRADE_LEVEL_OFFSET * 1) - 1
$game_party.trade_level_up(skill, 1) if rand(10) >= 1
elsif diff < (Craft.TRADE_LEVEL_OFFSET * 2) - 1
$game_party.trade_level_up(skill, 1) if rand(10) >= 3
elsif diff < (Craft.TRADE_LEVEL_OFFSET * 3) - 1
$game_party.trade_level_up(skill, 1) if rand(10) >= 6
end
if old_level != $game_party.trade_skills(skill)
@level_window = Window_Base.new(0, 0, 128, 64)
@level_window.contents = Bitmap.new(96, 32)
@level_window.x = 320 - @level_window.width / 2
@level_window.y = 240 - @level_window.height / 2
@level_window.contents.draw_text(4, 0, 88, 32,
"#{skill} +#{($game_party.trade_skills(skill) - old_level).abs}", 1)
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 = 0
for i in 0..@data.size
data = @data[i]
next unless data
self.contents.font.color = (Craft.can_make?(data) ? normal_color : disabled_color)
level = (Craft.get_recipe(data)['LEVEL'] ? Craft.get_recipe(data)['LEVEL'] : 1)
diff = $game_party.trade_skills(@type) - level
self.contents.font.color = Craft.color_chart(diff)
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
attr_reader :trade_skills
#-----------------------------------------------------------------------------
alias prexcraft_g_party_initialize initialize
#-----------------------------------------------------------------------------
def initialize
prexcraft_g_party_initialize
@recipes = []
@trade_skills = {}
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
#-----------------------------------------------------------------------------
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)
@trade_skills[name] += value
end
end