#============================================================================== # ★ RGSS3_マウスいじり # tomoaky (http://hikimoki.sakura.ne.jp/) # 移植担当:faida # # 2015/05/01 移植しましたが何か?以下原文 # 2010/04/27 イベント移動機能を追加 # 2010/04/12 機能追加、名称変更(旧名:タイルいじり) # 2009/11/06 公開 # # 機能切り替え用ゲーム変数の値に応じて機能が変化します # 1:左クリックしたセルを一時的に通行不可にする # 2:左クリックしたセルへプレイヤーをジャンプさせる(スクロールマップ不可) # 3:左クリックしたセルにいるイベントのセルフスイッチを反転する # 4:左クリックしたセルにいるイベントを強制的に起動する # 5:マウスのドラッグ&ドロップでイベントを移動させる # これ以外の値を指定すれば機能を無効化できます # # マウス入力のスクリプトはRPGTKOOLXP/RGSS Wikiで # 公開されている物を使わせていただきました。 # http://tkool.web-ghost.net/wiki/wiki.cgi?page=FrontPage #============================================================================== #============================================================================== # ■ 設定項目 #============================================================================== module TMI VAR_FLAG = 3 # 機能切り替えのために使用するゲーム変数ID TARGET_SW = "D" # セルフスイッチいじりで操作する対象 end module Sound def self.play_jump # ジャンプ効果音 Audio.se_play("Audio/SE/Jump1", 80, 100) end 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 @mouse_name = {"MLB"=>0, "MRB"=>1, "MMB"=>2} VK_LBUTTON = 1 VK_RBUTTON = 2 VK_MBUTTON = 4 SM_SWAPBUTTON = 23 @mouse_status = [[0, VK_LBUTTON], [0, VK_RBUTTON], [0, VK_MBUTTON]] # システム状態の検出 gsm = Win32API.new('user32', 'GetSystemMetrics', 'i', 'i') # マウスカーソルの表示切替 ShowCursor = Win32API.new("user32", "ShowCursor", "i", "i") # クラス変数 # マウスボタンの左右の入れ替えの可否 @swapped = gsm.call(SM_SWAPBUTTON) != 0 # キー(ボタン)状態取得 @gaks = Win32API.new('user32', 'GetAsyncKeyState', 'i', 'i') # マウスカーソル座標の取得 @cursor_pos = Win32API.new('user32', 'GetCursorPos', 'p', 'i') # スクリーン座標からクライアント座標へ変換 $scr2cli = Win32API.new('user32', 'ScreenToClient', %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 @cursor_pos.call(pos) != 0 return pos.unpack('ll') # 失敗した場合 else return nil 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 nil 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 != 1 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 nil 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 end #============================================================================== # ■ Game_Map #============================================================================== class Game_Map #-------------------------------------------------------------------------- # ● 公開インスタンス変数 #-------------------------------------------------------------------------- attr_reader :flash_data # マップ画面のフラッシュ状態 #-------------------------------------------------------------------------- # ● セットアップ # map_id : マップ ID #-------------------------------------------------------------------------- alias tstop_game_map_setup setup def setup(map_id) tstop_game_map_setup(map_id) @flash_data = Table.new(width, height) end #-------------------------------------------------------------------------- # ○ フラッシュデータのセット #-------------------------------------------------------------------------- def set_flash(x, y, color) @flash_data[x, y] = color end #-------------------------------------------------------------------------- # ● 通行可能判定 # x : X 座標 # y : Y 座標 # flag : 調べる通行禁止ビット (通常 0x01、乗り物の場合のみ変更) #-------------------------------------------------------------------------- alias tstop_game_map_passable? passable? def passable?(x, y, d) return false if @flash_data[x, y] != 0x000 # フラッシュタイルは通行不可 return tstop_game_map_passable?(x, y, d) end end #============================================================================== # ■ Spriteset_Map #============================================================================== class Spriteset_Map #-------------------------------------------------------------------------- # ● タイルマップの作成 #-------------------------------------------------------------------------- alias tstop_spriteset_map_create_tilemap create_tilemap def create_tilemap tstop_spriteset_map_create_tilemap @tilemap.flash_data = $game_map.flash_data end end #============================================================================== # ■ Scene_Map #============================================================================== class Scene_Map < Scene_Base #-------------------------------------------------------------------------- # ● フレーム更新 #-------------------------------------------------------------------------- alias tstop_scene_map_update update def update Input.mouse_update tstop_scene_map_update unless $game_message.visible # メッセージ表示中以外 if Input.mouse_press?("MLB") mx, my = Input.mouse_pos(true) x = (($game_map.display_x.to_i + (mx / 32))) % $game_map.width y = (($game_map.display_y.to_i + (my / 32))) % $game_map.height @move_target_event.moveto(x, y) if @move_target_event != nil if Input.mouse_trigger?("MLB") case $game_variables[TMI::VAR_FLAG] when 1 # タイルいじり color = $game_map.flash_data[x, y] != 0x000 ? 0x000 : 0xf22 $game_map.set_flash(x, y, color) when 2 # ジャンプいじり(スクロールマップには対応していません) if $game_player.passable?(x, y, $game_player.direction) Sound.play_jump x -= $game_player.x y -= $game_player.y d = x.abs > y.abs ? (x < 0 ? 4 : 6) : (y < 0 ? 8 : 2) $game_player.set_direction(d) $game_player.jump(x, y) else Sound.play_buzzer end when 3 # セルフスイッチいじり for event in $game_map.events_xy(x, y) key = [$game_map.map_id, event.id, TMI::TARGET_SW] $game_self_switches[key] = !$game_self_switches[key] event.refresh end when 4 # イベントいじり for event in $game_map.events_xy(x, y) do event.start end when 5 # イベント移動 @move_target_event = $game_map.events_xy(x, y)[0] end end else @move_target_event = nil end end end end