设为首页收藏本站|繁體中文

Project1

 找回密码
 注册会员
搜索
查看: 1862|回复: 1
打印 上一主题 下一主题

[有事请教] 求一个MZ能用的角色仓库插件!

[复制链接]

Lv3.寻梦者

梦石
0
星屑
1417
在线时间
914 小时
注册时间
2008-7-26
帖子
271
跳转到指定楼层
1
发表于 2022-9-29 17:04:19 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式

加入我们,或者,欢迎回来。

您需要 登录 才可以下载或查看,没有帐号?注册会员

x
求一个MZ能用的角色仓库插件!还有捕捉插件,最好有范例,多谢!

Lv1.梦旅人

梦石
0
星屑
224
在线时间
18 小时
注册时间
2025-6-6
帖子
15
2
发表于 2025-11-16 10:20:17 | 只看该作者
# =============================================================================
# TheoAllen - 仓库系统
# Version : 1.2
# Contact : www.rpgmakerid.com (or) http://theolized.blogspot.com
# (This script is translated by AbsoluteIce)
# =============================================================================
($imported ||= {})[:Theo_ChestSystem] = true
# =============================================================================
# CHANGE LOGS:
# -----------------------------------------------------------------------------
# 2013.08.19 - Compatibility Patch with Limited Inventory
# 2013.06.28 - Add custom chest name
# 2013.06.01 - Adjust control and GUI
# 2013.05.24 - Finished script
# 2013.05.23 - Started Script
# =============================================================================
=begin

  介绍 :
  本脚本可以设定一个仓库,允许玩家存放或取出物品.

  使用方法 :
  本脚本放在插件脚本之下,main之上

  在使用脚本打开仓库前,使用以下事件注释:
  <item: id, 数量>
  <weapon: id, 数量>
  <armor: id, 数量>

  解释 :
  id >> 物品/武器/护甲id
  数量 >> 数量多少

  使用以上注释后, 使用脚本 :
  open_chest

  对于自定义名称的仓库, 则可以 :
  open_chest("小仓库")
  open_chest("Eric的宝箱")

  注意 : 所有事件中的所有注释都会读取一次,请确保在使用脚本之前使用了注释。

  使用规定 :
  属名脚本作者, TheoAllen. 你可以自由编辑此脚本,只要你不声明你是脚本的原作者
  如果你想用此脚本于商业游戏,请和我共享收益.别忘了给我一份免费的游戏拷贝.

=end
# =============================================================================
# 设定 :
# =============================================================================
module THEO
  module CHEST
    # =========================================================================
    # Vocabs
    # -------------------------------------------------------------------------
      AMOUNT_VOCAB  = "数量 :"       # 数量.
      ALL_VOCAB     = "全部"         # 全部类别.
      INV_VOCAB     = "背包"         # 背包.
      ST_VOCAB      = "库存"         # 库存.
    # =========================================================================
   
    # =========================================================================
      TRIGGER_GAIN_ALL  = :CTRL
    # -------------------------------------------------------------------------
    # 全部取出的按钮. 如果你设定为 :CTRL, 则在玩家按下CTRL和确定键 (z)后会取出
    # 全部物品
    # =========================================================================
   
    # =========================================================================
      SHOW_AMOUNT_MIN   = 10
    # -------------------------------------------------------------------------
    # 显示窗口数量的最小值.
    # =========================================================================
   
  end
end
# =============================================================================
# 设定结束 (除非清除你在干什么,否则以下内容勿动)
# =============================================================================
module THEO
  module CHEST
  module REGEXP
   
    ITEM_REGEX   = /<(?:ITEM|item):[ ]*[ ]*(\d+\s*,\s*\d*)>/i
    WEAPON_REGEX = /<(?:WEAPON|weapon):[ ]*[ ]*(\d+\s*,\s*\d*)>/i
    ARMOR_REGEX  = /<(?:ARMOR|armor):[ ]*[ ]*(\d+\s*,\s*\d*)>/i
   
  end
  end
end

