=begin マウス入力スクリプト HnMouse ver 0.1.0 by半生 http://www.tktkgame.com/ http://www11.atpages.jp/namahanka/ VX用 ver 0.1.0 (2010/08/15) 文章表示と選択肢を同時に表示した時にカーソル位置がずれるバグを修正 ver 0.0.9 (2010/08/01) 戦闘中アイテム・スキル選択中にキーボードでキャンセルした時に落ちるバグを修正 ver 0.0.8 (2010/03/16) マップの端でカーソルの挙動がおかしかった部分を修正 ver 0.0.7 (2010/03/13) 左クリックでイベントを起動出来るように変更 マップ移動時にマウスカーソルを移動距離分ずらすように変更 ver 0.0.6 (2010/02/24) キーボードでカーソルを動かした場合マウスが追従するように ver 0.0.5 (2010/08/18) セーブ画面でもマウスを動かしていない時はカーソルを移動しないように修正 ver 0.0.4 (2010/05/28) マウスを動かしていない時はカーソルを移動しないように変更 ver 0.0.3 (2010/02/22) 一纏めに コメント追加 ver 0.0.2 (2010/02/21) バグ修正 項目のスクロールに対応 ver 0.0.1 公開 参考サイト RPGTKOOLXP/RGSS Wiki Input.mouseスクリプト http://tkool.web-ghost.net/wiki/wiki.cgi?page=FrontPage =end #============================================================================== # ■ module Input.mouse #------------------------------------------------------------------------------ #  マウス入力情報を取得 #============================================================================== =begin key = "MLB" or "MRB" or "MMB" Input.mouse_trigger?(key, ignore_swap = false) Input.mouse_press?(key, ignore_swap = false) Input.mouse_repeat?(key, ignore_swap = false) Input.mouse_pos return x, y =end module Input VK_LBUTTON = 1 VK_RBUTTON = 2 VK_MBUTTON = 4 SM_SWAPBUTTON = 23 @@mouse_name = {"MLB"=>0, "MRB"=>1, "MMB"=>2} @@mouse_status = [[0, VK_LBUTTON], [0, VK_RBUTTON], [0, VK_MBUTTON]] # システム状態の検出 @@gsm = Win32API.new('user32', 'GetSystemMetrics', 'i', 'i') # クラス変数 # マウスボタンの左右の入れ替えの可否 @@swapped = @@gsm.call(SM_SWAPBUTTON) != 0 # キー(ボタン)状態取得 @@gaks = Win32API.new('user32', 'GetAsyncKeyState', 'i', 'i') # マウスカーソル座標の取得 @@get_cursor_pos = Win32API.new('user32', 'GetCursorPos', 'p', 'i') # マウスカーソル座標の設定 @@set_cursor_pos = Win32API.new('user32', 'SetCursorPos', 'i i', 'i') # スクリーン座標からクライアント座標へ変換 @@scr2cli = Win32API.new('user32', 'ScreenToClient', %w(l p), 'i') # クライアント座標からスクリーン座標へ変換 @@cli2scr = Win32API.new('user32', 'ClientToScreen', %w(l p), 'i') #クライアント領域取得 @@client_rect = Win32API.new('user32', 'GetClientRect', %w(l p), 'i') # iniファイル読み込み @@readini = Win32API.new('kernel32', 'GetPrivateProfileStringA', %w(p p p p l p), 'l') # ウィンドウハンドル取得 @@findwindow = Win32API.new('user32', 'FindWindowA', %w(p p), 'l') module_function #-------------------------------------------------------------------------- # ● マウスのスクリーン座標 #-------------------------------------------------------------------------- def mouse_global_pos pos = [0, 0].pack('ll') # 呼び出しに成功した場合 if @@get_cursor_pos.call(pos) != 0 return pos.unpack('ll') # 失敗した場合 else return -1000, -1000 end end #-------------------------------------------------------------------------- # ● マウスのクライアント座標 # catch_anywhere : ウィンドウ外にカーソルがあっても構わず座標を返す #-------------------------------------------------------------------------- def mouse_pos(catch_anywhere = false) # スクリーン上のマウスカーソルの座標をクライアント座標に x, y = screen_to_client(*mouse_global_pos) # クライアント領域の大きさを取得 width, height = client_size # 画面外でも構わない場合か画面内にカーソルがある場合 if catch_anywhere or (x >= 0 and y >= 0 and x < width and y < height) return x, y else return -1000, -1000 end end #---------------------------------------------------------- # ● 更新 #---------------------------------------------------------- def mouse_update for i in @@mouse_status num1 = false num2 = @@gaks.call(i[1]) if num2 != 1 and num2 != 0 num1 = true end if num1 == false if i[0] > 0 i[0] = i[0] * -1 else i[0] = 0 end else if i[0] > 0 i[0] += 1 else i[0] = 1 end end end end #---------------------------------------------------------- # ● キー情報を返す。Inputとおなじ。 # id キーID ignore_swap 入れ替えを許可するかしないか #---------------------------------------------------------- def mouse_press?(value, ignore_swap = false) id = @@mouse_name[value] id = @@mouse_name["MRB"] if value == "MLB" && @@swapped && ignore_swap id = @@mouse_name["MLB"] if value == "MRB" && @@swapped && ignore_swap if @@mouse_status[id][0] > 0 return true else return false end end def mouse_trigger?(value, ignore_swap = false) id = @@mouse_name[value] id = @@mouse_name["MRB"] if value == "MLB" && @@swapped && ignore_swap id = @@mouse_name["MLB"] if value == "MRB" && @@swapped && ignore_swap if @@mouse_status[id][0] == 1 return true else return false end end def mouse_repeat?(value, ignore_swap = false) id = @@mouse_name[value] id = @@mouse_name["MRB"] if value == "MLB" && @@swapped && ignore_swap id = @@mouse_name["MLB"] if value == "MRB" && @@swapped && ignore_swap if @@mouse_status[id][0] <= 0 return false else if @@mouse_status[id][0] % 5 == 1 and @@mouse_status[id][0] % 5 != 2 return true else return false end end end #-------------------------------------------------------------------------- # ● スクリーン座標からクライアント座標へ変換 # x, y : スクリーン座標 #-------------------------------------------------------------------------- def screen_to_client(x, y) # 座標が無効なら失敗 return nil unless x and y pos = [x, y].pack('ll') # 呼び出しに成功した場合 if @@scr2cli.call(hwnd, pos) != 0 return pos.unpack('ll') # 失敗した場合 else return -1,-1 end end #-------------------------------------------------------------------------- # ● スクリーン座標からクライアント座標へ変換 # x, y : スクリーン座標 #-------------------------------------------------------------------------- def client_to_screen(x, y) # 座標が無効なら失敗 return -1,-1 unless x and y pos = [x, y].pack('ll') # 呼び出しに成功した場合 if @@cli2scr.call(hwnd, pos) != 0 return pos.unpack('ll') # 失敗した場合 else return -1,-1 end end #-------------------------------------------------------------------------- # ● ウィンドウハンドル取得 #-------------------------------------------------------------------------- def hwnd # ゲーム名を取得する game_name = "\0" * 256 @@readini.call('Game', 'Title', '', game_name, 255, ".\\Game.ini") game_name.delete!("\0") # ウィンドウハンドルを取得 h = @@findwindow.call('RGSS Player', game_name) if h == 0 h = @@findwindow.call('RGSS Player', nil) end return h end #-------------------------------------------------------------------------- # ● クライアント領域取得 #-------------------------------------------------------------------------- def client_size rect = [0, 0, 0, 0].pack('l4') @@client_rect.call(hwnd, rect) # topとleftは常に0なので省略 right, bottom = rect.unpack('l4')[2..3] return right, bottom end # updateのalias # 既に定義されている時は処理しない class << Input alias :_mouse_original__update :update unless method_defined?(:_mouse_original__update) end def update _mouse_original__update mouse_update $mouse_x_old = $mouse_x unless $mouse_x.nil? $mouse_y_old = $mouse_y unless $mouse_y.nil? $mouse_x ,$mouse_y = Input.mouse_pos end # マウスの位置が移動していた場合 真 def mouse_moved? return true if ($mouse_x_old != $mouse_x) or ($mouse_y_old != $mouse_y) return false end # マウスカーソルを指定した位置に移動 def set_mouse_pos(x, y) sc_x, sc_y = client_to_screen(x, y) @@set_cursor_pos.call(sc_x, sc_y) end end # Window_Selectable用 module HnMouse module Selectable # クリック対象範囲なら真 def inside_window_xy?(m_x, m_y, _x_margine = 0, _y_margine = 0) x_margine = 16 + _x_margine y_margine = 0 + _y_margine offset_x = x_margine + self.x offset_y = y_margine + self.y if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end return !m_x.nil? && !m_y.nil? && m_x > offset_x && m_x < offset_x + self.width - x_margine * 2 && m_y > offset_y && m_y < offset_y + self.height - y_margine * 2 end # クリック位置からindexを取得・変更。範囲外の場合は何もしない def get_index_xy(_x, _y, _x_margine = 0, _y_margine = 0, force = false) return self.index if !force && !(Input.mouse_moved?) x_margine = 16 + _x_margine y_margine = 16 + _y_margine offset_x = x_margine + self.x offset_y = y_margine + self.y if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end m_x = _x - offset_x + self.ox m_y = _y - offset_y + self.oy width = self.width - x_margine * 2 sec_width = width / self.column_max col = m_x / sec_width row = m_y / self.cursor_rect.height index = self.column_max * row + col self.index = index if index >= 0 && index < self.item_max end def fit_mouse_cursor return if Input.mouse_moved? x_margine = 16 y_margine = 16 offset_x = x_margine + self.x offset_y = y_margine + self.y if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end x = offset_x + cursor_rect.x + cursor_rect.width / 2 y = offset_y + cursor_rect.y + cursor_rect.height / 2 Input.set_mouse_pos(x, y) end end end #============================================================================== # ■ Window_Selectable #------------------------------------------------------------------------------ #  カーソルの移動やスクロールの機能を持つウィンドウクラスです。 #============================================================================== class Window_Selectable include HnMouse::Selectable alias :_mouse__update :update unless method_defined?(:_mouse__update) def update last_index = @index _mouse__update fit_mouse_cursor if last_index != @index end end #============================================================================== # ■ Window_ShopNumber #------------------------------------------------------------------------------ #  ショップ画面で、購入または売却するアイテムの個数を入力するウィンドウです。 #============================================================================== # 左クリックで加算・右クリックで減算 # マウス用に決定ボタンを追加しています class Window_ShopNumber def inside_box_xy?(m_x, m_y) x_margine = 16 y_margine = 16 offset_x = x_margine + self.x + 248 offset_y = y_margine + self.y + 96 if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end return !m_x.nil? && !m_y.nil? && m_x > offset_x && m_y > offset_y && m_x < offset_x + 20 && m_y < offset_y + WLH end # 決定ボタンの範囲内なら真 def inside_submit_box?(m_x, m_y) x_margine = 16 y_margine = 16 offset_x = x_margine + self.x + 204 offset_y = y_margine + self.y + 96 + WLH * 4 if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end return !m_x.nil? && !m_y.nil? && m_x > offset_x && m_y > offset_y && m_x < offset_x + 64 && m_y < offset_y + WLH end # クリックした位置の桁 def get_digit_x(m_x) digit = 1 digit = 2 if m_x < 274 return digit end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- # 再定義 def refresh y = 96 self.contents.clear draw_item_name(@item, 0, y) self.contents.font.color = normal_color self.contents.draw_text(212, y, 20, WLH, "×") self.contents.draw_text(248, y, 20, WLH, @number, 2) self.contents.draw_text(204, y + WLH * 4, 64, WLH, "決定", 2) self.cursor_rect.set(244, y, 28, WLH) draw_currency_value(@price * @number, 4, y + WLH * 2, 264) end #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- def update super if self.active last_number = @number mlb_trigger = false mrb_trigger = false if inside_box_xy?($mouse_x, $mouse_y) digit = get_digit_x($mouse_x) mlb_trigger = Input.mouse_trigger?("MLB") mrb_trigger = Input.mouse_trigger?("MRB") end if (Input.repeat?(Input::RIGHT) or (mlb_trigger && digit == 1)) and @number < @max @number += 1 end if (Input.repeat?(Input::LEFT) or (mrb_trigger && digit == 1)) and @number > 1 @number -= 1 end if (Input.repeat?(Input::UP) or (mlb_trigger && digit == 2)) and @number < @max @number = [@number + 10, @max].min end if (Input.repeat?(Input::DOWN) or (mrb_trigger && digit == 2)) and @number > 1 @number = [@number - 10, 1].max end if @number != last_number Sound.play_cursor refresh end end end end #============================================================================== # ■ Window_NameInput #------------------------------------------------------------------------------ #  名前入力画面で、文字を選択するウィンドウです。 #============================================================================== class Window_NameInput def inside_window_xy?(m_x, m_y) x_margine = 16 y_margine = 16 offset_x = x_margine + self.x offset_y = y_margine + self.y if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end return !m_x.nil? && !m_y.nil? && m_y > offset_y && m_y < offset_y + WLH * 9 && (m_x > offset_x && m_x < offset_x + 160 or m_x > offset_x +176 && m_x < offset_x + 336) end def get_index_xy(_x, _y, force = false) return if !force && $mouse_x == $mouse_x_old && $mouse_y == $mouse_y_old x_margine = 16 y_margine = 16 offset_x = x_margine + self.x offset_y = y_margine + self.y if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end m_x = _x - offset_x m_y = _y - offset_y m_x -= 16 if m_x > 176 col = m_x / 32 row = m_y / WLH index = col + row * 10 @index = index if index < 90 end end #============================================================================== # ■ Window_NumberInput #------------------------------------------------------------------------------ #  メッセージウィンドウの内部で使用する、数値入力用のウィンドウです。 #============================================================================== # 左クリックで加算・右クリックで減算 # マウス用に決定ボタンを追加しています class Window_NumberInput #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- # 再定義 def update super if self.active last_index = @index mlb_trigger = false mrb_trigger = false if inside_box_xy?($mouse_x, $mouse_y) get_index_x($mouse_x) mlb_trigger = Input.mouse_trigger?("MLB") mrb_trigger = Input.mouse_trigger?("MRB") elsif inside_submit_box?($mouse_x, $mouse_y) @index = @digits_max end if (Input.repeat?(Input::UP) or Input.repeat?(Input::DOWN) or mlb_trigger or mrb_trigger) && @index < @digits_max Sound.play_cursor place = 10 ** (@digits_max - 1 - @index) n = @number / place % 10 @number -= n * place n = (n + 1) % 10 if Input.repeat?(Input::UP) or mlb_trigger n = (n + 9) % 10 if Input.repeat?(Input::DOWN) or mrb_trigger @number += n * place refresh end if Input.repeat?(Input::RIGHT) cursor_right(Input.trigger?(Input::RIGHT)) end if Input.repeat?(Input::LEFT) cursor_left(Input.trigger?(Input::LEFT)) end if @index != last_index fit_mouse_cursor if !Input.mouse_moved? Sound.play_cursor end update_cursor end end def inside_box_xy?(m_x, m_y) x_margine = 16 y_margine = 16 offset_x = x_margine + self.x + 24 offset_y = y_margine + self.y if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end return !m_x.nil? && !m_y.nil? && m_x > offset_x && m_y > offset_y && m_x < offset_x + 16 * @digits_max && m_y < offset_y + WLH end def inside_submit_box?(m_x, m_y) x_margine = 72 + 16 * @digits_max y_margine = 16 offset_x = x_margine + self.x offset_y = y_margine + self.y if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end return !m_x.nil? && !m_y.nil? && m_x > offset_x && m_y > offset_y && m_x < offset_x + 64 && m_y < offset_y + WLH end def get_index_x(_x) x_margine = 40 offset_x = x_margine + self.x if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox end m_x = _x - offset_x index = m_x / 16 @index = index if index < @digits_max end def fit_mouse_cursor x = self.x + 50 + @index * 16 y = self.y + 36 Input.set_mouse_pos(x,y) end #-------------------------------------------------------------------------- # ● リフレッシュ #-------------------------------------------------------------------------- alias :_mouse__refresh :refresh unless method_defined?(:_mouse__refresh) def refresh _mouse__refresh self.contents.draw_text(56 + @digits_max * 16, 0, 32, WLH, "決定", 1) end #-------------------------------------------------------------------------- # ● カーソルの更新 #-------------------------------------------------------------------------- # 再定義 def update_cursor if @index < @digits_max self.cursor_rect.set(24 + @index * 16, 0, 16, WLH) else self.cursor_rect.set(56 + @digits_max * 16, 0, 32, WLH) end end end #============================================================================== # ■ Window_Message #------------------------------------------------------------------------------ #  文章表示に使うメッセージウィンドウです。 #============================================================================== # 文字送りと選択肢、数値入力関連 class Window_Message #-------------------------------------------------------------------------- # ● 文章送りの入力処理 #-------------------------------------------------------------------------- alias :_mouse__input_pause :input_pause unless method_defined?(:_mouse__input_pause) def input_pause _mouse__input_pause if Input.mouse_trigger?("MLB") self.pause = false if @text != nil and not @text.empty? new_page if @line_count >= MAX_LINE else terminate_message end end end #-------------------------------------------------------------------------- # ● 選択肢の入力処理 #-------------------------------------------------------------------------- alias :_mouse__input_choice :input_choice unless method_defined?(:_mouse__input_choice) def input_choice _mouse__input_choice # キー入力で決定・キャンセルされていたら抜ける return if self.active == false if inside_window_xy?($mouse_x, $mouse_y) get_index_xy($mouse_x, $mouse_y - $game_message.choice_start * WLH) if Input.mouse_moved? if Input.mouse_trigger?("MLB") Sound.play_decision $game_message.choice_proc.call(self.index) terminate_message return end end if Input.mouse_trigger?("MRB") if $game_message.choice_cancel_type > 0 Sound.play_cancel $game_message.choice_proc.call($game_message.choice_cancel_type - 1) terminate_message end return end end #-------------------------------------------------------------------------- # ● 数値入力の処理 #-------------------------------------------------------------------------- # 再定義 def input_number if Input.trigger?(Input::C) or (@number_input_window.inside_submit_box?($mouse_x, $mouse_y) && Input.mouse_trigger?("MLB")) Sound.play_decision $game_variables[$game_message.num_input_variable_id] = @number_input_window.number $game_map.need_refresh = true terminate_message end end end #============================================================================== # ■ Window_SaveFile #------------------------------------------------------------------------------ #  セーブ画面およびロード画面で表示する、セーブファイルのウィンドウです。 #============================================================================== class Window_SaveFile def inside_window_xy?(m_x, m_y, _x_margine = 0, _y_margine = 0) x_margine = 16 + _x_margine y_margine = 16 + _y_margine offset_x = x_margine + self.x offset_y = y_margine + self.y if !self.viewport.nil? offset_x += self.viewport.rect.x - self.viewport.ox offset_y += self.viewport.rect.y - self.viewport.oy end return !m_x.nil? && !m_y.nil? && m_x > offset_x && m_y > offset_y && m_x < offset_x + self.width - x_margine * 2 && m_y < offset_y + self.height - y_margine * 2 end end #============================================================================== # ■ Scene_Title #------------------------------------------------------------------------------ #  タイトル画面の処理を行うクラスです。 #============================================================================== class Scene_Title #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- # 再定義 def update super mlb_trigger = false if @command_window.inside_window_xy?($mouse_x, $mouse_y) @command_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end @command_window.update if Input.trigger?(Input::C) or mlb_trigger case @command_window.index when 0 # ニューゲーム command_new_game when 1 # コンティニュー command_continue when 2 # シャットダウン command_shutdown end end end end #============================================================================== # ■ Scene_Map #------------------------------------------------------------------------------ #  マップ画面の処理を行うクラスです。 #============================================================================== # メニュー呼び出しのみ # 移動関連はGame_Playerで定義しています class Scene_Map #-------------------------------------------------------------------------- # ● キャンセルボタンによるメニュー呼び出し判定 #-------------------------------------------------------------------------- alias :_mouse__update_call_menu :update_call_menu unless method_defined?(:_mouse__update_call_menu) def update_call_menu _mouse__update_call_menu return unless $game_temp.next_scene.nil? if Input.mouse_trigger?("MRB") return if $game_map.interpreter.running? # イベント実行中? return if $game_system.menu_disabled # メニュー禁止中? $game_temp.menu_beep = true # SE 演奏フラグ設定 $game_temp.next_scene = "menu" end end end #============================================================================== # ■ Scene_Menu #------------------------------------------------------------------------------ #  メニュー画面の処理を行うクラスです。 #============================================================================== class Scene_Menu #-------------------------------------------------------------------------- # ● コマンド選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_command_selection mlb_trigger = false if @command_window.inside_window_xy?($mouse_x, $mouse_y) @command_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel $scene = Scene_Map.new elsif Input.trigger?(Input::C) or mlb_trigger if $game_party.members.size == 0 and @command_window.index < 4 Sound.play_buzzer return elsif $game_system.save_disabled and @command_window.index == 4 Sound.play_buzzer return end Sound.play_decision case @command_window.index when 0 # アイテム $scene = Scene_Item.new when 1,2,3 # スキル、装備、ステータス start_actor_selection when 4 # セーブ $scene = Scene_File.new(true, false, false) when 5 # ゲーム終了 $scene = Scene_End.new end end end #-------------------------------------------------------------------------- # ● アクター選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_actor_selection mlb_trigger = false if @status_window.inside_window_xy?($mouse_x, $mouse_y) @status_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel end_actor_selection elsif Input.trigger?(Input::C) or mlb_trigger $game_party.last_actor_index = @status_window.index Sound.play_decision case @command_window.index when 1 # スキル $scene = Scene_Skill.new(@status_window.index) when 2 # 装備 $scene = Scene_Equip.new(@status_window.index) when 3 # ステータス $scene = Scene_Status.new(@status_window.index) end end end end #============================================================================== # ■ Scene_Item #------------------------------------------------------------------------------ #  アイテム画面の処理を行うクラスです。 #============================================================================== class Scene_Item #-------------------------------------------------------------------------- # ● アイテム選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_item_selection mlb_trigger = false if @item_window.inside_window_xy?($mouse_x, $mouse_y) @item_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel return_scene elsif Input.trigger?(Input::C) or mlb_trigger @item = @item_window.item if @item != nil $game_party.last_item_id = @item.id end if $game_party.item_can_use?(@item) Sound.play_decision determine_item else Sound.play_buzzer end end end #-------------------------------------------------------------------------- # ● ターゲット選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_target_selection mlb_trigger = false if @target_window.inside_window_xy?($mouse_x, $mouse_y) @target_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel if $game_party.item_number(@item) == 0 # アイテムを使い切った場合 @item_window.refresh # ウィンドウの内容を再作成 end hide_target_window elsif Input.trigger?(Input::C) or mlb_trigger if not $game_party.item_can_use?(@item) Sound.play_buzzer else determine_target end end end end #============================================================================== # ■ Scene_Skill #------------------------------------------------------------------------------ #  スキル画面の処理を行うクラスです。 #============================================================================== class Scene_Skill #-------------------------------------------------------------------------- # ● スキル選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_skill_selection mlb_trigger = false if @skill_window.inside_window_xy?($mouse_x, $mouse_y) @skill_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel return_scene elsif Input.trigger?(Input::R) Sound.play_cursor next_actor elsif Input.trigger?(Input::L) Sound.play_cursor prev_actor elsif Input.trigger?(Input::C) or mlb_trigger @skill = @skill_window.skill if @skill != nil @actor.last_skill_id = @skill.id end if @actor.skill_can_use?(@skill) Sound.play_decision determine_skill else Sound.play_buzzer end end end #-------------------------------------------------------------------------- # ● ターゲット選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_target_selection mlb_trigger = false if @target_window.inside_window_xy?($mouse_x, $mouse_y) @target_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel hide_target_window elsif Input.trigger?(Input::C) or mlb_trigger if not @actor.skill_can_use?(@skill) Sound.play_buzzer else determine_target end end end end #============================================================================== # ■ Window_Equip #------------------------------------------------------------------------------ #  装備画面で、アクターが現在装備しているアイテムを表示するウィンドウです。 #============================================================================== class Scene_Equip #-------------------------------------------------------------------------- # ● 装備部位選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_equip_selection mlb_trigger = false if @equip_window.inside_window_xy?($mouse_x, $mouse_y) @equip_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel return_scene elsif Input.trigger?(Input::R) Sound.play_cursor next_actor elsif Input.trigger?(Input::L) Sound.play_cursor prev_actor elsif Input.trigger?(Input::C) or mlb_trigger if @actor.fix_equipment Sound.play_buzzer else Sound.play_decision @equip_window.active = false @item_window.active = true @item_window.index = 0 end end end #-------------------------------------------------------------------------- # ● アイテム選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_item_selection mlb_trigger = false if @item_window.inside_window_xy?($mouse_x, $mouse_y) @item_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel @equip_window.active = true @item_window.active = false @item_window.index = -1 elsif Input.trigger?(Input::C) or mlb_trigger Sound.play_equip @actor.change_equip(@equip_window.index, @item_window.item) @equip_window.active = true @item_window.active = false @item_window.index = -1 @equip_window.refresh for item_window in @item_windows item_window.refresh end end end end #============================================================================== # ■ Scene_Status #------------------------------------------------------------------------------ #  ステータス画面の処理を行うクラスです。 #============================================================================== class Scene_Status # 再定義 def update update_menu_background @status_window.update if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel return_scene elsif Input.trigger?(Input::R) Sound.play_cursor next_actor elsif Input.trigger?(Input::L) Sound.play_cursor prev_actor end super end end #============================================================================== # ■ Scene_File #------------------------------------------------------------------------------ #  ファイル画面の処理を行うクラスです。 #============================================================================== class Scene_File #-------------------------------------------------------------------------- # ● セーブファイル選択の更新 #-------------------------------------------------------------------------- alias :_mouse__update_savefile_selection :update_savefile_selection unless method_defined?(:_mouse__update_savefile_selection) def update_savefile_selection last_index = @index mlb_trigger = false if Input.mouse_moved? (0..3).each do |no| if @savefile_windows[no].inside_window_xy?($mouse_x, $mouse_y) @index = no mlb_trigger = Input.mouse_trigger?("MLB") end end if last_index != @index Sound.play_cursor @savefile_windows[last_index].selected = false @savefile_windows[@index].selected = true end end if Input.mouse_trigger?("MLB") mouse_inside = false (0..3).each do |no| if @savefile_windows[no].inside_window_xy?($mouse_x, $mouse_y) mouse_inside = true end end if mouse_inside determine_savefile return end elsif Input.mouse_trigger?("MRB") Sound.play_cancel return_scene return end last_index = @index _mouse__update_savefile_selection # キーボードでカーソル移動した場合マウスカーソルも移動 if last_index != @index x = @savefile_windows[@index].x + @savefile_windows[@index].width / 2 y = @savefile_windows[@index].y + @savefile_windows[@index].height / 2 Input.set_mouse_pos(x, y) end end end #============================================================================== # ■ Scene_End #------------------------------------------------------------------------------ #  ゲーム終了画面の処理を行うクラスです。 #============================================================================== class Scene_End #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- # 再定義 def update super update_menu_background @command_window.update mlb_trigger = false if @command_window.inside_window_xy?($mouse_x, $mouse_y) @command_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel return_scene elsif Input.trigger?(Input::C) or mlb_trigger case @command_window.index when 0 # タイトルへ command_to_title when 1 # シャットダウン command_shutdown when 2 # やめる command_cancel end end end end #============================================================================== # ■ Scene_Shop #------------------------------------------------------------------------------ #  ショップ画面の処理を行うクラスです。 #============================================================================== class Scene_Shop #-------------------------------------------------------------------------- # ● コマンド選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_command_selection mlb_trigger = false if @command_window.inside_window_xy?($mouse_x, $mouse_y) @command_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel $scene = Scene_Map.new elsif Input.trigger?(Input::C) or mlb_trigger case @command_window.index when 0 # 購入する Sound.play_decision @command_window.active = false @dummy_window.visible = false @buy_window.active = true @buy_window.visible = true @buy_window.refresh @status_window.visible = true when 1 # 売却する if $game_temp.shop_purchase_only Sound.play_buzzer else Sound.play_decision @command_window.active = false @dummy_window.visible = false @sell_window.active = true @sell_window.visible = true @sell_window.refresh end when 2 # やめる Sound.play_decision $scene = Scene_Map.new end end end #-------------------------------------------------------------------------- # ● 購入アイテム選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_buy_selection mlb_trigger = false if @buy_window.inside_window_xy?($mouse_x, $mouse_y) @buy_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end @status_window.item = @buy_window.item if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel @command_window.active = true @dummy_window.visible = true @buy_window.active = false @buy_window.visible = false @status_window.visible = false @status_window.item = nil @help_window.set_text("") return end if Input.trigger?(Input::C) or mlb_trigger @item = @buy_window.item number = $game_party.item_number(@item) if @item == nil or @item.price > $game_party.gold or number == 99 Sound.play_buzzer else Sound.play_decision max = @item.price == 0 ? 99 : $game_party.gold / @item.price max = [max, 99 - number].min @buy_window.active = false @buy_window.visible = false @number_window.set(@item, max, @item.price) @number_window.active = true @number_window.visible = true end end end #-------------------------------------------------------------------------- # ● 売却アイテム選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_sell_selection mlb_trigger = false if @sell_window.inside_window_xy?($mouse_x, $mouse_y) @sell_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel @command_window.active = true @dummy_window.visible = true @sell_window.active = false @sell_window.visible = false @status_window.item = nil @help_window.set_text("") elsif Input.trigger?(Input::C) or mlb_trigger @item = @sell_window.item @status_window.item = @item if @item == nil or @item.price == 0 Sound.play_buzzer else Sound.play_decision max = $game_party.item_number(@item) @sell_window.active = false @sell_window.visible = false @number_window.set(@item, max, @item.price / 2) @number_window.active = true @number_window.visible = true @status_window.visible = true end end end #-------------------------------------------------------------------------- # ● 個数入力の更新 #-------------------------------------------------------------------------- # 再定義 def update_number_input submit_trigger = false cansel_trigger = false if @number_window.inside_submit_box?($mouse_x, $mouse_y) submit_trigger = Input.mouse_trigger?("MLB") elsif !@number_window.inside_box_xy?($mouse_x, $mouse_y) cansel_trigger = Input.mouse_trigger?("MRB") end if Input.trigger?(Input::B) or cansel_trigger cancel_number_input elsif Input.trigger?(Input::C) or submit_trigger decide_number_input end end end #============================================================================== # ■ Scene_Name #------------------------------------------------------------------------------ #  名前入力画面の処理を行うクラスです。 #============================================================================== class Scene_Name #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- # 再定義 def update super update_menu_background @edit_window.update @input_window.update mlb_trigger = false if @input_window.inside_window_xy?($mouse_x, $mouse_y) @input_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.repeat?(Input::B) or Input.mouse_trigger?("MRB") if @edit_window.index > 0 # 文字位置が左端ではない Sound.play_cancel @edit_window.back end elsif Input.trigger?(Input::C) or mlb_trigger if @input_window.is_decision # カーソル位置が [決定] の場合 if @edit_window.name == "" # 名前が空の場合 @edit_window.restore_default # デフォルトの名前に戻す if @edit_window.name == "" Sound.play_buzzer else Sound.play_decision end else Sound.play_decision @actor.name = @edit_window.name # アクターの名前を変更 return_scene end elsif @input_window.is_mode_change and mlb_trigger @input_window.cursor_pagedown elsif @input_window.character != "" # 文字が空ではない場合 if @edit_window.index == @edit_window.max_char # 文字位置が右端 Sound.play_buzzer else Sound.play_decision @edit_window.add(@input_window.character) # 文字を追加 end end end end end #============================================================================== # ■ Scene_Battle #------------------------------------------------------------------------------ #  バトル画面の処理を行うクラスです。 #============================================================================== class Scene_Battle #-------------------------------------------------------------------------- # ● パーティコマンド選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_party_command_selection mlb_trigger = false if @party_command_window.inside_window_xy?($mouse_x, $mouse_y, 4) @party_command_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::C) or mlb_trigger case @party_command_window.index when 0 # 戦う Sound.play_decision @status_window.index = @actor_index = -1 next_actor when 1 # 逃げる if $game_troop.can_escape == false Sound.play_buzzer return end Sound.play_decision process_escape end end end #-------------------------------------------------------------------------- # ● アクターコマンド選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_actor_command_selection mlb_trigger = false if @actor_command_window.inside_window_xy?($mouse_x, $mouse_y, 4) @actor_command_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel prior_actor elsif Input.trigger?(Input::C) or mlb_trigger case @actor_command_window.index when 0 # 攻撃 Sound.play_decision @active_battler.action.set_attack start_target_enemy_selection when 1 # スキル Sound.play_decision start_skill_selection when 2 # 防御 Sound.play_decision @active_battler.action.set_guard next_actor when 3 # アイテム Sound.play_decision start_item_selection end end end #-------------------------------------------------------------------------- # ● 対象敵キャラ選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_target_enemy_selection @target_enemy_window.update mlb_trigger = false if @target_enemy_window.inside_window_xy?($mouse_x, $mouse_y, 4) @target_enemy_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel end_target_enemy_selection elsif Input.trigger?(Input::C) or mlb_trigger Sound.play_decision @active_battler.action.target_index = @target_enemy_window.enemy.index end_target_enemy_selection end_skill_selection end_item_selection next_actor end end #-------------------------------------------------------------------------- # ● 対象アクター選択の更新 #-------------------------------------------------------------------------- # 再定義 def update_target_actor_selection @target_actor_window.update mlb_trigger = false if @target_actor_window.inside_window_xy?($mouse_x, $mouse_y, 4) @target_actor_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.trigger?(Input::B) or Input.mouse_trigger?("MRB") Sound.play_cancel end_target_actor_selection elsif Input.trigger?(Input::C) or mlb_trigger Sound.play_decision @active_battler.action.target_index = @target_actor_window.index end_target_actor_selection end_skill_selection end_item_selection next_actor end end #-------------------------------------------------------------------------- # ● スキル選択の更新 #-------------------------------------------------------------------------- alias :_mouse__update_skill_selection :update_skill_selection unless method_defined?(:_mouse__update_skill_selection) def update_skill_selection _mouse__update_skill_selection return if @skill_window.nil? or @skill_window.active != true mlb_trigger = false if @skill_window.inside_window_xy?($mouse_x, $mouse_y, 4) @skill_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.mouse_trigger?("MRB") Sound.play_cancel end_skill_selection elsif mlb_trigger @skill = @skill_window.skill if @skill != nil @active_battler.last_skill_id = @skill.id end if @active_battler.skill_can_use?(@skill) Sound.play_decision determine_skill else Sound.play_buzzer end end end #-------------------------------------------------------------------------- # ● アイテム選択の更新 #-------------------------------------------------------------------------- alias :_mouse__update_item_selection :update_item_selection unless method_defined?(:_mouse__update_item_selection) def update_item_selection _mouse__update_item_selection # 決定・キャンセル済みの場合は抜ける return if @item_window.nil? return if @item_window.active != true mlb_trigger = false if @item_window.inside_window_xy?($mouse_x, $mouse_y, 4) @item_window.get_index_xy($mouse_x, $mouse_y) mlb_trigger = Input.mouse_trigger?("MLB") end if Input.mouse_trigger?("MRB") Sound.play_cancel end_item_selection elsif mlb_trigger @item = @item_window.item if @item != nil $game_party.last_item_id = @item.id end if $game_party.item_can_use?(@item) Sound.play_decision determine_item else Sound.play_buzzer end end end end #============================================================================== # ■ Game_Player #------------------------------------------------------------------------------ #  プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの # 機能を持っています。このクラスのインスタンスは $game_player で参照されます。 #============================================================================== # 左クリックで移動、ホイールクリックで決定、右クリックでメニュー class Game_Player #-------------------------------------------------------------------------- # ● 方向ボタン入力による移動処理 + mouse #-------------------------------------------------------------------------- # 再定義 def move_by_input return unless movable? return if $game_map.interpreter.running? if Input.mouse_press?("MLB") sx = $game_map.adjust_x(self.real_x) + 128 - $mouse_x * 8 sy = $game_map.adjust_y(self.real_y) + 128 - $mouse_y * 8 if sx.abs > 128 or sy.abs > 128 if sx.abs > sy.abs # 横の距離のほうが長い sx > 0 ? move_left : move_right # 左右方向を優先 if @move_failed and sy.abs > 128 sy > 0 ? move_up : move_down end else # 縦の距離のほうが長いか等しい sy > 0 ? move_up : move_down # 上下方向を優先 if @move_failed and sx.abs > 128 sx > 0 ? move_left : move_right end end end end case Input.dir4 when 2; move_down when 4; move_left when 6; move_right when 8; move_up end end #-------------------------------------------------------------------------- # ● 移動中でない場合の処理 # last_moving : 直前に移動中だったか #-------------------------------------------------------------------------- # 再定義 def update_nonmoving(last_moving) return if $game_map.interpreter.running? return if moving? return if check_touch_event if last_moving if not $game_message.visible and Input.trigger?(Input::C) return if get_on_off_vehicle return if check_action_event end if not $game_message.visible and Input.mouse_trigger?("MLB") mdx = ( $mouse_x * 8 - $game_map.adjust_x(self.real_x) ) / 256 mdy = ( $mouse_y * 8 - $game_map.adjust_y(self.real_y) ) / 256 m_distance = mdx**2 + mdy**2 if (m_distance <= 1) return if get_on_off_vehicle if !in_airship? if m_distance < 1 return if check_event_trigger_here([0]) else return if check_event_trigger_there([0,1,2]) end end end end update_encounter if last_moving end # ● スクロール処理 alias :_mouse__update_scroll :update_scroll unless method_defined?(:_mouse__update_scroll) def update_scroll(last_real_x, last_real_y) # 移動前の座標を記憶 mx_before = $game_map.display_x my_before = $game_map.display_y # 元のスクロール処理 _mouse__update_scroll(last_real_x, last_real_y) # プレイヤーの移動中距離分マウスカーソルを移動 if !@move_route_forcing and Input.mouse_press?("MLB") mdx = ($game_map.display_x - mx_before) mdy = ($game_map.display_y - my_before) if mdx != 0 or mdy != 0 new_x = ($mouse_x - mdx / 8) % ($game_map.width * 32) new_y = ($mouse_y - mdy / 8) % ($game_map.height * 32) Input.set_mouse_pos(new_x, new_y) end end end end