sacred-ritual-academy/Scripts/_.28.rb
2025-03-18 19:45:34 -05:00

518 lines
No EOL
21 KiB
Ruby
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
#_/
#_/ ■ 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