class Scene_Chest < Scene_MenuBase
  
  include THEO::CHEST
  
  def initialize(key,st_vocab)
    $game_party.init_chest_cursors
    @last_active = :stash
    @key = key
    @st_vocab = st_vocab
  end
  
  def start
    super
    create_header_windows
    create_footer_window
    create_main_windows
    create_amount_window
    prepare
  end
  
  def create_header_windows
    create_help_window
    create_category_window
  end
  
  def create_main_windows
    create_inventory_window
    create_stash_window
  end
  
  def create_help_window
    @help = Window_Help.new
    @help.viewport = @viewport
  end
  
  def create_category_window
    @category = Window_ChestCategory.new
    @category.viewport = @viewport
    @category.y = @help.height
    @category.set_handler(:ok, method(:on_category_ok))
    @category.set_handler(:cancel, method(:return_scene))
  end
  
  def create_footer_window
    create_inv_footer
    create_st_footer
  end
  
  def create_inv_footer
    if $imported[:Theo_LimInventory]
      x = 0
      y = Graphics.height - 48
      w = Graphics.width/2
      @inv_footer = Window_ChestFreeSlot.new(x,y,w)
      @inv_footer.viewport = @viewport
    else
      @inv_footer = Window_ChestFooter.new(INV_VOCAB,$game_party,0)
      @inv_footer.viewport = @viewport
    end
  end
  
  def create_st_footer
    @st_footer = Window_ChestFooter.new(@st_vocab,$game_chests[@key],1)
    @st_footer.viewport = @viewport
  end
  
  def create_inventory_window
    x = 0
    y = @help.height + @category.height
    w = Graphics.width/2
    h = Graphics.height - y - @inv_footer.height
    @inventory = Window_Inventory.new(x,y,w,h)
    @inventory.viewport = @viewport
    @inventory.set_handler(:ok, method(:item_inventory_ok))
    @inventory.set_handler(:cancel, method(:on_inventory_cancel))
    @inventory.help_window = @help
    @category.item_window = @inventory
  end
  
  def create_stash_window
    x = Graphics.width / 2
    y = @inventory.y
    w = x
    h = @inventory.height
    @stash = Window_Stash.new(x,y,w,h,@key)
    @stash.viewport = @viewport
    @stash.set_handler(:ok, method(:item_stash_ok))
    @stash.set_handler(:cancel, method(:on_stash_cancel))
    @stash.help_window = @help
    @category.stash_window = @stash
  end
  
  def create_amount_window
    @amount = Window_ChestAmount.new
    @amount.viewport = @viewport
    @amount.inv_window = @inv_footer if $imported[:Theo_LimInventory]
  end
  
  # for future plan ~
  def refresh_all_footers
    @inv_footer.refresh
    @st_footer.refresh
  end
  
  def prepare
    unselect_all
    @category.show
    @category.activate
    @item_phase = false
    deactivate_item_windows
    hide_amount
  end
  
  def deactivate_item_windows
    @inventory.deactivate
    @stash.deactivate
  end
  
  def on_category_ok
    @category.deactivate
    activate_itemlist
    @item_phase = true
  end
  
  def item_inventory_ok
    unless @inventory.item
      @inventory.activate
      return
    end
    if @inventory.item_number < SHOW_AMOUNT_MIN
      store_items(1)
      @inventory.activate
      refresh_itemlist
    else
      @last_active = :inventory
      input_amount(@inventory)
    end
  end
  
  def item_stash_ok
    unless @stash.item
      @stash.activate
      return
    end
    if @stash.item_number < SHOW_AMOUNT_MIN
      gain_items(1)
      @stash.activate
      refresh_itemlist
    else
      @last_active = :stash
      input_amount(@stash)
    end
  end
  
  def on_stash_cancel
    @last_active = :stash
    memorize_st
    prepare
  end
  
  def on_inventory_cancel
    @last_active = :inventory
    memorize_inv
    prepare
  end
  
  def input_amount(window)
    memorize_all
    if window.equal?(@stash)
      @inventory.unselect
    else
      @stash.unselect
    end
    @amount.open
    @amount.item_window = window
    deactivate_item_windows
  end
  
  def hide_amount
    Sound.play_cancel
    @amount.close
    @amount.reset_amount
  end
  
  def update
    super
    @amount.mode = @last_active
    @inv_footer.mode = @last_active if $imported[:Theo_LimInventory]
    select_item_phase if @item_phase
    input_amount_phase if @amount.open?
  end
  
  def select_item_phase
    gain_all_items if trigger_gain_all_item?
    switch_window if Input.repeat?(:RIGHT) || Input.repeat?(:LEFT)
  end
  
  def input_amount_phase
    activate_itemlist if Input.trigger?(:B)
    if @amount.item_window.equal?(@stash) && Input.trigger?(:C)
      gain_items(@amount.amount)
    elsif @amount.item_window.equal?(@inventory) && Input.trigger?(:C)
      store_items(@amount.amount)
    end
  end
  
  def switch_window
    if @inventory.active
      switch_stash
    elsif @stash.active
      switch_inventory
    end
  end
  
  def switch_inventory
    memorize_st
    @stash.deactivate
    @stash.unselect
    @inventory.activate
    inv_select
  end
  
  def switch_stash
    @stash.activate
    st_select
    memorize_inv
    @inventory.deactivate
    @inventory.unselect
  end
  
  def gain_all_items
    if @stash.active
      @stash.data.each do |item|
        gain_items(@stash.item_number(item),item)
      end
      @stash.select(0)
    else
      @inventory.data.each do |item|
        store_items(@inventory.item_number(item),item)
      end
      @inventory.select(0)
    end
    refresh_itemlist
    refresh_all_footers
  end
  
  def trigger_gain_all_item?
    Input.press?(THEO::CHEST::TRIGGER_GAIN_ALL) && Input.trigger?(:C)
  end
  
  def gain_items(amount, item = @stash.item)
    if $imported[:Theo_LimInventory]
      amount = [[amount,0].max,$game_party.inv_max_item(item)].min
    end
    $game_party.gain_item(item,amount)
    $game_chests[@key].lose_item(item,amount)
    on_amount_confirm if @amount.open?
  end
  
  def store_items(amount, item = @inventory.item)
    $game_chests[@key].gain_item(item,amount)
    $game_party.lose_item(item,amount)
    on_amount_confirm if @amount.open?
  end
  
  def refresh_itemlist
    @stash.refresh   
    @inventory.refresh
  end
  
  def on_amount_confirm
    Sound.play_ok
    refresh_itemlist
    unselect_all
    activate_itemlist
  end
  
  def activate_itemlist
    hide_amount
    case @last_active
    when :stash
      activate_stash
    when :inventory
      activate_inventory
    end
    @item_phase = true
  end
  
  def activate_inventory
    @inventory.activate
    @stash.unselect
    inv_select
  end
  
  def activate_stash
    @stash.activate
    @inventory.unselect
    st_select
  end
  
  def memorize_inv
    $game_party.last_inv = @inventory.index
  end
  
  def memorize_st
    $game_party.last_st = @stash.index
  end
  
  def inv_select
    @inventory.index = [[$game_party.last_inv,@inventory.item_max-1].min,0].max
  end
  
  def st_select
    @stash.index = [[$game_party.last_st,@stash.item_max-1].min,0].max
  end
  
  def unselect_all
    @inventory.unselect
    @stash.unselect
  end
  
  def memorize_all
    memorize_inv
    memorize_st
  end
  
