| 赞 | 4 |
| VIP | |
| 好人卡 | |
| 积分 | 16 |
| 经验 | |
| 最后登录 | 2026-9-24 |
| 在线时间 | 523 小时 |
- 梦石
- 0
- 星屑
- 1554
- 在线时间
- 523 小时
- 注册时间
- 2015-8-23
- 回帖
- 83
|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 寂寞的青椒 于 2026-7-14 18:23 编辑
这个是模拟三角洲的摸金系统,不全像,但是效果类似,可玩性很高,配合物品颜色描绘脚本使用效果更棒
[fold=摸金脚本]#==============================================================================
# [PS0] 摸金模式 - 容器开箱系统 (指定物品池版)
#==============================================================================
module LOOT_CONFIG
BASE_SCAN_TIME = 30 # 基础扫描时间(帧数)
QUALITY_TIME_BONUS = 25 # 每级品质增加的时间
ITEM_COUNT_MIN = 1
ITEM_COUNT_MAX = 6
WINDOW_WIDTH = 440
WINDOW_HEIGHT = 350
# ========== 物品池配置 ==========
# 方式1:指定物品ID范围(推荐)
ITEM_ID_RANGE = 1..30 # 只使用1-30号物品
# 方式2:手动指定物品ID列表(如果需要更精确的控制)
# 如果设置了 ITEM_ID_LIST,则会忽略 ITEM_ID_RANGE
# ITEM_ID_LIST = [1, 2, 3, 5, 8, 13, 21]
# 是否排除名称为空的物品
EXCLUDE_EMPTY_NAME = true # true=排除空名称物品,false=不排除
# 是否排除没有名称且没有图标的物品(彻底空白)
EXCLUDE_COMPLETELY_EMPTY = true
end
#==============================================================================
# ■ Game_Interpreter (修改)
#==============================================================================
class Game_Interpreter
def open_container(container_id, item_list = nil)
$container_data ||= {}
$container_data[container_id] ||= Game_Container.new
container = $container_data[container_id]
if !container.opened
if item_list.nil? || item_list.empty?
item_list = get_valid_item_list
end
container.generate_items(item_list)
elsif !container.has_items?
if !item_list.nil? && !item_list.empty?
container.generate_items(item_list)
elsif !get_valid_item_list.empty?
container.generate_items(get_valid_item_list)
end
end
if container.is_empty?
$game_message.add("容器是空的")
return
end
SceneManager.scene.create_loot_window(container)
end
# 获取有效的物品列表(排除空白物品)
def get_valid_item_list
items = []
# 获取物品ID列表
if defined?(LOOT_CONFIG::ITEM_ID_LIST) && LOOT_CONFIG::ITEM_ID_LIST.is_a?(Array)
id_list = LOOT_CONFIG::ITEM_ID_LIST
else
id_list = LOOT_CONFIG::ITEM_ID_RANGE.to_a
end
id_list.each do |i|
item = $data_items
next if item.nil?
# 排除完全空白的物品
if LOOT_CONFIG::EXCLUDE_COMPLETELY_EMPTY
next if item.name.nil? || item.name.empty?
next if item.icon_index == 0 && (item.description.nil? || item.description.empty?)
end
# 排除名称为空的物品
if LOOT_CONFIG::EXCLUDE_EMPTY_NAME
next if item.name.nil? || item.name.empty?
end
# 排除没有图标的物品(可选)
# next if item.icon_index == 0
items << item
end
return items
end
end
#==============================================================================
# ■ Game_Container
#==============================================================================
class Game_Container
attr_reader :items
attr_reader :looted_flags
attr_accessor :opened
def initialize
@items = []
@looted_flags = []
@opened = false
end
def generate_items(item_list)
count = rand(LOOT_CONFIG::ITEM_COUNT_MAX - LOOT_CONFIG::ITEM_COUNT_MIN + 1) + LOOT_CONFIG::ITEM_COUNT_MIN
@items = []
@looted_flags = []
if item_list && item_list.size > 0
count.times do
item = item_list.sample
@items << item if item
@looted_flags << false
end
end
@opened = true
end
def get_remaining_indices
indices = []
@looted_flags.each_with_index do |flag, i|
indices << i if !flag
end
return indices
end
def loot_item(index)
if index >= 0 && index < @items.size && !@looted_flags[index]
@looted_flags[index] = true
return true
end
return false
end
def all_looted?
return !@looted_flags.include?(false)
end
def get_item_by_index(index)
return @items[index]
end
def has_items?
return @items.size > 0
end
def is_empty?
return get_remaining_indices.empty?
end
end
#==============================================================================
# ■ Window_LootDisplay
#==============================================================================
class Window_LootDisplay < Window_Base
attr_reader :closed
def initialize(container)
x = (Graphics.width - LOOT_CONFIG::WINDOW_WIDTH) / 2
y = (Graphics.height - LOOT_CONFIG::WINDOW_HEIGHT) / 2
super(x, y, LOOT_CONFIG::WINDOW_WIDTH, LOOT_CONFIG::WINDOW_HEIGHT)
@closed = false
@container = container
@current_index = 0
@scan_progress = 0
@displaying = false
@finished = false
@cursor_index = 0
@selection_mode = false
@input_delay = 0
@waiting_for_input = false
@is_scanning = false
@current_item = nil
@scan_timer = 0
@revealed_items = []
self.opacity = 255
self.visible = true
self.active = true
@remaining_indices = @container.get_remaining_indices
@display_indices = @remaining_indices.clone
refresh
start_display
end
def start_display
@displaying = true
@current_index = 0
@finished = false
@selection_mode = false
@cursor_index = 0
@waiting_for_input = false
@is_scanning = false
@scan_progress = 0
@revealed_items = []
@remaining_indices = @container.get_remaining_indices
@display_indices = @remaining_indices.clone
if @display_indices.size > 0
start_scan_current
end
refresh
end
def start_scan_current
if @current_index < @display_indices.size
item_index = @display_indices[@current_index]
@current_item = @container.get_item_by_index(item_index)
@is_scanning = true
@scan_progress = 0
total_frames = get_scan_time(@current_item)
@scan_step = 100.0 / total_frames
refresh
else
@displaying = false
@selection_mode = true
@cursor_index = 0
@waiting_for_input = false
@remaining_indices = @container.get_remaining_indices
refresh
end
end
def get_scan_time(item)
return LOOT_CONFIG::BASE_SCAN_TIME if item.nil?
quality = get_quality_level(item)
return LOOT_CONFIG::BASE_SCAN_TIME + quality * LOOT_CONFIG::QUALITY_TIME_BONUS
end
def get_quality_level(item)
return 0 if item.nil?
if item.is_a?(RPG::EquipItem)
c = item.up || 0
else
n = item.note
a = n.split{/<(?:Quality|品质)\s*(.+)>/i}
c = a[1].to_i
end
return c
end
def get_quality_color(quality)
case quality
when 0..1
return Color.new(255, 255, 255)
when 2..3
return Color.new(128, 255, 128)
when 4..5
return Color.new(128, 128, 255)
when 6..7
return Color.new(255, 0, 255)
when 8..9
return Color.new(255, 128, 128)
when 10..11
return Color.new(255, 128, 0)
else
return Color.new(255, 255, 128)
end
end
def get_quality_text(quality)
case quality
when 0..1
return "普通"
when 2..3
return "平庸"
when 4..5
return "精良"
when 6..7
return "卓越"
when 8..9
return "神秘"
when 10..11
return "传说"
else
return "特殊"
end
end
def safe_contents
return nil if @closed
return nil if disposed?
return contents if contents && !contents.disposed?
return nil
end
def refresh
return if @closed
return if disposed?
c = safe_contents
return if c.nil?
begin
c.clear
c.font.color = normal_color
if !@selection_mode
c.draw_text(0, 0, contents_width, 32, "【扫描中...】", 1)
else
c.draw_text(0, 0, contents_width, 32, "【选择物品】", 1)
end
if @display_indices.empty?
c.draw_text(0, 40, contents_width, line_height, "容器是空的...", 1)
return
end
if !@selection_mode
y = 35
item_height = 50
max_display = 5
@revealed_items.each_with_index do |item, idx|
rect = Rect.new(20, y + idx * item_height, 380, item_height - 5)
quality = get_quality_level(item)
border_color = get_quality_color(quality)
c.fill_rect(rect.x - 2, rect.y - 2, rect.width + 4, rect.height + 4,
Color.new(border_color.red, border_color.green, border_color.blue, 80))
draw_item_name(item, rect.x + 5, rect.y + 5, true, 300)
c.font.color = get_quality_color(quality)
c.font.size = 14
c.draw_text(rect.x + 280, rect.y + 5, 80, 20, get_quality_text(quality))
c.font.size = 20
c.font.color = normal_color
c.font.color = Color.new(100, 255, 100)
c.draw_text(rect.x + 360, rect.y + 5, 30, 24, "✓")
c.font.color = normal_color
end
scan_y = 35 + @revealed_items.size * item_height
if @is_scanning && @current_item
rect = Rect.new(20, scan_y, 380, item_height - 5)
c.fill_rect(rect.x - 2, rect.y - 2, rect.width + 4, rect.height + 4,
Color.new(255, 255, 200, 80 * @scan_progress / 100))
if @scan_progress < 100
scan_line_y = rect.y + ((rect.height - 5) * @scan_progress / 100)
c.fill_rect(rect.x, scan_line_y, rect.width, 2, Color.new(255, 255, 200, 200))
end
if @scan_progress >= 100
draw_item_name(@current_item, rect.x + 5, rect.y + 5, true, 300)
quality = get_quality_level(@current_item)
c.font.color = get_quality_color(quality)
c.font.size = 14
c.draw_text(rect.x + 280, rect.y + 5, 80, 20, get_quality_text(quality))
c.font.size = 20
c.font.color = normal_color
c.font.color = Color.new(100, 255, 100)
c.draw_text(rect.x + 360, rect.y + 5, 30, 24, "✓")
c.font.color = normal_color
else
c.font.color = Color.new(200, 200, 200, 100 + (100 * @scan_progress / 100))
c.draw_text(rect.x + 30, rect.y + 5, 250, 24, "■■■■■■■■■■")
c.font.color = normal_color
c.font.color = Color.new(200, 200, 200)
c.draw_text(rect.x + 280, rect.y + 5, 80, 20, sprintf("%d%%", @scan_progress))
end
c.font.color = Color.new(200, 200, 200)
c.font.size = 14
c.draw_text(0, contents_height - 25, contents_width, 20,
sprintf("扫描 %d/%d", @revealed_items.size + 1, @display_indices.size), 0)
c.font.size = 20
end
else
@remaining_indices = @container.get_remaining_indices
if @remaining_indices.empty?
c.draw_text(0, 40, contents_width, line_height, "所有物品已取走!", 1)
return
end
if @cursor_index >= @remaining_indices.size
@cursor_index = @remaining_indices.size - 1
end
if @cursor_index < 0
@cursor_index = 0
end
y = 35
max_display = 5
start_index = 0
if @remaining_indices.size > max_display
if @cursor_index >= max_display - 1
start_index = @cursor_index - (max_display - 1)
if start_index + max_display > @remaining_indices.size
start_index = @remaining_indices.size - max_display
end
end
end
end_index = [start_index + max_display, @remaining_indices.size].min
for i in start_index...end_index
item_index = @remaining_indices
item = @container.get_item_by_index(item_index)
rect = Rect.new(20, y, 380, line_height)
if i == @cursor_index
c.fill_rect(rect.x - 5, rect.y - 2, rect.width + 10, rect.height + 4,
Color.new(255, 255, 255, 50))
end
if item
draw_item_name(item, rect.x, rect.y, true, 300)
end
y += line_height
end
if @remaining_indices.size > max_display
if start_index > 0
c.font.color = Color.new(255, 255, 255)
c.draw_text(0, 35, 20, line_height, "▲")
end
if end_index < @remaining_indices.size
c.font.color = Color.new(255, 255, 255)
c.draw_text(0, contents_height - 40, 20, line_height, "▼")
end
end
c.font.color = Color.new(255, 255, 128)
hint_text = "方向键选择 | 确定键选取 | 取消键关闭"
c.draw_text(0, contents_height - 30, contents_width, line_height, hint_text, 1)
end
rescue RGSSError
# 忽略
end
end
def update
super if !@closed && !disposed?
return if @closed
return if disposed?
begin
if @displaying && !@selection_mode
if @is_scanning
@scan_progress += @scan_step
if @scan_progress >= 100
@scan_progress = 100
@is_scanning = false
if @current_item
@revealed_items << @current_item
end
Sound.play_equip
@scan_timer = 20
refresh
else
refresh
end
else
@scan_timer -= 1
if @scan_timer <= 0
@current_index += 1
if @current_index >= @display_indices.size
@displaying = false
@selection_mode = true
@cursor_index = 0
@waiting_for_input = false
@remaining_indices = @container.get_remaining_indices
refresh
else
start_scan_current
end
end
end
elsif @selection_mode
if @waiting_for_input
@waiting_for_input = false
return
end
if @input_delay > 0
@input_delay -= 1
else
@remaining_indices = @container.get_remaining_indices
if @remaining_indices.empty?
close
return
end
if @cursor_index >= @remaining_indices.size
@cursor_index = @remaining_indices.size - 1
end
moved = false
if Input.repeat?(:DOWN)
if @cursor_index < @remaining_indices.size - 1
@cursor_index += 1
moved = true
end
elsif Input.repeat?(:UP)
if @cursor_index > 0
@cursor_index -= 1
moved = true
end
end
if moved
refresh
@input_delay = 8
end
if Input.trigger?(:C)
if @cursor_index < @remaining_indices.size && @cursor_index >= 0
item_index = @remaining_indices[@cursor_index]
if !@container.looted_flags[item_index]
if @container.loot_item(item_index)
item = @container.get_item_by_index(item_index)
$game_party.gain_item(item, 1) if item
Sound.play_equip
@waiting_for_input = true
@remaining_indices = @container.get_remaining_indices
if @remaining_indices.empty?
@selection_mode = false
@finished = true
Sound.play_save
close
else
if @cursor_index >= @remaining_indices.size
@cursor_index = @remaining_indices.size - 1
end
refresh
end
end
end
end
elsif Input.trigger?(:B)
close
end
end
end
rescue RGSSError
# 忽略
end
end
def close
return if @closed
@closed = true
self.visible = false
self.active = false
begin
self.dispose if !self.disposed?
rescue
end
end
def closed?
return @closed
end
end
#==============================================================================
# ■ Scene_Map
#==============================================================================
class Scene_Map < Scene_Base
attr_reader :loot_window
alias :loot_start :start unless method_defined?(:loot_start)
def start
loot_start
@loot_window = nil
end
def create_loot_window(container)
if @loot_window && !@loot_window.closed?
begin
@loot_window.close
rescue
end
@loot_window = nil
end
@loot_window = Window_LootDisplay.new(container)
@loot_window.z = 200
end
alias :loot_update :update unless method_defined?(:loot_update)
def update
if @loot_window && !@loot_window.closed?
begin
@loot_window.update
update_basic
return
rescue RGSSError
@loot_window = nil
end
end
loot_update
end
alias :loot_terminate :terminate unless method_defined?(:loot_terminate)
def terminate
if @loot_window && !@loot_window.closed?
begin
@loot_window.close
rescue
end
@loot_window = nil
end
loot_terminate
end
end
#==============================================================================
# [PS0] End of Script
#==============================================================================[/fold]
[fold=物品颜色描绘脚本]#在下面if c <= 0处修改强化升到各级时显示的颜色
#c代表着升级次数
#==============================================================================
# [PS0]物品颜色描绘
# Window_Base_Itemcolor
#------------------------------------------------------------------------------
# 在物品、技能选项中显示物品品质并显示品质框和修改物品名颜色。
#==============================================================================
# [更新记录]
# - 2016.05.05 BY somebody
# - 恢复了 “在【非“装备”类物品中】备注栏使用【<品质 7>】字样,来控制显示颜色”的功能,物品颜色与品质无关,如需在
#“变色”之余,使物品有个好的性能,需要自行修改【数据库】
# - 2012.02.17 By wyongcan
# * 修改为适合装备系统增强 不会读取说明中的品质
# - 2012.01.03 By 仲秋启明
# * 修改为VA定义
# - 2011.12.27 By 仲秋启明
# * 移植至RGSS3,遵循PS0协议;
# * 优化数据库备注中设定方法
# - 2011.08.22 By 冰舞蝶恋
# * 蓝本(实用·极简 -- 按品质,给物品描绘色彩边框)
# - 2010.08.06 By 仲秋启明
# * 蓝本(物品颜色描绘脚本(完整无冲突版))
#------------------------------------------------------------------------------
# [使用方法]
# - 替换原Window_Base中的draw_item_name定义或复制到Main之前
#==============================================================================
$_PS0 = {} if $_PS0 == nil
$_PS0["Window_Base_Itemcolor"] = 20111227
#==============================================================================
# [PS0] 通用配置模块 下面if c <= 0处修改强化升到各级时显示的颜色 c代表着升级次数
#==============================================================================
module PS0
module Window_Base_Itemcolor
Color1 = Color.new(255, 255, 255) # 一般品质的色彩(白,1)
Color2 = Color.new(128, 255, 128) # 平庸品质的色彩(绿,2)
Color3 = Color.new(128, 128, 255) # 精良品质的色彩(蓝,3)
Color4 = Color.new(255, 0, 255) # 卓越品质的色彩(紫,4)
Color5 = Color.new(255, 128, 128) # 神秘品质的色彩(红,5)
Color6 = Color.new(255, 128, 0) # 传说品质的色彩(橙,6)
Color7 = Color.new(255, 255, 128) # 特殊品质的色彩(黄,7)
end
end
#==============================================================================
# ■ Window_Base
#==============================================================================
class Window_Base < Window
def draw_item_name(item, x, y, enabled = true, width = 172)
return unless item
n = item.note
a = n.split{/<(?:Quality|品质)\s*(.+)>/i}
item.up = 0 if item.is_a?(RPG::EquipItem) && item.up == nil
c = 0
if item.is_a?(RPG::EquipItem)
then
c = item.up
else
c = a[1].to_i
end
if c <= 0
color = PS0::Window_Base_Itemcolor::Color1
elsif c <= 2
color = PS0::Window_Base_Itemcolor::Color2
elsif c <= 4
color = PS0::Window_Base_Itemcolor::Color3
elsif c <= 6
color = PS0::Window_Base_Itemcolor::Color4
elsif c <= 8
color = PS0::Window_Base_Itemcolor::Color5
elsif c <= 10
color = PS0::Window_Base_Itemcolor::Color6
elsif c <= 12
color = PS0::Window_Base_Itemcolor::Color7
else
color = Color.new(0, 0, 0, 0)
end
self.contents.fill_rect(x, y, 24, 1, color)
self.contents.fill_rect(x, y, 1, 24, color)
self.contents.fill_rect(x, y+23, 24, 1, color)
self.contents.fill_rect(x+23, y, 1, 24, color)
draw_icon(item.icon_index, x, y, enabled)
change_color(color, enabled)
if item.is_a?(RPG::EquipItem) && item.up != nil && item.up != 0
draw_text(x + 24, y, width, line_height, item.name + "+" + item.up.to_s)
return
end
draw_text(x + 24, y, width, line_height, item.name)
end
end
#==============================================================================
# [PS0] End of Script
#==============================================================================
[/fold] |
|