#===============================================================================
# Mr Wiggles Alchemy Script
#===============================================================================
# By Mr Wiggles
# Version 2.4
# 3-20-11
#-------------------------------------------------------------------------------
# Instructions:
# Fill out the constants, And then call this script by using...
# $scene = Alchemy.new
#===============================================================================
#-------------------------------------------------------------------------------
module ALCHEMY#///////// *** EDIT AREA *** /////////#
#-------------------------------------------------------------------------------
# Item IDs that can be used in Alchemy.
ALCHEMY_ITEMS = [1,2,3,4]
#-------------------------------------------------------------------------------
# Item IDs that are not consumed when combined.
NON_CONSUME_ITEMS = [1,3]
#-------------------------------------------------------------------------------
# Weapon IDs that can be used in Alchemy.
ALCHEMY_WEAPONS = [1,2,3,4]
#-------------------------------------------------------------------------------
# Weapon IDs that are not consumed when combined.
NON_CONSUME_WEAPONS = [2,4]
#-------------------------------------------------------------------------------
# Armor IDs that can be used in Alchemy.
ALCHEMY_ARMORS = [1,2,3,4]
#-------------------------------------------------------------------------------
# Armor IDs that are not consumed when combined.
NON_CONSUME_ARMORS = [2,3]
#-------------------------------------------------------------------------------
# Can combine more then the same type of item together, or just one of each.
COMBINE_DUPS = true
#-------------------------------------------------------------------------------
# Button that is used to check if the items being combined make anything.
CHECK_RECIPE_BUTTON = Keys::SHIFT
#-------------------------------------------------------------------------------
# Sound to play if the recipe was successful. leave blank if none.
RIGHT_SE = "055-Right01"
#-------------------------------------------------------------------------------
# Sound to play if the recipe failed. leave blank if none.
WRONG_SE = "057-Wrong01"
#-------------------------------------------------------------------------------
# recipes to make items. Example of a recipe:
# [[A,B], [A,B], [A,B], [A,B]]
# A = Type of Item in the recipe, (0 = Item, 1 = Weapon, 2 = Armor)
# B = ID if Item
# if slot is not being used in recipe, use 0.
ALCHEMY_RECIPES = [
[[0,2], [0,5], [0,6], 0 ], # 0 = 9 mm Rounds + Machine Gun Round + Bobby Pin
[[0,1], [1,1], [0,1], [0,1]], # 1 = 3 Arrows + Recurve Bow
[[0,2], [0,2], 0 , 0 ], # 2 = 9 mm Rounds x2
[[1,2], [0,2], [2,3], [0,3]],
[[1,2], [2,6], [0,4], 0 ],
[[1,2], [2,5], [0,5], 0 ],
[[1,2], [2,4], [0,6], 0 ],
[[2,2], [0,2], [1,7], 0 ]
]# needs to be here
#-------------------------------------------------------------------------------
# Out comes of the above recipes:
# [A, B]
# A = Type of Creation (0 = Item, 1 = Weapon, 2 = Armor)
# B = ID of Item
ALCHEMY_OUTCOMES = [
[0, 10], # 0 Makes Flame Fuel
[1, 1], # 1 Makes Recurve Bow
[2, 5], # 2 Makes Leather Boots
[1, 2],
[1, 3],
[1, 4],
[1, 5],
[0, 3]
]# needs to be here
#-------------------------------------------------------------------------------
# Blue prints: the basic idea behind this is that the player can not create any
# items that they do not know how to create it. This can be done by using a
# script call command in an event that says:
# $game_system.add_blue_prints(Blue Print ID)
# the Blue print id refers to the location of the recipe in the
# ALCHEMY_RECIPES array, also remember that it starts counting at 0, this
# means that 1=0, 2=1, and so on.
#
# Bellow is the blue prints that the player already knows at the start of the
# game. [BP, BP, BP] BP = Blue Print ID
BLUE_PRINTS = [1,2,4]
#-------------------------------------------------------------------------------
# Remove the items being combined if the recipe is wrong.
PENALIZE = false
#-------------------------------------------------------------------------------
# Give the player a junk item if the mix was wrong. PENALIZE must be true for
# this. If you don't want to use this set the ID to 0.
JUNK_ITEM_ID = 0
#-------------------------------------------------------------------------------
end#///////// *** END EDIT AREA *** /////////#
#-------------------------------------------------------------------------------
#===============================================================================
# ** Alchemy
#===============================================================================
class Alchemy
#----------------------------------------------------------------
# * Main
#----------------------------------------------------------------
def main
# Create Windows
@alchemy_window = Window_Alchemy.new
@item_selection_window = Item_Selection_Window.new
@help_window = Alchemy_Help.new
@map_back = Spriteset_Map.new
@combination_window = Combination_List_Window.new
@finished_item_window = Finished_Item_Window.new
# change Z
@alchemy_window.z = 210
@item_selection_window.z = 210
@finished_item_window.z = 210
@combination_window.z = 210
@help_window.z = 210
# Make variables
@items_being_combined = []
@recipes = ALCHEMY::ALCHEMY_RECIPES
@out_comes = ALCHEMY::ALCHEMY_OUTCOMES
@creation = []
@combination = ""
@showing_text_wait = 0
# Execute transition
Graphics.transition
# Main loop
loop do
# Update game screen
Graphics.update
# Update input information
Input.update
# Frame update
update
# Abort loop if screen is changed
if $scene != self
break
end
end
# Prepare for transition
Graphics.freeze
# Dispose of windows
@alchemy_window.dispose
@item_selection_window.dispose
@help_window.dispose
@map_back.dispose
@combination_window.dispose
@finished_item_window.dispose
end
#----------------------------------------------------------------
# * Update
#----------------------------------------------------------------
def update
# Show the names of items being added
@showing_text_wait -= 1 if @showing_text_wait != 0
if @showing_text_wait == 0
item_names = []
for item in @items_being_combined
return if item == nil
item_names << item.name.to_s
end
@combination = item_names.join(" + ")
@finished_item_window.update
end
# Update Windows
@alchemy_window.refresh(@items_being_combined)
@item_selection_window.update
@combination_window.update(@combination)
# update mains
update_help
update_commands
end
#----------------------------------------------------------------
# * Update Help
#----------------------------------------------------------------
def update_help
if @item_selection_window.item != nil
@help_window.set_text(@item_selection_window.item.description)
end
end
#----------------------------------------------------------------
# * Update Commands
#----------------------------------------------------------------
def update_commands
#--------------------------
# If B button was pressed
#--------------------------
if Input.trigger?(Input::B)
@showing_text_wait = 0
if @items_being_combined.size > 0
item = @items_being_combined[@items_being_combined.size - 1]
case item
when RPG::Item
$game_party.gain_item(item.id, 1) if
!ALCHEMY::NON_CONSUME_ITEMS.include?(item.id)
when RPG::Weapon
$game_party.gain_weapon(item.id, 1) if
!ALCHEMY::NON_CONSUME_WEAPONS.include?(item.id)
when RPG::Armor
$game_party.gain_armor(item.id, 1) if
!ALCHEMY::NON_CONSUME_ARMORS.include?(item.id)
end
$game_system.se_play($data_system.cancel_se)
@items_being_combined.delete_at(@items_being_combined.size - 1)
else
# Return to map
$game_system.se_play($data_system.cancel_se)
$scene = Scene_Map.new
end
# Update item selection window
@item_selection_window.refresh
return
end
#--------------------------
# If C button was pressed
#--------------------------
if Input.trigger?(Input::C)
@showing_text_wait = 0
item = @item_selection_window.item
return if item == nil
if @items_being_combined.size < 4
if !@items_being_combined.include?(item) and
ALCHEMY::COMBINE_DUPS == false
$game_system.se_play($data_system.decision_se)
@items_being_combined << item
case item
when RPG::Item
$game_party.gain_item(item.id, -1) if
!ALCHEMY::NON_CONSUME_ITEMS.include?(item.id)
when RPG::Weapon
$game_party.gain_weapon(item.id, -1) if
!ALCHEMY::NON_CONSUME_WEAPONS.include?(item.id)
when RPG::Armor
$game_party.gain_armor(item.id, -1) if
!ALCHEMY::NON_CONSUME_ARMORS.include?(item.id)
end
elsif ALCHEMY::COMBINE_DUPS == true
$game_system.se_play($data_system.decision_se)
@items_being_combined << item
case item
when RPG::Item
$game_party.gain_item(item.id, -1) if
!ALCHEMY::NON_CONSUME_ITEMS.include?(item.id)
when RPG::Weapon
$game_party.gain_weapon(item.id, -1) if
!ALCHEMY::NON_CONSUME_WEAPONS.include?(item.id)
when RPG::Armor
$game_party.gain_armor(item.id, -1) if
!ALCHEMY::NON_CONSUME_ARMORS.include?(item.id)
end
else
$game_system.se_play($data_system.buzzer_se)
end
else
$game_system.se_play($data_system.buzzer_se)
end
# Update item selection window
@item_selection_window.refresh
return
end
#--------------------------
# If Check button was pressed
#--------------------------
if Input.trigger?(ALCHEMY::CHECK_RECIPE_BUTTON)
# check if the player was able to make anything
@creation = []
if @items_being_combined.size > 1
for id in 0..@recipes.size - 1
recipe = @recipes[id]
new_recipe = recipe.flatten
new_recipe.sort!
# if player does not know recipe
next unless $game_system.blue_prints.include?(id)
# get created item
@creation = @out_comes[id]
# kill game to prevent syntax error
if @creation == nil
print ("There is no out come for the recipie, please add one.")
$scene = nil
return
end
# get items to be combine
items_combined = []
for i in 0..@items_being_combined.size - 1
item = @items_being_combined[i]
case item
when RPG::Item
type = 0
when RPG::Weapon
type = 1
when RPG::Armor
type = 2
end
item_array = [type, item.id]
items_combined.push(item_array)
end
# fill empty slots with 0
empty_slots = 4 - items_combined.size
for i in 0..empty_slots
items_combined << 0 if items_combined.size < 4
end
items_combined.flatten!
items_combined.sort!
# see if the combination matches any recipes then
# returns the item that was created
break if items_combined == new_recipe
@creation = []
end
# show result
if @creation != []
Audio.se_play("Audio/SE/"+ALCHEMY::RIGHT_SE, 90, 100) rescue nil
# Add Item
case @creation[0]
when 0
$game_party.gain_item(@creation[1], 1)
item = $data_items[@creation[1]]
when 1
$game_party.gain_weapon(@creation[1], 1)
item = $data_weapons[@creation[1]]
when 2
$game_party.gain_armor(@creation[1], 1)
item = $data_armors[@creation[1]]
end
# Clear Varaibles
@items_being_combined = []
@showing_text_wait = 120
# Show text
@combination = "Success! Looks like you made a(n) #{item.name}."
@finished_item_window.update(item)
else
Audio.se_play("Audio/SE/"+ALCHEMY::WRONG_SE, 90, 100) rescue nil
# Clear items being combined
if ALCHEMY::PENALIZE
@items_being_combined = []
junk_id = ALCHEMY::JUNK_ITEM_ID
$game_party.gain_item(junk_id, 1) if junk_id > 0
end
@showing_text_wait = 120
# Show text
@combination = "I don't think those go well together."
end
end
# Update item selection window
@item_selection_window.refresh
return
end
end
end
#===============================================================================
# ** Game_System
#===============================================================================
class Game_System
attr_accessor :blue_prints
alias alchemy_init initialize
def initialize
alchemy_init
@blue_prints = ALCHEMY::BLUE_PRINTS
@recipes = ALCHEMY::ALCHEMY_RECIPES
end
def add_blue_prints(prints)
if !@blue_prints.include?(prints) and prints < @recipes.size - 1
@blue_prints << prints
end
end
end
#===============================================================================
# ** Alchemy Window
#===============================================================================
class Window_Alchemy < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(176, 32, 288, 80)
self.opacity = 160
self.contents = Bitmap.new(width - 32, height - 32)
refresh([])
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh(items)
@item_place = 0
self.contents.clear
for item in items
draw_item(item, @item_place)
@item_place += 1
end
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def draw_item(item, place)
return if item == nil
x = 0 + (place * 64)
y = 0
bitmap = RPG::Cache.icon(item.icon_name)
w = bitmap.width
h = bitmap.height
src_rect = Rect.new(0, 0, w, h)
dest_rect = Rect.new(x, y, w*2, h*2)
self.contents.stretch_blt(dest_rect, bitmap, src_rect)
end
end
#===============================================================================
# ** Item Selection Window
#===============================================================================
class Item_Selection_Window < Window_Selectable
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 168, 640, 250)
self.opacity = 160
@column_max = 3
refresh
self.index = 0
end
#--------------------------------------------------------------------------
# * Refresh
#--------------------------------------------------------------------------
def refresh
if self.contents != nil
self.contents.dispose
self.contents = nil
end
@data = []
# Add Items that can be combined
for i in 1...$data_items.size
if $game_party.item_number(i) > 0 and ALCHEMY::ALCHEMY_ITEMS.include?(i)
@data.push($data_items[i])
end
end
# Add Weapons that can be combined
for i in 1...$data_weapons.size
if $game_party.weapon_number(i) > 0 and ALCHEMY::ALCHEMY_WEAPONS.include?(i)
@data.push($data_weapons[i])
end
end
# Add Armors that can be combined
for i in 1...$data_armors.size
if $game_party.armor_number(i) > 0 and ALCHEMY::ALCHEMY_ARMORS.include?(i)
@data.push($data_armors[i])
end
end
# Make selection Window
@item_max = @data.size
if @item_max > 0
self.contents = Bitmap.new(width - 32, row_max * 32)
for i in 0...@item_max
draw_item(i)
end
end
end
#--------------------------------------------------------------------------
# * Item
#--------------------------------------------------------------------------
def item
return @data[self.index]
end
#--------------------------------------------------------------------------
# * Item by index
#--------------------------------------------------------------------------
def return_item(index)
return @data[index]
end
#--------------------------------------------------------------------------
# * Draw Item
#--------------------------------------------------------------------------
def draw_item(index)
# Load Item Data
item = @data[index]
case item
when RPG::Item
number = $game_party.item_number(item.id)
when RPG::Weapon
number = $game_party.weapon_number(item.id)
when RPG::Armor
number = $game_party.armor_number(item.id)
end
self.contents.font.color = normal_color
# Creat Selector
x = 4 + index % 3 * ((self.width - 30) / 3)
if index == 1
y = 0
else
y = index / 3 * 32
end
rect = Rect.new(x, y, self.width / @column_max, 32)
self.contents.fill_rect(rect, Color.new(0, 0, 0, 0))
# Create Item Icon
bitmap = RPG::Cache.icon(item.icon_name)
opacity = self.contents.font.color == normal_color ? 255 : 128
self.contents.blt(x, y + 4, bitmap, Rect.new(0, 0, 24, 24), opacity)
self.contents.font.size = 16
if number > 1
self.contents.draw_text(x, y + 8, 24, 32, number.to_s, 1)
end
# Draw Item name next to Icon
self.contents.font.size = 16
self.contents.draw_text(x+32, y, 130, 32, item.name)
end
#--------------------------------------------------------------------------
# * Frame Update
#--------------------------------------------------------------------------
def update
# If cursor is movable
if self.active and @item_max > 0 and @index >= 0
# Move cursor down
if Input.repeat?(Input::DOWN)
if @index < @item_max - @column_max
$game_system.se_play($data_system.cursor_se)
@index = (@index + @column_max) % @item_max
end
end
# Move cursor up
if Input.repeat?(Input::UP)
if @index >= @column_max
$game_system.se_play($data_system.cursor_se)
@index = (@index - @column_max + @item_max) % @item_max
end
end
# Move cursor right
if Input.repeat?(Input::RIGHT)
if (@index % 3 < 2)
if @index != @item_max - 1
@index += 1
$game_system.se_play($data_system.cursor_se)
end
end
end
# Move cursor left
if Input.repeat?(Input::LEFT)
if (@index % 3 > 0)
@index -= 1
$game_system.se_play($data_system.cursor_se)
end
end
end
# Update cursor rectangle
update_cursor_rect
end
#--------------------------------------------------------------------------
# * Update Cursor Rectangle
#--------------------------------------------------------------------------
def update_cursor_rect
# If cursor position is less than 0
if @index < 0
self.cursor_rect.empty
return
end
# Get current row
row = @index / @column_max
# If current row is before top row
if row < self.top_row
# Scroll so that current row becomes top row
self.top_row = row
end
# If current row is more to back than back row
if row > self.top_row + (self.page_row_max - 1)
# Scroll so that current row becomes back row
self.top_row = row - (self.page_row_max - 1)
end
# Calculate cursor width
cursor_width = self.width / @column_max - 16
# Calculate cursor coordinates
x = @index % @column_max * (cursor_width + 4)
y = @index / @column_max * 32 - self.oy
# Update cursor rectangle
self.cursor_rect.set(x, y, cursor_width, 32)
end
end
#==============================================================================
# ** Alchemy_Help
#==============================================================================
class Alchemy_Help < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 416, 640, 64)
self.opacity = 160
self.contents = Bitmap.new(width - 32, height - 32)
end
#--------------------------------------------------------------------------
# * Set Text
#--------------------------------------------------------------------------
def set_text(text, align = 0)
if text != @text or align != @align
self.contents.clear
self.contents.font.color = normal_color
self.contents.draw_text(4, 0, self.width - 40, 32, text, align)
@text = text
@align = align
@actor = nil
end
self.visible = true
end
end
#==============================================================================
# ** Combination_List_Window
#==============================================================================
class Combination_List_Window < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(0, 120, 640, 48)
self.opacity = 190
self.contents = Bitmap.new(width - 32, height - 32)
update
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update(text="")
self.contents.clear
self.contents.font.size = 17
self.contents.draw_text(0, -6, 640, 32, text)
end
end
#==============================================================================
# ** Finished_Item_Window
#==============================================================================
class Finished_Item_Window < Window_Base
#--------------------------------------------------------------------------
# * Object Initialization
#--------------------------------------------------------------------------
def initialize
super(276, 32, 96, 96)
self.opacity = 0
self.contents = Bitmap.new(width - 32, height - 32)
update
end
#--------------------------------------------------------------------------
# * Update
#--------------------------------------------------------------------------
def update(item=nil)
self.contents.clear
if item != nil
bitmap = RPG::Cache.icon(item.icon_name)
w = bitmap.width
h = bitmap.height
src_rect = Rect.new(0, 0, w, h)
dest_rect = Rect.new(0, 0, w*2, h*2)
self.contents.stretch_blt(dest_rect, bitmap, src_rect)
end
end
end