end

if $imported[:Theo_LimInventory]
class Window_ChestFreeSlot < Window_FreeSlot
  attr_accessor :item
  attr_accessor :mode
  
  def initialize(x,y,w)
    @add_number = 0
    @mode = :stash
    super(x,y,w)
  end
  
  def add_number=(number)
    temp = @add_number
    @add_number = number
    refresh if temp != number
  end
  
  def draw_inv_slot(x,y,width = contents.width,align = 2)
    item_size = @item.nil? ? 0 : @item.inv_size
    item_size = -item_size if @mode == :inventory
    txt = sprintf("%d/%d",$game_party.total_inv_size + @add_number *
    item_size, $game_party.inv_max)
    color = Theo::LimInv::NearMaxed_Color
    near_max = ($game_party.total_inv_size + @add_number * item_size).to_f /
      $game_party.inv_max >= (100 - Theo::LimInv::NearMaxed_Percent)/100.0
    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
  
end
end

class Window_ChestCategory < Window_ItemCategory
  attr_reader :stash_window
  
  def col_max
    return 4
  end
  
  def update
    super
    @stash_window.category = current_symbol if @stash_window
  end
  
  def make_command_list
    add_command(THEO::CHEST::ALL_VOCAB, :all)
    add_command(Vocab::item,     :item)
    add_command(Vocab::weapon,   :weapon)
    add_command(Vocab::armor,    :armor)
  end
  
  def stash_window=(stash_window)
    @stash_window = stash_window
    update
  end
  
end

class Window_Inventory < Window_ItemList
  attr_reader :data
  
  def col_max
    return 1
  end
  
  def current_item_enabled?
    return true
  end
  
  def include?(item)
    case @category
    when :item
      item.is_a?(RPG::Item) && !item.key_item?
    when :weapon
      item.is_a?(RPG::Weapon)
    when :armor
      item.is_a?(RPG::Armor)
    when :all
      item.is_a?(RPG::Armor) || item.is_a?(RPG::Weapon) || item.is_a?(RPG::Item)
    else
      false
    end
  end
  
  def draw_item(index)
    item = @data[index]
    if item
      rect = item_rect(index)
      rect.width -= 4
      draw_item_name(item, rect.x, rect.y, true,contents.width)
      draw_item_number(rect, item)
    end
  end
  
  def item_number(item = @data[index])
    $game_party.item_number(item)
  end
  
  def process_ok
    return if Input.press?(THEO::CHEST::TRIGGER_GAIN_ALL)
    super
  end
  
