TheoAllen

Theo - Crafting System

Aug 20th, 2013
503
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 19.35 KB | None | 0 0
  1. # =============================================================================
  2. # TheoAllen - (Fallout Like) Crafting System
  3. # Version : 1.1b
  4. # Contact : www.rpgmakerid.com (or) http://theolized.blogspot.com
  5. # (This script documentation is written in informal indonesian language)
  6. # =============================================================================
  7. ($imported ||= {})[:Theo_Crafting] = true
  8. # =============================================================================
  9. # CHANGE LOGS:
  10. # -----------------------------------------------------------------------------
  11. # 2013.08.25 - Bugfix disable req text isn't working
  12. # 2013.08.22 - Bugfix at amount of item crafting
  13. #            - Added show condition
  14. #            - Added custom name
  15. # 2013.08.20 - Finished script
  16. # 2013.08.19 - Started script
  17. # =============================================================================
  18. =begin
  19.  
  20.   ---------------------------------------------------------------------------
  21.   Perkenalan :
  22.   Script ini ngebikin kamu bisa bikin item berdasar resep dan bahannya
  23.  
  24.   ---------------------------------------------------------------------------
  25.   Cara penggunaan :
  26.   ---------------------------------------------------------------------------
  27.   Pasang script ini dibawah material namun diatas main
  28.   Untuk script call ke menu craftingnya, kamu bisa gunain kek gini :
  29.  
  30.   enter_crafting
  31.  
  32.   ---------------------------------------------------------------------------
  33.   Notetags (UntukItems/Armors/Weapons):
  34.   ---------------------------------------------------------------------------
  35.   -----------------------------------
  36.   Level : Easy
  37.   -----------------------------------
  38.   <add item recipe: id,jumlah>
  39.   <add armor recipe: id,jumlah>
  40.   <add weapon recipe: id,jumlah>
  41.   ^
  42.   Notetag untuk menentukan resep dari sebuah item/armor/weapon. Dimana id
  43.   adalah id resep itu di database. Dan jumlah adalah jumlah minimal yang harus
  44.   dimiliki player
  45.  
  46.   <craft name: text>
  47.   ^
  48.   Notetag ini untuk mengganti nama item sementara. Semisal dalam list, potion
  49.   akan ditulis dengan "Craft Potions". Namun setelah jadi itemnya akan jadi
  50.   potion
  51.  
  52.   -----------------------------------
  53.   Level : Medium - Hard
  54.   (kalo ga paham ga usah coba2 make)
  55.   -----------------------------------
  56.   <craft require>
  57.   script
  58.   </craft require>
  59.   ^
  60.   Notetag ini untuk menentukan apakah item tersebut bisa dibikin ato ngga
  61.   ditentukan berdasar script. Jika kamu make banyak baris, semuanya akan
  62.   diitung sebagai satu baris. Untuk instruksi script call yg bisa dipake gw
  63.   tulis terpisah.
  64.  
  65.   Kesalahan penulisan bisa nyebab'in error. Jadi kalo semisal kamu pengen ngasi
  66.   requirement tertentu, mending langsung tanya gw aja ato scripter laen.
  67.  
  68.   <craft req text>
  69.   some text here
  70.   </craft req text>
  71.   ^
  72.   Notetag ini untuk representasi dari script call diatas. Misalnya kamu tulis
  73.   requirement item untuk crafting itu butuh silver hammer, kamu bisa tulis
  74.   kek gini :
  75.  
  76.   <craft req text>
  77.   This items need a silver hammer
  78.   to make
  79.   </craft req text>
  80.  
  81.   <craft show eval>
  82.   script
  83.   </craft show eval>
  84.   ^
  85.   Notetag ini untuk keperluan apakah item tersebut masuk dalam list ato ngga.
  86.   Semisal, sebelum kamu bisa crafting elixir, kamu harus belajar ngeramu dulu.
  87.   Setelah selese belajar, kamu akhirnya bisa crafting elixir.
  88.  
  89.   ---------------------------------------------------------------------------
  90.   Terms of Use :
  91.   ---------------------------------------------------------------------------
  92.   Credit gw, TheoAllen. Kalo semisal u bisa ngedit2 script gw trus jadi lebih
  93.   keren, terserah. Ane bebasin. Asal ngga ngeklaim aja. Kalo semisal mau
  94.   dipake buat komersil, jangan lupa, gw dibagi gratisannya.  
  95.  
  96. =end
  97. # =============================================================================
  98. # Konfigurasi :
  99. # =============================================================================
  100. module THEO
  101.   module Craft
  102.  
  103.   # --------------------------------------------------------------------------
  104.   # Settingan umum
  105.   # --------------------------------------------------------------------------
  106.     MainMenu        = true
  107.   # Set true kalo kamu pengen dalam main menu bisa akses crafting
  108.  
  109.     DisplayReqText  = true
  110.   # Set false kalo kamu pengen ngilangin tulisan requirement sbelum resep
  111.   # di window status sebelah kanan
  112.  
  113.   # --------------------------------------------------------------------------
  114.   # Settingan vokab
  115.   # --------------------------------------------------------------------------
  116.     VocabMenu      = "Craft"          # Command buat main menu (kalo kamu make)
  117.     VocabNoReq     = "- None -"       # Kalo ngga ada requirement khusus
  118.     VocabRequire   = "Requirement :"  # Vokab requirement
  119.     VocabRecipes   = "Recipes : "     # Vokab resep
  120.     VocabInventory = "Inventory: "    # Vokab buat inventory
  121.    
  122.   # --------------------------------------------------------------------------
  123.   # Lainnya
  124.   # --------------------------------------------------------------------------
  125.     Text_Buffer_x = 12
  126.   # Jarak tambahan text dari samping kiri
  127.  
  128.     AmountSize = 250
  129.   # Lebar window amount
  130.  
  131.   end
  132. end
  133. # =============================================================================
  134. # Akhir dari konfig :
  135. # =============================================================================
  136. module THEO
  137.   module Craft
  138.     def self.items
  139.       items = $data_items + $data_armors + $data_weapons
  140.       items.compact!
  141.       items.select {|item| item.can_be_crafted? }
  142.     end
  143.   end
  144. end
  145.  
  146. class RPG::BaseItem
  147.   attr_accessor :item_recipes
  148.   attr_accessor :armor_recipes
  149.   attr_accessor :weapon_recipes
  150.   attr_accessor :enable_cond
  151.   attr_accessor :enable_text
  152.   attr_accessor :show_cond
  153.   attr_accessor :craft_name
  154.   attr_accessor :craft_key  # For future planned feature
  155.  
  156.   def load_recipes
  157.     @item_recipes = {}
  158.     @armor_recipes = {}
  159.     @weapon_recipes = {}
  160.     @show_cond = @enable_cond = "true"
  161.     @enable_text = []
  162.     @craft_name = ""
  163.     @craft_key = ""
  164.     read_craft_cond = read_craft_txt = read_craft_show = false
  165.     self.note.split(/[\r\n]+/).each do |line|
  166.       case line
  167.       when /<(?:ADD_ITEM_RECIPE|add item recipe): (.*)>/i
  168.         str = $1.scan(/\d+/)
  169.         @item_recipes[str[0].to_i] = str[1].to_i
  170.       when /<(?:ADD_ARMOR_RECIPE|add armor recipe): (.*)>/i
  171.         str = $1.scan(/\d+/)
  172.         @armor_recipes[str[0].to_i] = str[1].to_i
  173.       when /<(?:ADD_WEAPON_RECIPE|add WEAPON recipe): (.*)>/i
  174.         str = $1.scan(/\d+/)
  175.         @weapon_recipes[str[0].to_i] = str[1].to_i
  176.       when /<(?:CRAFT_REQUIRE|craft require)>/i
  177.         read_craft_cond = true
  178.         @enable_cond = ""
  179.       when /<\/(?:CRAFT_REQUIRE|craft require)>/i
  180.         read_craft_cond = false
  181.       when /<(?:CRAFT_REQ_TEXT|craft req text)>/i
  182.         read_craft_txt = true
  183.       when /<\/(?:CRAFT_REQ_TEXT|craft req text)>/i
  184.         read_craft_txt = false
  185.       when /<(?:CRAFT_SHOW_EVAL|craft show eval)>/i
  186.         read_craft_show = true
  187.         @show_cond = ""
  188.       when /<\/(?:CRAFT_SHOW_EVAL|craft show eval)>/i
  189.         read_craft_show = false
  190.       when /<(?:CRAFT_NAME|craft name): (.*)>/i
  191.         @craft_name = $1.to_s
  192.       when /<(?:CRAFT_KEY|craft key): [ ]*(.*)>/i
  193.         @craft_key = $1.to_s
  194.       else
  195.         if read_craft_cond
  196.           @enable_cond += line
  197.         end
  198.         if read_craft_txt
  199.           @enable_text.push(line)
  200.         end
  201.         if read_craft_show
  202.           @show_cond += line
  203.         end
  204.       end
  205.     end
  206.   end
  207.  
  208.   def recipes
  209.     [@item_recipes, @armor_recipes, @weapon_recipes]
  210.   end
  211.  
  212.   # ---------------------------------------------------------------------------
  213.   # If the error is directed you to this line. It's possible that you wrote
  214.   # craft requirement formula in a wrong way. Not this script mistake
  215.   # ---------------------------------------------------------------------------
  216.   def craft_possible?
  217.     return eval(@enable_cond) && can_be_crafted?
  218.   end
  219.  
  220.   def show_possible?
  221.     return eval(@show_cond)
  222.   end
  223.   # ---------------------------------------------------------------------------
  224.   # Determine if item can be crafted
  225.   # ---------------------------------------------------------------------------
  226.   def can_be_crafted?
  227.     recipes.any? {|recipe| !recipe.empty?} && show_possible?
  228.   end
  229.  
  230. end
  231.  
  232. class << DataManager
  233.  
  234.   alias theo_recipe_craft_load_db load_database
  235.   def load_database
  236.     theo_recipe_craft_load_db
  237.     load_item_recipes
  238.   end
  239.  
  240.   def load_item_recipes
  241.     ($data_items+$data_armors+$data_weapons).compact.each do |db|
  242.       db.load_recipes
  243.     end
  244.   end
  245.  
  246. end
  247.  
  248. class Window_CraftList < Window_ItemList
  249.  
  250.   def initialize(x,y,w,h,key)
  251.     @key = key
  252.     super(x,y,w,h)
  253.     refresh
  254.   end
  255.  
  256.   def col_max
  257.     return 1
  258.   end
  259.  
  260.   def status_window=(window)
  261.     @status_window = window
  262.     update_help
  263.   end
  264.  
  265.   def item_number_window=(window)
  266.     @inum_window = window
  267.     update_help
  268.   end
  269.  
  270.   def update_help
  271.     super
  272.     @status_window.set_item(item) if @status_window
  273.     @inum_window.set_item(item) if @inum_window
  274.   end
  275.  
  276.   def make_item_list
  277.     @data = []
  278.     items = THEO::Craft.items
  279.     items.each do |item|
  280.       @data.push(item) if @key.empty? || item.craft_key == @key
  281.     end
  282.   end
  283.  
  284.   def enable?(item)
  285.     item.craft_possible? && has_recipes?(item) && has_free_slot?(item)
  286.   end
  287.  
  288.   def has_free_slot?(item)
  289.     $game_party.item_number(item) < $game_party.max_item_number(item)
  290.   end
  291.  
  292.   def has_recipes?(item)
  293.     result1 = check_recipe(item.recipes[0], $data_items)
  294.     result2 = check_recipe(item.recipes[1], $data_armors)
  295.     result3 = check_recipe(item.recipes[2], $data_weapons)
  296.     return result1 && result2 && result3
  297.   end
  298.  
  299.   def check_recipe(recipes, data)
  300.     return true if recipes.empty?
  301.     return recipes.all? {|recipe|
  302.       $game_party.item_number(data[recipe[0]]) >= recipe[1]}
  303.   end
  304.  
  305.   def draw_item_name(item, x, y, enabled = true, width = 172)
  306.     return unless item
  307.     draw_icon(item.icon_index, x, y, enabled)
  308.     change_color(normal_color, enabled)
  309.     name = item.craft_name.empty? ? item.name : item.craft_name
  310.     draw_text(x + 24, y, width, line_height, name)
  311.   end
  312.  
  313.   def draw_item_number(rect, item)
  314.     return unless $imported[:Theo_LimInventory]
  315.     return unless THEO::LimInv::Display_ItemSize
  316.     draw_text(rect, sprintf(":%2d", item.inv_size), 2)
  317.   end
  318.  
  319. end
  320.  
  321. class Window_CraftStatus < Window_Base
  322.  
  323.   def set_item(item)
  324.     @item = item
  325.     refresh
  326.   end
  327.  
  328.   def refresh
  329.     contents.clear
  330.     return unless @item
  331.     @line_count = 0
  332.     draw_requirement
  333.     draw_recipes
  334.   end
  335.  
  336.   def draw_requirement
  337.     return unless THEO::Craft::DisplayReqText
  338.     change_color(system_color)
  339.     draw_text(line_rect(4),THEO::Craft::VocabRequire)
  340.     increase_line_count
  341.     if !@item.enable_text.empty?
  342.       change_color(normal_color, @item.craft_possible?)
  343.       @item.enable_text.each do |text|
  344.         draw_text(line_rect(buff_x),text)
  345.         increase_line_count
  346.       end
  347.       increase_line_count
  348.     else
  349.       change_color(normal_color)
  350.       draw_text(line_rect(buff_x),THEO::Craft::VocabNoReq)
  351.       2.times { increase_line_count }
  352.     end
  353.   end
  354.  
  355.   def draw_recipes
  356.     change_color(system_color)
  357.     draw_text(line_rect(4),THEO::Craft::VocabRecipes)
  358.     change_color(normal_color)
  359.     increase_line_count
  360.     draw_recipe(@item.recipes[0], $data_items)
  361.     draw_recipe(@item.recipes[1], $data_armors)
  362.     draw_recipe(@item.recipes[2], $data_weapons)
  363.   end
  364.  
  365.   def draw_recipe(hash, items)
  366.     hash.each do |id,amount|
  367.       item_num = $game_party.item_number(items[id])
  368.       enable = item_num >= amount
  369.       change_color(normal_color, enable)
  370.       rect = line_rect(buff_x + 24)
  371.       text = sprintf("%s (%d/%d)",items[id].name, item_num, amount)
  372.       draw_text(rect, text)
  373.       draw_icon(items[id].icon_index, buff_x, @line_count, enable)
  374.       increase_line_count
  375.     end
  376.   end  
  377.  
  378.   def line_rect(xpos = 0)
  379.     Rect.new(xpos,@line_count,contents.width-xpos,line_height)
  380.   end
  381.  
  382.   def increase_line_count
  383.     @line_count += line_height
  384.   end
  385.  
  386.   def buff_x
  387.     THEO::Craft::Text_Buffer_x
  388.   end
  389.  
  390. end
  391.  
  392. class Window_CraftAmount < Window_Base
  393.   attr_accessor :inv_window
  394.   attr_accessor :ok_handler
  395.   attr_accessor :cancel_handler
  396.   attr_reader :amount
  397.  
  398.   def initialize
  399.     super(0,0,window_width,fitting_height(1))
  400.     self.openness = 0
  401.     to_center
  402.     @amount = 0
  403.     @max = 0
  404.     @item = nil
  405.   end
  406.  
  407.   def window_width
  408.     return THEO::Craft::AmountSize
  409.   end
  410.  
  411.   def to_center
  412.     self.x = (Graphics.width - width)/2
  413.     self.y = (Graphics.height - height)/2
  414.   end
  415.  
  416.   def set(item, max)
  417.     change_amount(0,true)
  418.     @item = item
  419.     @max = max
  420.     open
  421.     refresh
  422.   end
  423.  
  424.   def refresh
  425.     contents.clear
  426.     return unless @item
  427.     draw_item_name(@item,0,0,true,contents.width)
  428.     draw_amount
  429.   end
  430.  
  431.   def draw_amount
  432.     text = sprintf("%d/%d",@amount,@max)
  433.     draw_text(0,0,contents.width,line_height,text,2)
  434.   end
  435.  
  436.   def update
  437.     super
  438.     if open?
  439.       change_amount(1) if Input.repeat?(:RIGHT)
  440.       change_amount(-1) if Input.repeat?(:LEFT)
  441.       change_amount(10) if Input.repeat?(:UP)
  442.       change_amount(-10) if Input.repeat?(:DOWN)
  443.       call_ok if Input.trigger?(:C)
  444.       call_cancel if Input.trigger?(:B)
  445.     end
  446.   end
  447.  
  448.   def change_amount(number, instant = false)
  449.     if instant
  450.       @amount = number
  451.     else
  452.       Sound.play_cursor
  453.       @amount = [[@amount + number,0].max,@max].min
  454.     end
  455.     refresh
  456.     @inv_window.amount = @amount if @inv_window
  457.   end
  458.  
  459.   def call_ok
  460.     Sound.play_ok
  461.     ok_handler.call
  462.     change_amount(0,true)
  463.     close
  464.   end
  465.  
  466.   def call_cancel
  467.     Sound.play_cancel
  468.     cancel_handler.call
  469.     change_amount(0,true)
  470.     close
  471.   end
  472.  
  473. end
  474.  
  475. class Window_CraftFooter < Window_Base
  476.  
  477.   def initialize
  478.     super(0,0,Graphics.width,fitting_height(1))
  479.     self.y = Graphics.height - height
  480.     @amount = 0
  481.     @item = nil
  482.     refresh
  483.   end
  484.  
  485.   def amount=(amount)
  486.     @amount = amount
  487.     refresh
  488.   end
  489.  
  490.   def refresh
  491.     contents.clear
  492.     change_color(system_color)
  493.     draw_text(0,0,contents.width,line_height,THEO::Craft::VocabInventory)
  494.     change_color(normal_color)
  495.     return unless @item
  496.     if $imported[:Theo_LimInventory]
  497.       draw_inv_slot(0,0)
  498.     else
  499.       draw_item_number
  500.     end
  501.   end
  502.  
  503.   def draw_inv_slot(x,y,width = contents.width,align = 2)
  504.     total = $game_party.total_inv_size + @amount*@item.inv_size
  505.     total -= calculate_lose_item
  506.     txt = sprintf("%d/%d", total, $game_party.inv_max)
  507.     color = THEO::LimInv::NearMaxed_Color
  508.     near_max = total.to_f/$game_party.inv_max >=
  509.       (100 - THEO::LimInv::NearMaxed_Percent).to_f / 100
  510.     if near_max
  511.       change_color(text_color(color))
  512.     else
  513.       change_color(normal_color)
  514.     end
  515.     draw_text(x,y,width,line_height,txt,align)
  516.     change_color(normal_color)
  517.   end
  518.  
  519.   def draw_item_number
  520.     txt = sprintf("%d/%d",@amount + $game_party.item_number(@item),
  521.       $game_party.max_item_number(@item))
  522.     draw_text(0,0,contents.width,line_height,txt,2)
  523.   end
  524.  
  525.   def set_item(item)
  526.     @item = item
  527.     refresh
  528.   end
  529.  
  530.   def calculate_lose_item
  531.     result = 0
  532.     @item.recipes[0].each do |id,amount|
  533.       data = $data_items[id]
  534.       amount *= @amount
  535.       result += amount
  536.     end
  537.     @item.recipes[1].each do |id,amount|
  538.       data = $data_armors[id]
  539.       amount *= @amount
  540.       result += amount
  541.     end
  542.     @item.recipes[2].each do |id,amount|
  543.       data = $data_weapons[id]
  544.       amount *= @amount
  545.       result += amount
  546.     end
  547.     return result
  548.   end
  549.  
  550. end
  551.  
  552. class Game_Interpreter
  553.  
  554.   # ----------------------------------------------
  555.   # key is just for my future planned feature
  556.   # ----------------------------------------------
  557.   def enter_crafting(key = "")
  558.     SceneManager.call(Scene_ItemCrafting)
  559.     SceneManager.scene.prepare(key)
  560.     Fiber.yield
  561.   end
  562.  
  563. end
  564.  
  565. class Window_MenuCommand < Window_Command
  566.  
  567.   alias theo_craft_ori_cmd add_original_commands
  568.   def add_original_commands
  569.     theo_craft_ori_cmd
  570.     return unless THEO::Craft::MainMenu
  571.     add_command(THEO::Craft::VocabMenu, :craft)
  572.   end
  573.  
  574. end
  575.  
  576. class Scene_Menu < Scene_MenuBase
  577.  
  578.   alias theo_craft_cmnd_window create_command_window
  579.   def create_command_window
  580.     theo_craft_cmnd_window
  581.     @command_window.set_handler(:craft, method(:enter_crafting))
  582.   end
  583.  
  584.   def enter_crafting
  585.     SceneManager.call(Scene_ItemCrafting)
  586.     SceneManager.scene.prepare("")
  587.   end
  588.  
  589. end
  590.  
  591. class Scene_ItemCrafting < Scene_MenuBase
  592.  
  593.   def prepare(key)
  594.     @key = key
  595.   end
  596.  
  597.   def start
  598.     super
  599.     create_help_window
  600.     create_craftfooter_window
  601.     create_craftlist_window
  602.     create_craftstatus_window
  603.     create_craftamount_window
  604.   end
  605.  
  606.   def create_craftfooter_window
  607.     @craft_footer = Window_CraftFooter.new
  608.   end
  609.  
  610.   def create_craftlist_window
  611.     wy = @help_window.height
  612.     ww = Graphics.width/2
  613.     wh = Graphics.height - wy - @craft_footer.height
  614.     @craft_list = Window_CraftList.new(0,wy,ww,wh,@key)
  615.     @craft_list.set_handler(:ok, method(:on_craft_ok))
  616.     @craft_list.set_handler(:cancel, method(:return_scene))
  617.     @craft_list.help_window = @help_window
  618.     @craft_list.item_number_window = @craft_footer
  619.     @craft_list.activate
  620.     @craft_list.select(0)
  621.   end
  622.  
  623.   def create_craftstatus_window
  624.     wx = @craft_list.width
  625.     wy = @craft_list.y
  626.     ww = @craft_list.width
  627.     wh = @craft_list.height
  628.     @craft_status = Window_CraftStatus.new(wx,wy,ww,wh)
  629.     @craft_list.status_window = @craft_status
  630.   end
  631.  
  632.   def create_craftamount_window
  633.     @craft_amount = Window_CraftAmount.new
  634.     @craft_amount.ok_handler = method(:on_amount_ok)
  635.     @craft_amount.cancel_handler = method(:on_amount_cancel)
  636.     @craft_amount.inv_window = @craft_footer
  637.   end
  638.  
  639.   def on_craft_ok
  640.     @craft_amount.set(item, item_max)
  641.   end
  642.  
  643.   def on_amount_ok
  644.     $game_party.gain_item(item, @craft_amount.amount)
  645.     lose_recipes
  646.     @craft_status.refresh
  647.     @craft_list.refresh
  648.     @craft_list.activate
  649.   end
  650.  
  651.   def on_amount_cancel
  652.     @craft_list.activate
  653.   end
  654.  
  655.   def item
  656.     @craft_list.item
  657.   end
  658.  
  659.   def item_max
  660.     ary = []
  661.     item.recipes[0].each do |id,amount|
  662.       data = $data_items[id]
  663.       ary.push($game_party.item_number(data)/amount)
  664.     end
  665.     item.recipes[1].each do |id,amount|
  666.       data = $data_armors[id]
  667.       ary.push($game_party.item_number(data)/amount)
  668.     end
  669.     item.recipes[2].each do |id,amount|
  670.       data = $data_weapons[id]
  671.       ary.push($game_party.item_number(data)/amount)
  672.     end
  673.     max_item = $game_party.max_item_number(item)
  674.     inum = $game_party.item_number(item)
  675.     return [ary.min , max_item - inum].min
  676.   end
  677.  
  678.   def lose_recipes
  679.     item.recipes[0].each do |id,amount|
  680.       data = $data_items[id]
  681.       amount *= @craft_amount.amount
  682.       $game_party.lose_item(data,amount)
  683.     end
  684.     item.recipes[1].each do |id,amount|
  685.       data = $data_armors[id]
  686.       amount *= @craft_amount.amount
  687.       $game_party.lose_item(data,amount)
  688.     end
  689.     item.recipes[2].each do |id,amount|
  690.       data = $data_weapons[id]
  691.       amount *= @craft_amount.amount
  692.       $game_party.lose_item(data,amount)
  693.     end
  694.   end
  695.  
  696. end
Advertisement
Add Comment
Please, Sign In to add comment