#=============================================================================== # 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