end

class Window_Stash < Window_ItemList
  attr_reader :data
  
  def initialize(x, y, width, height, key)
    @key = key
    super(x,y,width,height)
    @category = :none
    @data = []
  end
  
  def col_max
    return 1
  end
  
  def current_item_enabled?
    enable?(item)
  end
  
  def enable?(item)
    return true unless $imported[:Theo_LimInventory]
    return $game_party.inv_max_item(item) > 0
  end
  
  def include?(item)
    case @category
    when :item
      item.is_a?(RPG::Item) && !item.key_item?
    when :weapon
      item.is_a?(RPG::Weapon)
    when :armor
      item.is_a?(RPG::Armor)
    when :all
      item.is_a?(RPG::Armor) || item.is_a?(RPG::Weapon) || item.is_a?(RPG::Item)
    else
      false
    end
  end
  
  def make_item_list
    @data = $game_chests[@key].all_items.select {|item| include?(item) }
    @data.push(nil) if include?(nil)
  end
  
  def draw_item(index)
    item = @data[index]
    if item
      rect = item_rect(index)
      rect.width -= 4
      draw_item_name(item, rect.x, rect.y, enable?(item),contents.width)
      draw_item_number(rect, item)
    end
  end
  
  def draw_item_number(rect, item)
    draw_text(rect, sprintf(":%2d", $game_chests[@key].item_number(item)), 2)
  end
  
  def item_number(item = @data[index])
    $game_chests[@key].item_number(item)
  end
  
  def process_ok
    return if Input.press?(THEO::CHEST::TRIGGER_GAIN_ALL)
    super
  end
  
end

class Window_ChestAmount < Window_Base  
  attr_accessor :item_window
  attr_accessor :mode
  attr_reader   :amount
  
  def initialize
    super(0,0,window_width,window_height)
    self.openness = 0
    @mode = :stash
    reset_amount
    update_position
    refresh
  end
  
  def inv_window=(window)
    @inv_window = window
  end
  
  def reset_amount
    @amount = 0
    refresh
  end
  
  def open
    super
    reset_amount
  end
  
  def update_position
    self.x = (Graphics.width / 2) - (self.width / 2)
    self.y = (Graphics.height / 2) - (self.height / 2)
  end
  
  def refresh
    contents.clear
    draw_text(0,0,contents.width,24,THEO::CHEST::AMOUNT_VOCAB,)
    draw_text(0,0,contents.width,24,@amount,2)
  end
  
  def window_width
    return 200
  end
  
  def window_height
    return 24+24
  end
  
  def update
    super
    if @inv_window
      @inv_window.add_number = @amount
      @inv_window.item = @item_window.item if @item_window
    end
    if open?
      increment if Input.repeat?(:RIGHT)
      decrement if Input.repeat?(:LEFT)
      ten_increment if Input.repeat?(:UP)
      ten_decrement if Input.repeat?(:DOWN)
    end
  end
  
  def increment
    change_amount(1)
  end
  
  def decrement
    change_amount(-1)
  end
  
  def ten_increment
    change_amount(10)
  end
  
  def ten_decrement
    change_amount(-10)
  end
  
  def change_amount(modifier)
    @amount = [[@amount+modifier,0].max,max_amount].min
    refresh
  end
  
  def show
    super
    reset_amount
  end
  
  def max_amount
    if $imported[:Theo_LimInventory]
      if @mode == :inventory
        @item_window.item_number rescue 0
      elsif @mode == :stash
        [@item_window.item_number,$game_party.inv_max_item(@item_window.item)].min
      end
    else
      @item_window.item_number rescue 0
    end
  end
  
end

class Window_ChestFooter < Window_Base
  
  include THEO::CHEST
  
  def initialize(vocab,object,x)
    w = Graphics.width/2
    h = fitting_height(1)
    y = Graphics.height - h
    x = (Graphics.width/2) * x
    @vocab = vocab
    super(x,y,w,h)
    @object = object
    refresh
  end
  
  def refresh
    contents.clear
    cx = text_size(@vocab).width
    draw_text(0,0,contents.width,line_height,@vocab,1)
  end
  
end

