#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ #_/ #_/ ■ RGSS3 Script WideRangeEvent - イベントの接触範囲を拡大 - #_/---------------------------------------------------------------------------- #_/ 制 作 者 : CanariAlternate #_/ 配 布 元 : カルトの鳥篭 (http://canarialt.blog.fc2.com) #_/---------------------------------------------------------------------------- #_/ □ 概要 : イベントの接触範囲を拡大するスクリプトです。 #_/ #_/ □ 必須 : 「注釈取得スクリプト」 #_/ #_/ □ 位置 : 「経路探索VXAce」より上 #_/ 「注釈取得スクリプト」より下 #_/ 「イベント起動判定拡張」より下 #_/---------------------------------------------------------------------------- #_/ 注意 : 「マルチレイヤーシステム」との併用は不可 #_/ #_/---------------------------------------------------------------------------- #_/ 仕様 : プライオリティ「通常キャラと同じ」とそれ以外で接触範囲の拡大方法が #_/ 異なります。「通常キャラと同じ」は接触範囲のみを拡大しています。 #_/ 対して、それ以外は接触範囲だけでなく当たり判定も拡大しています。 #_/---------------------------------------------------------------------------- #_/ 更新履歴 : 2014/05/28 Ver1.00 スクリプトを作成した。 #_/ : 2014/06/07 Ver1.01 上向き用の図を左向きに変換にする処理を修正した。 #_/ : 2014/06/07 Ver1.02 イベントから接触した場合も起動するように変更した。 #_/ : 2014/06/10 Ver1.03 イベントから接触の判定タイミングを調整した。 #_/ : 2020/06/11 Ver1.04 経路探索との競合を修正した。(pos?の継承問題) #_/ #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ $imported ||= {} $imported[:CanariAlternate_RangeEvent] = true #============================================================================== # ■ CaltRangeEvent #------------------------------------------------------------------------------ #  このスクリプトの設定です。 #============================================================================== module CaltRangeEvent #---------------------------------------------------------------------------- # ▼ 接触範囲の設定取得 # # ◇ 注釈から設定を取得する為の正規表現 EVENT_NOTE = /\[\s*接触範囲\s*\:\s*(.+?)\s*\]/m # 記述した頁に適用(全ての頁より優先して採用) WHOLE_NOTE = /\<\s*接触範囲\s*\:\s*(.+?)\s*\>/m # 全ての頁に適用(1頁目に記述) # # 例1 注釈に記述した頁に適用(全ての頁より優先して採用) # # ◆注釈:[接触範囲: 前方5 ] # # # 例2 全ての頁に適用(1頁目に記述) # # ◆注釈:<接触範囲: 前方4 > # # 例1、例2は予め定義してある接触範囲図の接触範囲が適用されます。 # # # 例3 図を使用して範囲を指定 # # ◆注釈:[接触範囲: # :□□■ # :■★■ # :■□■ # :■□■■ # :■□■ # ◆注釈:■■□■■] # # 例3のように接触範囲図を直接記述することも出来ます。 # #---------------------------------------------------------------------------- # ▼ 接触範囲図の定義 # イベントの位置を基準にして接触範囲を図で定義します。 # 注釈に接触範囲図を直接記述できますが多用する接触範囲はここで定義することを # 推奨します。 # # 各記号の意味 # ■ : 接触する # □ : 接触しない # ★ : 基準(向きに関係なく固定) # ▲ : 基準(向きに合わせて回転。図は上が前。※8方向には非対応) # ※基準となる ★ または ▲ は必ず1つ必要です。 # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ◇ 接触範囲図のハッシュを生成 RANGE_DIAGRAM = {} # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ◇ 接触範囲図 1 RANGE_DIAGRAM["1"] = "□■□ ■★■ □■□" # # ◇ 接触範囲図 2 RANGE_DIAGRAM["2"] = "□□■□□ □■■■□ ■■★■■ □■■■□ □□■□□" # # ◇ 接触範囲図 3 RANGE_DIAGRAM["3"] = "□□□■□□□ □□■■■□□ □■■■■■□ ■■■★■■■ □■■■■■□ □□■■■□□ □□□■□□□" # # ◇ 接触範囲図 4 RANGE_DIAGRAM["4"] = "□□□□■□□□□ □□□■■■□□□ □□■■■■■□□ □■■■■■■■□ ■■■■★■■■■ □■■■■■■■□ □□■■■■■□□ □□□■■■□□□ □□□□■□□□□" # # ◇ 接触範囲図 5 RANGE_DIAGRAM["5"] = "□□□□□■□□□□□ □□□□■■■□□□□ □□□■■■■■□□□ □□■■■■■■■□□ □■■■■■■■■■□ ■■■■■★■■■■■ □■■■■■■■■■□ □□■■■■■■■□□ □□□■■■■■□□□ □□□□■■■□□□□ □□□□□■□□□□□" # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ◇ 接触範囲図 前方4 RANGE_DIAGRAM["前方4"] = "■■■■■■■■■ □■■■■■■■□ □□■■■■■□□ □□□■■■□□□ □□□□▲□□□□" # # ◇ 接触範囲図 前方5 RANGE_DIAGRAM["前方5"] = "■■■■■■■■■■■ □■■■■■■■■■□ □□■■■■■■■□□ □□□■■■■■□□□ □□□□■■■□□□□ □□□□□▲□□□□□" # # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - # ◇ 接触範囲図 全方向を別々に定義 RANGE_DIAGRAM["全方向を別々に定義"] = diagrams = Array.new(10, "★") # 下 diagrams[2] = "□■□ ■★■ □□□" # 左 diagrams[4] = "□■□ ■★□ □□□" # 右 diagrams[6] = "□■□ ■★■ ■□□" # 上 diagrams[8] = "□□□ ■★■ □□□" # #---------------------------------------------------------------------------- end #============================================================================== # ■ CaltRangeEvent #------------------------------------------------------------------------------ #  接触範囲図から情報を抽出して変換する処理を定義しています。 #============================================================================== module CaltRangeEvent #-------------------------------------------------------------------------- # ○ 接触範囲図から情報を抽出 #-------------------------------------------------------------------------- def self.read_diagram(diagram) range_list = [] diagram = diagram.clone # 基準を探索 length = diagram.index(/★|▲/) + 1 last_line = nil oy = -1 diagram[0, length].each_line do |line| last_line = line oy += 1 end ox = last_line.scan(/■|□|★|▲/).size - 1 # 接触範囲図を範囲リストに変換 x = ox y = oy begin case diagram.slice!(0, 1) when "\n" x = ox y -= 1 when "■" range_list.push [x, y] x -= 1 when "□" x -= 1 when "★" fix = true x -= 1 when "▲" fix = false x -= 1 end end until diagram.empty? return range_list, fix end #-------------------------------------------------------------------------- # ○ 接触範囲情報を生成 #-------------------------------------------------------------------------- def self.create_range(diagram) if diagram.kind_of?(String) range_list, fix = read_diagram(diagram) if fix # 向き固定か判定 range_hash = {} range_list.each {|key| range_hash[key] = true } return Array.new(10, range_hash) # ★ は8方向とも同じ接触範囲 else result = Array.new(10, {}) range_hash = {} range_list.each {|key| range_hash[ [-key[0], -key[1]] ] = true } result[2] = range_hash range_hash = {} range_list.each {|key| range_hash[ [key[1], -key[0]] ] = true } result[4] = range_hash range_hash = {} range_list.each {|key| range_hash[ [-key[1], key[0]] ] = true } result[6] = range_hash range_hash = {} range_list.each {|key| range_hash[key] = true } result[8] = range_hash return result # ▲ は8方向には非対応 end else return Array.new(10) do |i| # 全方向を対応する接触範囲図で設定 range_hash = {} read_diagram(diagram[i])[0].each {|key| range_hash[key] = true } next range_hash end end end #-------------------------------------------------------------------------- # ○ 上で定義した接触範囲図を接触範囲情報に変換 #-------------------------------------------------------------------------- RANGE = {} RANGE_DIAGRAM.each {|key, diagram| RANGE[key] = create_range(diagram) } end #============================================================================== # ■ Game_Map #------------------------------------------------------------------------------ #  マップを扱うクラスです。スクロールや通行可能判定などの機能を持っています。 # このクラスのインスタンスは $game_map で参照されます。 #============================================================================== class Game_Map #-------------------------------------------------------------------------- # ○ 公開インスタンス変数 #-------------------------------------------------------------------------- attr_accessor :normal_event_range_mode # 通常キャラの接触判定モード #-------------------------------------------------------------------------- # ● オブジェクト初期化 #-------------------------------------------------------------------------- alias :__RangeEvent__initialize :initialize def initialize __RangeEvent__initialize @normal_event_range_mode = false end end #============================================================================== # ■ Game_Player #------------------------------------------------------------------------------ #  プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの # 機能を持っています。このクラスのインスタンスは $game_player で参照されます。 #============================================================================== class Game_Player < Game_Character #-------------------------------------------------------------------------- # ● 同位置のイベント起動判定 #-------------------------------------------------------------------------- alias :__RangeEvent__check_event_trigger_here :check_event_trigger_here def check_event_trigger_here(triggers) $game_map.normal_event_range_mode = true start_map_event(@x, @y, triggers, true) $game_map.normal_event_range_mode = false __RangeEvent__check_event_trigger_here(triggers) end end #============================================================================== # ■ Game_Event #------------------------------------------------------------------------------ #  イベントを扱うクラスです。条件判定によるイベントページ切り替えや、並列処理 # イベント実行などの機能を持っており、Game_Map クラスの内部で使用されます。 #============================================================================== class Game_Event < Game_Character #-------------------------------------------------------------------------- # ● 非公開メンバ変数の初期化 #-------------------------------------------------------------------------- alias :__RangeEvent__init_private_members :init_private_members def init_private_members __RangeEvent__init_private_members @range_list = nil @last_range_x = nil @last_range_y = nil @last_range_d = nil @last_range_p = nil end #-------------------------------------------------------------------------- # ● 座標一致判定 #-------------------------------------------------------------------------- def pos?(x, y) return in_event_range?(x, y, true) if $game_map.normal_event_range_mode super(x, y) || in_event_range?(x, y, false) end # 経路探索と競合:変更前の親クラスを継承して正しい動作にならない。 # alias :__RangeEvent__pos? :pos? # def pos?(x, y) # return in_event_range?(x, y, true) if $game_map.normal_event_range_mode # __RangeEvent__pos?(x, y) || in_event_range?(x, y, false) # end #-------------------------------------------------------------------------- # ● 停止時の更新 #-------------------------------------------------------------------------- alias :__RangeEvent__update_stop :update_stop def update_stop if !@locked && stopping? && (@last_range_x != @x || @last_range_y != @y || @last_range_d != @direction || @last_range_p != @page) @last_range_x = @x @last_range_y = @y @last_range_d = @direction @last_range_p = @page check_event_trigger_touch_range end __RangeEvent__update_stop end #-------------------------------------------------------------------------- # ○ 接触イベントの拡大した範囲の起動判定 #-------------------------------------------------------------------------- def check_event_trigger_touch_range return false unless @range_list return false unless normal_priority? == true result = false @range_list[@direction].each_key do |xy| x2 = $game_map.round_x(@x - xy[0]) y2 = $game_map.round_y(@y - xy[1]) result = true if check_event_trigger_touch(x2, y2) end return result end #-------------------------------------------------------------------------- # ● イベントページ更新時に注釈から設定を取得 #-------------------------------------------------------------------------- alias :__RangeEvent__setup_note_settings :setup_note_settings def setup_note_settings __RangeEvent__setup_note_settings @range_list = get_range_list end #-------------------------------------------------------------------------- # ○ 接触範囲の取得 #-------------------------------------------------------------------------- def get_range_list result = nil if @page.event_note[CaltRangeEvent::EVENT_NOTE] result = CaltRangeEvent::RANGE[$1] result = CaltRangeEvent.create_range($1) unless result elsif @event.pages[0].event_note[CaltRangeEvent::WHOLE_NOTE] result = CaltRangeEvent::RANGE[$1] result = CaltRangeEvent.create_range($1) unless result end return result end #-------------------------------------------------------------------------- # ○ 接触範囲内か判定 #-------------------------------------------------------------------------- def in_event_range?(x, y, normal) return false unless @range_list return false unless normal_priority? == normal return @range_list[@direction][ [distance_x_from(x), distance_y_from(y)] ] end end #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ #_/ #_/ ▼ 以下、イベント起動判定拡張との競合回避 #_/ #_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/ if $imported[:CanariAlternate_EventEveryone] #============================================================================== # ■ Game_Player #------------------------------------------------------------------------------ #  プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの # 機能を持っています。このクラスのインスタンスは $game_player で参照されます。 #============================================================================== class Game_Player < Game_Character #-------------------------------------------------------------------------- # ● 非公開メンバ変数の初期化 #-------------------------------------------------------------------------- alias :__RangeEvent__init_private_members :init_private_members def init_private_members __RangeEvent__init_private_members @last_range_x = nil @last_range_y = nil @last_range_d = nil end #-------------------------------------------------------------------------- # ● 座標一致判定 #-------------------------------------------------------------------------- def pos?(x, y) return in_event_range?(x, y, true) if $game_map.normal_event_range_mode super(x, y) || in_event_range?(x, y, false) end # 経路探索と競合:変更前の親クラスを継承して正しい動作にならない。 # alias :__RangeEvent__pos? :pos? # def pos?(x, y) # return in_event_range?(x, y, true) if $game_map.normal_event_range_mode # __RangeEvent__pos?(x, y) || in_event_range?(x, y, false) # end #-------------------------------------------------------------------------- # ● 停止時の更新 #-------------------------------------------------------------------------- alias :__RangeEvent__update_stop :update_stop def update_stop if !@locked && stopping? && (@last_range_x != @x || @last_range_y != @y || @last_range_d != @direction) @last_range_x = @x @last_range_y = @y @last_range_d = @direction check_event_trigger_touch_range end __RangeEvent__update_stop end #-------------------------------------------------------------------------- # ○ 接触イベントの拡大した範囲の起動判定 #-------------------------------------------------------------------------- def check_event_trigger_touch_range range_list = get_range_list return false unless range_list return false unless normal_priority? == true result = false range_list[@direction].each_key do |xy| x2 = $game_map.round_x(@x - xy[0]) y2 = $game_map.round_y(@y - xy[1]) result = true if check_event_trigger_touch(x2, y2) end return result end #-------------------------------------------------------------------------- # ○ 接触範囲内か判定 #-------------------------------------------------------------------------- def in_event_range?(x, y, normal) range_list = get_range_list return false unless range_list return false unless normal_priority? == normal return range_list[@direction][ [distance_x_from(x), distance_y_from(y)] ] end #-------------------------------------------------------------------------- # ○ 接触範囲の取得 #-------------------------------------------------------------------------- def get_range_list return nil unless event_list = get_list event_note = Calt.Read_EventNote(event_list) range_list = nil if event_note[CaltRangeEvent::EVENT_NOTE] range_list = CaltRangeEvent::RANGE[$1] range_list = CaltRangeEvent.create_range($1) unless range_list elsif event_note[CaltRangeEvent::WHOLE_NOTE] range_list = CaltRangeEvent::RANGE[$1] range_list = CaltRangeEvent.create_range($1) unless range_list end return range_list end end #============================================================================== # ■ Game_Event #------------------------------------------------------------------------------ #  イベントを扱うクラスです。条件判定によるイベントページ切り替えや、並列処理 # イベント実行などの機能を持っており、Game_Map クラスの内部で使用されます。 #============================================================================== class Game_Event < Game_Character #-------------------------------------------------------------------------- # ● 同位置のイベント起動判定 #-------------------------------------------------------------------------- alias :__RangeEvent__check_event_trigger_here :check_event_trigger_here def check_event_trigger_here(triggers) $game_map.normal_event_range_mode = true start_map_event(@x, @y, triggers, true) $game_map.normal_event_range_mode = false __RangeEvent__check_event_trigger_here(triggers) end end end