#==============================================================================
# ■ Window_SkillConfirm
#==============================================================================
class Window_SkillConfirm < Window_Selectable
def initialize
super((Graphics.width - 240) / 2, 200, 240, 96)
self.opacity = 200
@item_max = 2
@column_max = 2
@item_width = 120
refresh
end
def unselect
self.index = -1
end
# 添加item_max方法覆盖
def item_max
2
end
# 新增:覆盖方向键处理逻辑
def cursor_right(wrap = false)
if index % @column_max < @column_max - 1
select((index + 1) % @item_max)
end
end
def cursor_left(wrap = false)
if index % @column_max > 0
select((index - 1) % @item_max)
end
end
# 修改:恢复上下键功能但限制移动
def cursor_down(wrap = false)
# 禁用垂直移动
end
def cursor_up(wrap = false)
# 禁用垂直移动
end
# 修改:调整光标移动判断
def cursor_movable?
return false unless super
return false if @cursor_all
(index % @column_max > 0 && Input.repeat?(:LEFT)) ||
(index % @column_max < @column_max - 1 && Input.repeat?(:RIGHT))
end
def refresh
contents.clear
# 绘制标题(添加居中参数)
draw_text(0, 0, 240, line_height, "是否忘记该技能?", 1)
# 使用循环绘制可选项(添加居中参数)
@item_max.times do |i|
rect = item_rect(i)
text = i == 0 ? "确认" : "取消"
draw_text(rect, text, 1) # 使用矩形区域和居中参数
end
end
# 修正光标矩形计算方法
def item_rect(index)
rect = Rect.new
rect.width = @item_width
rect.height = line_height
rect.x = index % @column_max * (rect.width + 0) # 列间距为0
rect.y = line_height * 2 # 标题下方留两行空间
rect
end
# 重写绘制光标方法
def draw_cursor(index)
rect = item_rect(index)
text = index == 0 ? "确认" : "取消"
# 获取实际文字尺寸
text_width = text_size(text).width + 8 # 增加边距
text_height = line_height * 0.8
# 计算居中坐标
cursor_x = rect.x + (rect.width - text_width) / 2
cursor_y = rect.y + (rect.height - text_height) / 2
draw_cursor_rect(cursor_x, cursor_y, text_width, text_height)
end
# 重写绘制项目方法,调用调整后的光标绘制方法
def draw_item(index)
rect = item_rect(index)
text = index == 0 ? "确认" : "取消"
draw_text(rect.x, rect.y, rect.width, rect.height, text)
if index == self.index
draw_cursor(index)
end
end
# # 重写 update_cursor 方法
def update_cursor
if index >= 0
rect = item_rect(index)
text = index == 0 ? "确认" : "取消"
text_width = text_size(text).width + 8
text_height = line_height * 0.8
cursor_x = rect.x + (rect.width - text_width) / 2
cursor_y = rect.y + (rect.height - text_height) / 2
self.cursor_rect.set(cursor_x, cursor_y, text_width, text_height)
else
self.cursor_rect.empty
end
end
# 简化绘制项目方法
def draw_item(index)
rect = item_rect(index)
text = index == 0 ? "确认" : "取消"
draw_text(rect, text, 1) # 使用矩形区域和居中参数
end
end
# 以下部分代码保持不变
#==============================================================================
# ■ Scene_Skill
#==============================================================================
class Scene_Skill < Scene_ItemBase
#--------------------------------------------------------------------------
# ● 开始处理(新增确认窗口创建)
#--------------------------------------------------------------------------
alias start_skill_confirm start
def start
start_skill_confirm
create_skill_confirm_window
end
#--------------------------------------------------------------------------
# ● 创建技能确认窗口
#--------------------------------------------------------------------------
def create_skill_confirm_window
@confirm_window = Window_SkillConfirm.new
@confirm_window.viewport = @viewport
@confirm_window.hide.deactivate # 增加deactivate
@confirm_window.hide
@confirm_window.set_handler(:ok, method(:on_confirm_ok))
@confirm_window.set_handler(:cancel, method(:on_confirm_cancel))
@confirm_window.select(0) # 添加默认选择项
end
#--------------------------------------------------------------------------
# ● アイテムウィンドウの作成
#--------------------------------------------------------------------------
def create_item_window
wx = 0
wy = @status_window.y + @status_window.height
ww = Graphics.width
wh = Graphics.height - wy
@item_window = Window_SkillList.new(wx, wy, ww, wh)
@item_window.actor = @actor
@item_window.viewport = @viewport
@item_window.help_window = @help_window
@item_window.set_handler(:ok, method(:on_item_ok))
@item_window.set_handler(:cancel, method(:on_item_cancel))
@item_window.set_handler(:CTRL, method(:on_item_del))
@command_window.skill_window = @item_window
end
#--------------------------------------------------------------------------
# ● スキルを忘れる(修改后的版本)
#--------------------------------------------------------------------------
def on_item_del
if !item.nil?
Sound.play_ok
@confirm_window.show.activate
@confirm_window.select(0) # 新增这行重置选择状态
@item_window.deactivate
else
Sound.play_buzzer
end
end
#--------------------------------------------------------------------------
# ● 确认窗口[确定]
#--------------------------------------------------------------------------
# 修改 Scene_Skill 中的 on_confirm_ok 方法
def on_confirm_ok
# 根据当前选中的索引判断操作
if @confirm_window.index == 0
# 确认操作
skill_id = item.id
@actor.forget_skill(skill_id)
@item_window.refresh
Sound.play_ok
@confirm_window.hide.deactivate
activate_item_window
@confirm_window.unselect
else
# 取消操作
on_confirm_cancel
end
end
#--------------------------------------------------------------------------
# ● 确认窗口[取消]
#--------------------------------------------------------------------------
def on_confirm_cancel
Sound.play_cancel
@confirm_window.hide.deactivate # 同时停用窗口
activate_item_window
@confirm_window.unselect # 清除选择状态
end
# 新增激活技能窗口方法
def activate_item_window
@item_window.activate.refresh # 强制刷新窗口
end
end
#==============================================================================
# ■ Game_Actor
#==============================================================================
class Game_Actor < Game_Battler
#--------------------------------------------------------------------------
# ● オブジェクト初期化(新增初始化方法)
#--------------------------------------------------------------------------
alias _initialize_copy initialize
def initialize(actor_id)
_initialize_copy(actor_id)
@copy_skills ||= [] # 确保副本技能数组初始化
end
#--------------------------------------------------------------------------
# ● スキルを忘れる
#--------------------------------------------------------------------------
#--------------------------------------------------------------------------
# ● スキルを忘れる(修复后的方法)
#--------------------------------------------------------------------------
alias _forget_skill_copy forget_skill
def forget_skill(skill_id)
_forget_skill_copy(skill_id)
@copy_skills.delete(skill_id) if @copy_skills # 增加存在性检查
end
end
#==============================================================================
# ■ Window_Selectable
#==============================================================================
class Window_Selectable < Window_Base
#--------------------------------------------------------------------------
# ● 決定やキャンセルなどのハンドリング処理
#--------------------------------------------------------------------------
def process_handling
return unless open? && active
return process_ok if ok_enabled? && Input.trigger?(:C)
return process_cancel if cancel_enabled? && Input.trigger?(:B)
return process_pagedown if handle?(:pagedown) && Input.trigger?(:R)
return process_pageup if handle?(:pageup) && Input.trigger?(:L)
return process_ctrl if Input.trigger?(:CTRL)
end
#--------------------------------------------------------------------------
# ● CTRL ボタン(CTRL)が押されたときの処理
#--------------------------------------------------------------------------
def process_ctrl
Sound.play_ok
if Time.now - (@last_ctrl_time || Time.at(0)) < 1
Sound.play_ok
Input.update
call_handler(:CTRL)
@last_ctrl_time = nil
else
@last_ctrl_time = Time.now
end
end
end
#==============================================================================
# ■ Window_ItemList
#==============================================================================
class Window_ItemList < Window_Selectable
#--------------------------------------------------------------------------
# ● 決定やキャンセルなどのハンドリング処理
#--------------------------------------------------------------------------
def process_handling
return unless open? && active
return call_handler(:append_ctrl) if handle?(:append_ctrl) && Input.trigger?(:CTRL)
super
end
end
#==============================================================================
# ■ Window_ItemNumber
#==============================================================================
class Window_ItemNumber < Window_ShopNumber
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_reader :number # 入力された個数
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
x = (Graphics.width - window_width) / 2
super(x, 200, line_height * 2 + 32)
@item = nil
@Max = 1
@number = 1
end
#--------------------------------------------------------------------------
# ● アイテム、最大個数の設定
#--------------------------------------------------------------------------
def set(item, max)
@item = item
@max = max
@number = 1
refresh
end
#--------------------------------------------------------------------------
# ● リフレッシュ
#--------------------------------------------------------------------------
def refresh
contents.clear
contents.draw_text(0, 0, 200, line_height, "捨てる数:")
draw_item_name(@item, 4, line_height)
draw_number
end
#--------------------------------------------------------------------------
# ● アイテム名表示行の Y 座標
#--------------------------------------------------------------------------
def item_y
line_height
end
end
#==============================================================================
# ■ Scene_Item
#==============================================================================
class Scene_Item < Scene_ItemBase
#--------------------------------------------------------------------------
# ● 開始処理
#--------------------------------------------------------------------------
alias start_dump start
def start
start_dump
create_item_dump_window
end
#--------------------------------------------------------------------------
# ● アイテムウィンドウの作成
#--------------------------------------------------------------------------
alias create_item_window_dump create_item_window
def create_item_window
create_item_window_dump
@item_window.set_handler(:append_ctrl, method(:on_item_dump))
end
#--------------------------------------------------------------------------
# ● アイテム数選択ウィンドウの作成
#--------------------------------------------------------------------------
def create_item_dump_window
@number_window = Window_ItemNumber.new
@number_window.viewport = @viewport
@number_window.hide
@number_window.set_handler(:ok, method(:on_number_ok))
@number_window.set_handler(:cancel, method(:on_number_cancel))
end
#--------------------------------------------------------------------------
# ● アイテム[捨てる]
#--------------------------------------------------------------------------
def on_item_dump
if item_dumpable?
Sound.play_ok
if Time.now - (@last_ctrl_time || Time.at(0)) < 1
Sound.play_ok
@number_window.set(item, max_item)
@number_window.show.activate
@item_window.deactivate
@last_ctrl_time = nil
else
@last_ctrl_time = Time.now
end
else
Sound.play_buzzer
end
end
#--------------------------------------------------------------------------
# ● 個数入力[決定]
#--------------------------------------------------------------------------
def on_number_ok
Sound.play_ok
do_item_dump(@number_window.number)
@number_window.hide
activate_item_window
end
#--------------------------------------------------------------------------
# ● 個数入力[キャンセル]
#--------------------------------------------------------------------------
def on_number_cancel
Sound.play_cancel
@number_window.hide
activate_item_window
end
#--------------------------------------------------------------------------
# ● 捨てるの実行
#--------------------------------------------------------------------------
def do_item_dump(number)
$game_party.lose_item(item, number)
end
#--------------------------------------------------------------------------
# ● アイテムを捨てる判定
#--------------------------------------------------------------------------
def item_dumpable?
item.is_a?(RPG::Item) ? !item.key_item? : (!item.nil?)
end
#--------------------------------------------------------------------------
# ● 所持数の取得
#--------------------------------------------------------------------------
def max_item
$game_party.item_number(item)
end
end