module DataManager
  
  class << self
    alias pre_create_chest create_game_objects
    alias pre_chest_save_contents make_save_contents
    alias pre_extract_chests extract_save_contents
  end
  
  def self.create_game_objects
    pre_create_chest
    create_chest_object
  end
  
  def self.create_chest_object
    $game_chests = Game_Chest.new
  end
  
  def self.make_save_contents
    contents = pre_chest_save_contents
    contents[:chest] = $game_chests
    contents
  end
  
  def extract_save_contents(contents)
    pre_extract_chests(contents)
    $game_chests = contents[:chest]
  end
  
end

class Game_Chest
  
  def initialize
    @data = {}
    @explored = {}
  end
  
  def[](key)
    (@data[key] ||= Game_Stash.new)
  end
  
  def explored
    @explored
  end
  
end

class Game_Stash
  attr_accessor :items_stash
  attr_accessor :weapons_stash
  attr_accessor :armors_stash
  
  def initialize
    @items_stash = {}
    @weapons_stash = {}
    @armors_stash = {}
  end
  
  def refresh
    evaluate(@items_stash)
    evaluate(@weapons_stash)
    evaluate(@armors_stash)
  end
  
  def evaluate(stash)
    stash.keys.each do |key|
      stash.delete(key) if stash[key] <= 0
    end
  end
  
  def items
    @items_stash.keys.collect {|id| $data_items[id] }
  end
  
  def weapons
    @weapons_stash.keys.collect {|id| $data_weapons[id] }
  end
  
  def armors
    @armors_stash.keys.collect {|id| $data_armors[id] }
  end
  
  def all_items
    items + weapons + armors
  end
  
  def item_number(item)
    if item.is_a?(RPG::Item)
      return @items_stash[item.id] ||= 0
    elsif item.is_a?(RPG::Weapon)
      return @weapons_stash[item.id] ||= 0
    elsif item.is_a?(RPG::Armor)
      return @armors_stash[item.id] ||= 0
    end
    refresh
  end
  
  def gain_item(item, amount)
    return unless item
    stash = pick_stash(item)
    stash[item.id] = 0 if stash[item.id].nil?
    stash[item.id] += amount
    refresh
  end
  
  def lose_item(item,amount)
    gain_item(item,-amount)
  end
  
  def pick_stash(item)
    if item.is_a?(RPG::Item)
      return @items_stash
    elsif item.is_a?(RPG::Weapon)
      return @weapons_stash
    elsif item.is_a?(RPG::Armor)
      return @armors_stash
    end
  end
  
end

class Game_Party
  attr_accessor :last_inv
  attr_accessor :last_st
  
  alias pre_chest_init initialize
  def initialize
    pre_chest_init
    init_chest_cursors
  end
  
  def init_chest_cursors
    @last_inv   = 0
    @last_st = 0
  end
  
end

class Game_Interpreter
  
  def open_chest(st_vocab = THEO::CHEST::ST_VOCAB,key = [@map_id,@event_id])
    if st_vocab.is_a?(Numeric)
      key = st_vocab
      st_vocab = THEO::CHEST::ST_VOCAB
    end
    SceneManager.call_chest(key,st_vocab)
  end
  
  alias pre_chest_command_108 command_108
  def command_108
    pre_chest_command_108
    read_chest_comments
  end
  
  def read_chest_comments
    map = @map_id
    event = @event_id
    key = [map,event]
    return if $game_chests.explored[key]
    @comments.each do |comment|
      case comment
      when THEO::CHEST::REGEXP::ITEM_REGEX
        x = $1.scan(/\d+/)
        $game_chests[key].items_stash[x[0].to_i] = x[1].to_i
      when THEO::CHEST::REGEXP::WEAPON_REGEX
        x = $1.scan(/\d+/)
        $game_chests[key].weapons_stash[x[0].to_i] = x[1].to_i
      when THEO::CHEST::REGEXP::ARMOR_REGEX
        x = $1.scan(/\d+/)
        $game_chests[key].armors_stash[x[0].to_i] = x[1].to_i
      end
    end
    $game_chests.explored[key] = next_event_code != 108
  end
  
end

module SceneManager
  
  def self.call_chest(key,st_vocab = THEO::CHEST::ST_VOCAB)
    @stack.push(@scene)
    @scene = Scene_Chest.new(key,st_vocab)
  end
  
end
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册会员

本版积分规则

拿上你的纸笔,建造一个属于你的梦想世界,加入吧。
 注册会员
找回密码

站长信箱:[email protected]|手机版|小黑屋|无图版|Project1游戏制作

GMT+8, 2025-11-27 01:02

Powered by Discuz! X3.1

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表