# ============================================================================= # TheoAllen - (像辐射的) 合成系统 # Version : 1.1 # Contact : [url]www.rpgmakerid.com[/url] (or) [url]http://theolized.blogspot.com[/url] # (English documentation) # ============================================================================= ($imported ||= {})[:Theo_Crafting] = true # ============================================================================= # CHANGE LOGS: # ----------------------------------------------------------------------------- # 2013.08.25 - Bugfix disable req text isn't working # 2013.08.22 - Bugfix at amount of item crafting # - Added show condition # - Added custom name # 2013.08.20 - Finished script # 2013.08.19 - Started script # ============================================================================= =begin --------------------------------------------------------------------------- 介绍 : 本脚本可以根据原料合成物品 --------------------------------------------------------------------------- 使用方法 : --------------------------------------------------------------------------- 本脚本放在插件脚本之下,main之上 使用脚本来显示合成画面 : enter_crafting --------------------------------------------------------------------------- 物品/武器/护甲备注: --------------------------------------------------------------------------- ----------------------------------- 简单的备注 ----------------------------------- <add item recipe: id,数量> <add armor recipe: id,数量> <add weapon recipe: id,数量> ^ 以上备注可以确定该物品/武器/护甲需要物品/护甲/武器作为合成原料,id为原料id, 数量为需要原料的数量 <craft name: 文本> ^ 暂时改变物品名称的备注.例如,在你的合成列表中,回复剂会显示名称“合成回复剂” 但是当你成功合成回复剂,且得到它后,它的名称会变回初始名称。 ----------------------------------- 复杂的备注 (如果你不懂,就不要尝试) ----------------------------------- <craft require> 脚本 </craft require> ^ 设定物品的合成条件,由脚本作为判断条件。写作多行时会视为同一行。我在别处写了 可以调用的脚本指令,可是..用的是印尼语。 错误的书写会使游戏崩溃,所以请确定书写规范. <craft req text> 文本 </craft req text> ^ 用于告诉玩家合成的条件。例如,如果合成某物品需要一把银色的锤子,则你可以这样写: <craft req text> 合成这个物品需要一把银色的锤子 </craft req text> <craft show eval> 脚本 </craft show eval> ^ 以上备注用来确定物品是否会出现在合成列表中。例如,合成圣灵药时,需要角色学会 高等级的炼金术,所以在角色学会特定技能前不会显示于合成列表中。 错误的书写会使游戏崩溃,所以请确定书写规范. --------------------------------------------------------------------------- 使用规定 : 属名脚本作者, TheoAllen. 你可以自由编辑此脚本,只要你不声明你是脚本的原作者 如果你想用此脚本于商业游戏,请和我共享收益.别忘了给我一份免费的游戏拷贝. =end # ============================================================================= # 设定 : # ============================================================================= module THEO module Craft # -------------------------------------------------------------------------- # 通用设定 (true/false) # -------------------------------------------------------------------------- MainMenu = true # 是否在菜单中显示"合成"指令 DisplayReqText = true # 对于那些不想使用合成条件文本的人,你可以在这里禁用它 # -------------------------------------------------------------------------- # 用语设置 (文本/字符串) # -------------------------------------------------------------------------- VocabMenu = "合成" # 主菜单的合成指令 VocabNoReq = "- 无 -" # 无任何合成条件 VocabRequire = "合成条件 :" # 合成条件 VocabRecipes = "原料 : " # 原料 VocabInventory = "持有量: " # 持有量 # -------------------------------------------------------------------------- # 杂项 (使用数字来设定 / 0123456789) # -------------------------------------------------------------------------- Text_Buffer_x = 12 # 文本右移距离 AmountSize = 250 # 数量窗口的宽度 end end # ============================================================================= # 以下勿动 # ============================================================================= module THEO module Craft def self.items items = $data_items + $data_armors + $data_weapons items.compact! items.select {|item| item.can_be_crafted? } end end end class RPG::BaseItem attr_accessor :item_recipes attr_accessor :armor_recipes attr_accessor :weapon_recipes attr_accessor :enable_cond attr_accessor :enable_text attr_accessor :show_cond attr_accessor :craft_name attr_accessor :craft_key # For future planned feature def load_recipes @item_recipes = {} @armor_recipes = {} @weapon_recipes = {} @show_cond = @enable_cond = "true" @enable_text = [] @craft_name = "" @craft_key = "" read_craft_cond = read_craft_txt = read_craft_show = false self.note.split(/[\r\n]+/).each do |line| case line when /<(?:ADD_ITEM_RECIPE|add item recipe): (.*)>/i str = $1.scan(/\d+/) @item_recipes[str[0].to_i] = str[1].to_i when /<(?:ADD_ARMOR_RECIPE|add armor recipe): (.*)>/i str = $1.scan(/\d+/) @armor_recipes[str[0].to_i] = str[1].to_i when /<(?:ADD_WEAPON_RECIPE|add WEAPON recipe): (.*)>/i str = $1.scan(/\d+/) @weapon_recipes[str[0].to_i] = str[1].to_i when /<(?:CRAFT_REQUIRE|craft require)>/i read_craft_cond = true @enable_cond = "" when /<\/(?:CRAFT_REQUIRE|craft require)>/i read_craft_cond = false when /<(?:CRAFT_REQ_TEXT|craft req text)>/i read_craft_txt = true when /<\/(?:CRAFT_REQ_TEXT|craft req text)>/i read_craft_txt = false when /<(?:CRAFT_SHOW_EVAL|craft show eval)>/i read_craft_show = true @show_cond = "" when /<\/(?:CRAFT_SHOW_EVAL|craft show eval)>/i read_craft_show = false when /<(?:CRAFT_NAME|craft name): (.*)>/i @craft_name = $1.to_s when /<(?:CRAFT_KEY|craft key): [ ]*(.*)>/i @craft_key = $1.to_s else if read_craft_cond @enable_cond += line end if read_craft_txt @enable_text.push(line) end if read_craft_show @show_cond += line end end end end def recipes [@item_recipes, @armor_recipes, @weapon_recipes] end # --------------------------------------------------------------------------- # If the error is directed you to this line. It's possible that you wrote # craft requirement formula in a wrong way. Not this script mistake # --------------------------------------------------------------------------- def craft_possible? return eval(@enable_cond) && can_be_crafted? end def show_possible? return eval(@show_cond) end # --------------------------------------------------------------------------- # Determine if item can be crafted # --------------------------------------------------------------------------- def can_be_crafted? recipes.any? {|recipe| !recipe.empty?} && show_possible? end end class << DataManager alias theo_recipe_craft_load_db load_database def load_database theo_recipe_craft_load_db load_item_recipes end def load_item_recipes ($data_items+$data_armors+$data_weapons).compact.each do |db| db.load_recipes end end end class Window_CraftList < Window_ItemList def initialize(x,y,w,h,key) @key = key super(x,y,w,h) refresh end def col_max return 1 end def status_window=(window) @status_window = window update_help end def item_number_window=(window) @inum_window = window update_help end def update_help super @status_window.set_item(item) if @status_window @inum_window.set_item(item) if @inum_window end def make_item_list @data = [] items = THEO::Craft.items items.each do |item| @data.push(item) if @key.empty? || item.craft_key == @key end end def enable?(item) item.craft_possible? && has_recipes?(item) && has_free_slot?(item) end def has_free_slot?(item) $game_party.item_number(item) < $game_party.max_item_number(item) end def has_recipes?(item) result1 = check_recipe(item.recipes[0], $data_items) result2 = check_recipe(item.recipes[1], $data_armors) result3 = check_recipe(item.recipes[2], $data_weapons) return result1 && result2 && result3 end def check_recipe(recipes, data) return true if recipes.empty? return recipes.all? {|recipe| $game_party.item_number(data[recipe[0]]) >= recipe[1]} end def draw_item_name(item, x, y, enabled = true, width = 172) return unless item draw_icon(item.icon_index, x, y, enabled) change_color(normal_color, enabled) name = item.craft_name.empty? ? item.name : item.craft_name draw_text(x + 24, y, width, line_height, name) end def draw_item_number(rect, item) return unless $imported[:Theo_LimInventory] return unless THEO::LimInv::Display_ItemSize draw_text(rect, sprintf(":%2d", item.inv_size), 2) end end class Window_CraftStatus < Window_Base def set_item(item) @item = item refresh end def refresh contents.clear return unless @item @line_count = 0 draw_requirement draw_recipes end def draw_requirement return unless THEO::Craft::DisplayReqText change_color(system_color) draw_text(line_rect(4),THEO::Craft::VocabRequire) increase_line_count if !@item.enable_text.empty? change_color(normal_color, @item.craft_possible?) @item.enable_text.each do |text| draw_text(line_rect(buff_x),text) increase_line_count end increase_line_count else change_color(normal_color) draw_text(line_rect(buff_x),THEO::Craft::VocabNoReq) 2.times { increase_line_count } end end def draw_recipes change_color(system_color) draw_text(line_rect(4),THEO::Craft::VocabRecipes) change_color(normal_color) increase_line_count draw_recipe(@item.recipes[0], $data_items) draw_recipe(@item.recipes[1], $data_armors) draw_recipe(@item.recipes[2], $data_weapons) end def draw_recipe(hash, items) hash.each do |id,amount| item_num = $game_party.item_number(items[id]) enable = item_num >= amount change_color(normal_color, enable) rect = line_rect(buff_x + 24) text = sprintf("%s (%d/%d)",items[id].name, item_num, amount) draw_text(rect, text) draw_icon(items[id].icon_index, buff_x, @line_count, enable) increase_line_count end end def line_rect(xpos = 0) Rect.new(xpos,@line_count,contents.width-xpos,line_height) end def increase_line_count @line_count += line_height end def buff_x THEO::Craft::Text_Buffer_x end end class Window_CraftAmount < Window_Base attr_accessor :inv_window attr_accessor :ok_handler attr_accessor :cancel_handler attr_reader :amount def initialize super(0,0,window_width,fitting_height(1)) self.openness = 0 to_center @amount = 0 @max = 0 @item = nil end def window_width return THEO::Craft::AmountSize end def to_center self.x = (Graphics.width - width)/2 self.y = (Graphics.height - height)/2 end def set(item, max) change_amount(0,true) @item = item @max = max open refresh end def refresh contents.clear return unless @item draw_item_name(@item,0,0,true,contents.width) draw_amount end def draw_amount text = sprintf("%d/%d",@amount,@max) draw_text(0,0,contents.width,line_height,text,2) end def update super if open? change_amount(1) if Input.repeat?(:RIGHT) change_amount(-1) if Input.repeat?(:LEFT) change_amount(10) if Input.repeat?(:UP) change_amount(-10) if Input.repeat?(:DOWN) call_ok if Input.trigger?(:C) call_cancel if Input.trigger?(:B) end end def change_amount(number, instant = false) if instant @amount = number else Sound.play_cursor @amount = [[@amount + number,0].max,@max].min end refresh @inv_window.amount = @amount if @inv_window end def call_ok Sound.play_ok ok_handler.call change_amount(0,true) close end def call_cancel Sound.play_cancel cancel_handler.call change_amount(0,true) close end end class Window_CraftFooter < Window_Base def initialize super(0,0,Graphics.width,fitting_height(1)) self.y = Graphics.height - height @amount = 0 @item = nil refresh end def amount=(amount) @amount = amount refresh end def refresh contents.clear change_color(system_color) draw_text(0,0,contents.width,line_height,THEO::Craft::VocabInventory) change_color(normal_color) return unless @item if $imported[:Theo_LimInventory] draw_inv_slot(0,0) else draw_item_number end end def draw_inv_slot(x,y,width = contents.width,align = 2) total = $game_party.total_inv_size + @amount*@item.inv_size total -= calculate_lose_item txt = sprintf("%d/%d", total, $game_party.inv_max) color = THEO::LimInv::NearMaxed_Color near_max = total.to_f/$game_party.inv_max >= (100 - THEO::LimInv::NearMaxed_Percent).to_f / 100 if near_max change_color(text_color(color)) else change_color(normal_color) end draw_text(x,y,width,line_height,txt,align) change_color(normal_color) end def draw_item_number txt = sprintf("%d/%d",@amount + $game_party.item_number(@item), $game_party.max_item_number(@item)) draw_text(0,0,contents.width,line_height,txt,2) end def set_item(item) @item = item refresh end def calculate_lose_item result = 0 @item.recipes[0].each do |id,amount| data = $data_items[id] amount *= @amount result += amount end @item.recipes[1].each do |id,amount| data = $data_armors[id] amount *= @amount result += amount end @item.recipes[2].each do |id,amount| data = $data_weapons[id] amount *= @amount result += amount end return result end end class Game_Interpreter # ---------------------------------------------- # key is just for my future planned feature # ---------------------------------------------- def enter_crafting(key = "") SceneManager.call(Scene_ItemCrafting) SceneManager.scene.prepare(key) Fiber.yield end end class Window_MenuCommand < Window_Command alias theo_craft_ori_cmd add_original_commands def add_original_commands theo_craft_ori_cmd return unless THEO::Craft::MainMenu add_command(THEO::Craft::VocabMenu, :craft) end end class Scene_Menu < Scene_MenuBase alias theo_craft_cmnd_window create_command_window def create_command_window theo_craft_cmnd_window @command_window.set_handler(:craft, method(:enter_crafting)) end def enter_crafting SceneManager.call(Scene_ItemCrafting) SceneManager.scene.prepare("") end end class Scene_ItemCrafting < Scene_MenuBase def prepare(key) @key = key end def start super create_help_window create_craftfooter_window create_craftlist_window create_craftstatus_window create_craftamount_window end def create_craftfooter_window @craft_footer = Window_CraftFooter.new end def create_craftlist_window wy = @help_window.height ww = Graphics.width/2 wh = Graphics.height - wy - @craft_footer.height @craft_list = Window_CraftList.new(0,wy,ww,wh,@key) @craft_list.set_handler(:ok, method(:on_craft_ok)) @craft_list.set_handler(:cancel, method(:return_scene)) @craft_list.help_window = @help_window @craft_list.item_number_window = @craft_footer @craft_list.activate @craft_list.select(0) end def create_craftstatus_window wx = @craft_list.width wy = @craft_list.y ww = @craft_list.width wh = @craft_list.height @craft_status = Window_CraftStatus.new(wx,wy,ww,wh) @craft_list.status_window = @craft_status end def create_craftamount_window @craft_amount = Window_CraftAmount.new @craft_amount.ok_handler = method(:on_amount_ok) @craft_amount.cancel_handler = method(:on_amount_cancel) @craft_amount.inv_window = @craft_footer end def on_craft_ok @craft_amount.set(item, item_max) end def on_amount_ok $game_party.gain_item(item, @craft_amount.amount) lose_recipes @craft_status.refresh @craft_list.refresh @craft_list.activate end def on_amount_cancel @craft_list.activate end def item @craft_list.item end def item_max ary = [] item.recipes[0].each do |id,amount| data = $data_items[id] ary.push($game_party.item_number(data)/amount) end item.recipes[1].each do |id,amount| data = $data_armors[id] ary.push($game_party.item_number(data)/amount) end item.recipes[2].each do |id,amount| data = $data_weapons[id] ary.push($game_party.item_number(data)/amount) end max_item = $game_party.max_item_number(item) inum = $game_party.item_number(item) return [ary.min , max_item - inum].min end def lose_recipes item.recipes[0].each do |id,amount| data = $data_items[id] amount *= @craft_amount.amount $game_party.lose_item(data,amount) end item.recipes[1].each do |id,amount| data = $data_armors[id] amount *= @craft_amount.amount $game_party.lose_item(data,amount) end item.recipes[2].each do |id,amount| data = $data_weapons[id] amount *= @craft_amount.amount $game_party.lose_item(data,amount) end end end
01.png (4.05 KB, 下载次数: 19)
02.png (15.45 KB, 下载次数: 17)
03.png (12.35 KB, 下载次数: 18)
欢迎光临 Project1 (https://rpg.blue/) | Powered by Discuz! X3.1 |