| 赞 | 204 |
| VIP | |
| 好人卡 | |
| 积分 | 122 |
| 经验 | |
| 最后登录 | 2025-11-17 |
| 在线时间 | 4435 小时 |
- 梦石
- 0
- 星屑
- 12161
- 在线时间
- 4435 小时
- 注册时间
- 2014-4-11
- 回帖
- 5616

|
加入我们,或者,欢迎回来。
您需要 登录 才可以下载或查看,没有账号?注册会员
×
本帖最后由 yang1zhi 于 2016-1-22 16:19 编辑
NPC名字[pre lang="ruby"]#==============================================================================
# 本脚本来自www.66rpg.com,转载、使用请保留此信息
#==============================================================================
# 作者:柳柳
#
# 使用方法:插入到main前即可,之后就会显示每个事件的名字。
# 不想显示名字的NPC直接把名字设置为一个空格就行了。
#
# 附加功能:名字颜色区分:比如一个NPC的名字是 柳柳,2 就会用2号颜色(红色)显示
#
# 修改NPC名的方法:$game_map.events[事件ID编号].name =
# 比如某个宝箱,原名宝箱,打开后名为“打开的宝箱”,则
# $game_map.events[@event_id].name = "打开的宝箱" 或者
# $game_map.events[2].name = "打开的宝箱" (假设宝箱是2号事件)
#
# 修改颜色定义:70-88行,131-149行,自己随便改。
#
# 给主角带上名字:192行,改 "" 为 "主角" 或者 $game_party.actors[0].name 即可
#
# 是否显示姓名的开关:157行,开头的井号去掉。则以后39号开关打开的时候才会显示姓名
#
#==============================================================================
# ■ Game_Event
#------------------------------------------------------------------------------
# 处理事件的类。条件判断、事件页的切换、并行处理、执行事件功能
# 在 Game_Map 类的内部使用。
#==============================================================================
class Game_Event < Game_Character
#——————————————————————————————————————
# 用来返回名称
#——————————————————————————————————————
def name
return @event.name
end
def name=(newname)
@event.name = newname
end
end
#==============================================================================
# ■ Sprite_Character
#------------------------------------------------------------------------------
# 角色显示用脚本。监视 Game_Character 类的实例、
# 自动变化脚本状态。
#==============================================================================
class Sprite_Character < RPG::Sprite
#--------------------------------------------------------------------------
# ● 定义实例变量
#--------------------------------------------------------------------------
attr_accessor :character # 角色
#--------------------------------------------------------------------------
# ● 初始化对像
# viewport : 查看端口
# character : 角色 (Game_Character)
#--------------------------------------------------------------------------
def initialize(viewport, character = nil)
name = character.name
super(viewport)
@character = character
@namesprite = Sprite.new
@namesprite.bitmap = Bitmap.new(160, 48)
@namesprite.bitmap.font.name = "黑体"
@namesprite.bitmap.font.size = 14
@namesprite.bitmap.font.color.set(255, 0, 0)
@evname = name
@evname_split = name.split(/,/)[0]
if name[0, 2]=="EV"
@evname_split = " "
end
if name.split(/,/)[1] != nil
case name.split(/,/)[1]
when "0"
@namesprite.bitmap.font.color.set(255, 0, 0)
when "1"
@namesprite.bitmap.font.color.set(128, 0, 0)
when "2"
@namesprite.bitmap.font.color.set(255, 0, 0)
when "3"
@namesprite.bitmap.font.color.set(128, 0, 0)
when "4"
@namesprite.bitmap.font.color.set(128, 0, 0)
when "5"
@namesprite.bitmap.font.color.set(255, 0, 0)
when "6"
@namesprite.bitmap.font.color.set(255, 0, 0)
when "7"
@namesprite.bitmap.font.color.set(192, 0, 0)
else
@namesprite.bitmap.font.color.set(255, 0, 0)
end
end
if @evname_split != "" and @evname_split != nil
@namesprite.bitmap.draw_text(0, 0, 160, 36, @evname_split, 1)
end
update
end
#--------------------------------------------------------------------------
# ● 更新画面
#--------------------------------------------------------------------------
def update
super
# 元件 ID、文件名、色相与现在的情况存在差异的情况下
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
# 记忆元件 ID 与文件名、色相
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
# 元件 ID 为有效值的情况下
if @tile_id >= 384
self.bitmap = RPG::Cache.tile($game_map.tileset_name,
@tile_id, @character.character_hue)
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
# 元件 ID 为无效值的情况下
else
self.bitmap = RPG::Cache.character(@character.character_name,
@character.character_hue)
@cw = bitmap.width / 4
@ch = bitmap.height / 4
self.ox = @cw / 2
self.oy = @ch
end
end
if @evname != @character.name
@namesprite.bitmap.clear
@evname = @character.name
@evname_split = @character.name.split(/,/)[0]
if @character.name.split(/,/)[1] != nil
case @character.name.split(/,/)[1]
when "0"
@namesprite.bitmap.font.color.set(255, 0, 0)
when "1"
@namesprite.bitmap.font.color.set(128, 0, 0)
when "2"
@namesprite.bitmap.font.color.set(255, 0, 0)
when "3"
@namesprite.bitmap.font.color.set(128, 0, 0)
when "4"
@namesprite.bitmap.font.color.set(128, 0, 0)
when "5"
@namesprite.bitmap.font.color.set(255, 0, 0)
when "6"
@namesprite.bitmap.font.color.set(255, 0, 0)
when "7"
@namesprite.bitmap.font.color.set(192, 0, 0)
else
@namesprite.bitmap.font.color.set(255, 0, 0)
end
end
if @evname_split != "" and @evname_split != nil
@namesprite.bitmap.draw_text(0, 0, 160, 36, @evname_split, 1)
end
end
@namesprite.x = self.x - 80
@namesprite.y = self.y-self.oy+35-60
#@namesprite.visible = $game_switches[39]
# 设置可视状态
self.visible = (not @character.transparent)
@namesprite.visible = @character.character_name == "" ? false : self.visible
# 图形是角色的情况下
if @tile_id == 0
# 设置传送目标的矩形
sx = @character.pattern * @cw
sy = (@character.direction - 2) / 2 * @ch
self.src_rect.set(sx, sy, @cw, @ch)
end
# 设置脚本的坐标
self.x = @character.screen_x
self.y = @character.screen_y
self.z = @character.screen_z(@ch)
# 设置不透明度、合成方式、茂密
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
# 动画
if @character.animation_id != 0
animation = $data_animations[@character.animation_id]
animation(animation, true)
@character.animation_id = 0
end
end
end
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
# 处理主角的类。事件启动的判定、以及地图的滚动等功能。
# 本类的实例请参考 $game_player。
#==============================================================================
class Game_Player < Game_Character
def name
return ""#$game_party.actors[0].name
end
end
#==============================================================================
# 本脚本来自www.66rpg.com,转载、使用请保留此信息
#==============================================================================[/pre]
NPC大小判断[pre lang="ruby"]# ===========================================================================
# ★ WF-RGSS Scripts ★
# LargeCharacter イベント当たり判定調整スクリプト
# バージョン : rev-4.4 (2013-8-25)
# 作者 : WF-RGSS担当 (WHITE-FLUTE)
# サポート先URI: http://www.whiteflute.org/wfrgss/
# ---------------------------------------------------------------------------
# 機能:
# ・イベントの大きさを感知し、当たり判定を調整します。
# ・ある程度マップの処理を軽量化します。
# ---------------------------------------------------------------------------
# 影響:
# ・軽量化スクリプトと競合します。
# 詳細は readme.txt を参照してください。
# ---------------------------------------------------------------------------
# 設置場所 :Sprite_Character より下、Mainより上
# 必要スクリプト:
# ・共通スクリプト(rev-17以降)、共通実行スクリプト(rev-17以降)
# 注意事項:
# ▽ ほかの軽量化スクリプトとの併用は避けてください。
# ===========================================================================
class Sprite_Character < RPG::Sprite
#------------------------------------------------------------------------
# ● カスタマイズ ポイント
#------------------------------------------------------------------------
# 認知されるキャラクターの大きさを指定します。
LARGE_SET = 24 * 3
LARGE_SIZE = 32 * 2
end
#==============================================================================
# ◆ PassagesList
#------------------------------------------------------------------------------
# キャラクターの位置を判定するリストです
#==============================================================================
class PassagesList
# 継承禁止
include FinalClass
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
@list = Hash.new
end
#--------------------------------------------------------------------------
# ● クリア
#--------------------------------------------------------------------------
def clear
@list.clear
end
#--------------------------------------------------------------------------
# ◆ 位置情報ID
#--------------------------------------------------------------------------
def passages( x , y )
( x << 9 ) + y
end
#--------------------------------------------------------------------------
# ◆ キャラクタ通行不能情報更新
#--------------------------------------------------------------------------
def update( event_id , old_r , new_r , xsize = 1 , ysize = 1)
if xsize > 1 or ysize > 1
xr = xsize / 2
yr = -(ysize - 1)
unless old_r.nil?
for i in -xr..xr
for j in yr..0
outevent( event_id , old_r + i * 512 + j )
end
end
end
unless new_r.nil?
for i in -xr..xr
for j in yr..0
inevent( event_id , new_r + i * 512 + j )
end
end
end
else
unless old_r.nil?
outevent( event_id , old_r )
end
unless new_r.nil?
inevent( event_id , new_r )
end
end
end
#--------------------------------------------------------------------------
# ◆ キャラクタ通行不能情報読み取り イベント用
#--------------------------------------------------------------------------
def passages_event( x , y )
if (val = @list[passages( x , y )])
if val.is_a?(Fixnum)
return $game_map.events[val].passable_event?
else
for event_id in val
event = $game_map.events[event_id]
return false unless event.passable_event?
end
return true
end
else
return true
end
end
#--------------------------------------------------------------------------
# ◆ キャラクタ通行不能情報読み取り プレイヤー用
#--------------------------------------------------------------------------
def passages_player( x , y )
if (val = @list[passages( x , y )])
if val.is_a?(Fixnum)
return $game_map.events[val].passable_player?
else
for event_id in val
event = $game_map.events[event_id]
return false unless event.passable_player?
end
return true
end
else
return true
end
end
#--------------------------------------------------------------------------
# ● イベント存在判定
#--------------------------------------------------------------------------
def include?( x , y )
@list[passages( x , y )]
end
private
#--------------------------------------------------------------------------
# ◆(内部専用)◆ イベント位置代入
#--------------------------------------------------------------------------
def inevent( event_id , r )
val = @list[r]
if val.nil?
@list[r] = event_id
elsif val.is_a?(Fixnum)
@list[r] = [ val , event_id ] if val != event_id
else
@list[r] = val.push( event_id ) unless val.include?( event_id )
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ イベント位置撤去
#--------------------------------------------------------------------------
def outevent( event_id , r )
val = @list[r]
if val.is_a?(Fixnum)
@list.delete(r)
elsif val.is_a?(Array)
val.delete( event_id )
if val.size < 2
@list[r] = val.at(0)
else
@list[r] = val
end
end
end
end
#==============================================================================
# ■ Game_Map
#------------------------------------------------------------------------------
# マップを扱うクラスです。スクロールや通行可能判定などの機能を持っています。
# このクラスのインスタンスは $game_map で参照されます。
#==============================================================================
class Game_Map
# 継承禁止
include FinalClass
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_reader :width_scroll # ◆ スクロール X 座標最大
attr_reader :height_scroll # ◆ スクロール Y 座標最大
attr_reader :onscreen_x # ◆ 画面内判定 X 座標
attr_reader :onscreen_y # ◆ 画面内判定 Y 座標
attr_reader :passages_char
#--------------------------------------------------------------------------
# ● 定数
#--------------------------------------------------------------------------
DISPLAY_X = 1280 # ◆ ディスプレイX
DISPLAY_Y = 960 # ◆ ディスプレイY
TILE_SET_WORK = [ 2 , 1 , 0 ].freeze # ◆ タイルマップレイヤー順序
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias _wfrgss_initialize initialize
def initialize
_wfrgss_initialize
@passages_char = PassagesList.new
@onscreen_x = 0
@onscreen_y = 0
end
#--------------------------------------------------------------------------
# ● セットアップ
# map_id : マップ ID
#--------------------------------------------------------------------------
alias _wfrgss_setup_ setup
def setup(map_id)
@passages_char.clear
_wfrgss_setup_(map_id)
@events[0] = $game_player
@onscreen_x = @display_x + DISPLAY_X # 1280
@onscreen_y = @display_y + DISPLAY_Y # 960
@width_scroll = ( (@map.width - 20) << 7 )
@height_scroll= ( (@map.height - 15) << 7 )
end
#--------------------------------------------------------------------------
# ● 下にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_down(distance)
@display_y += distance
@display_y = @height_scroll if @display_y > @height_scroll
@onscreen_y = @display_y + DISPLAY_Y # 960
end
#--------------------------------------------------------------------------
# ● 左にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_left(distance)
@display_x -= distance
@display_x = 0 if @display_x < 0
@onscreen_x = @display_x + DISPLAY_X # 1280
end
#--------------------------------------------------------------------------
# ● 右にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_right(distance)
@display_x += distance
@display_x = @width_scroll if @display_x > @width_scroll
@onscreen_x = @display_x + DISPLAY_X # 1280
end
#--------------------------------------------------------------------------
# ● 上にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_up(distance)
@display_y -= distance
@display_y = 0 if @display_y < 0
@onscreen_y = @display_y + DISPLAY_Y # 960
end
#--------------------------------------------------------------------------
# ● 任意座標にスクロール
# distance : スクロールする距離
#--------------------------------------------------------------------------
def scroll_any( distance_x , distance_y )
@display_x += distance_x
if @display_x < 0
@display_x = 0
elsif @display_x > @width_scroll
@display_x = @width_scroll
end
@display_y += distance_y
if @display_y < 0
@display_y = 0
elsif @display_y > @height_scroll
@display_y = @height_scroll
end
@onscreen_x = @display_x + DISPLAY_X # 1280
@onscreen_y = @display_y + DISPLAY_Y # 960
end
#--------------------------------------------------------------------------
# ● 任意座標にスクロール
#--------------------------------------------------------------------------
def scroll_fix( display_x , display_y )
@display_x = display_x
if @display_x < 0
@display_x = 0
elsif @display_x > @width_scroll
@display_x = @width_scroll
end
@display_y = display_y
if @display_y < 0
@display_y = 0
elsif @display_y > @height_scroll
@display_y = @height_scroll
end
@onscreen_x = @display_x + DISPLAY_X # 1280
@onscreen_y = @display_y + DISPLAY_Y # 960
end
#--------------------------------------------------------------------------
# ● 通行可能判定
# x : X 座標
# y : Y 座標
# d : 方向 (0,2,4,6,8,10)
# ※ 0,10 = 全方向通行不可の場合を判定 (ジャンプなど)
# self_event : 自分 (イベントが通行判定をする場合)
#--------------------------------------------------------------------------
def passable?( x , y , d , self_event = nil )
return false unless valid?(x, y)
bit = (1 << (( d >> 1 ) - 1)) & 0x0f
if (val = @passages_char.include?( x , y ))
ret = nil
if val.is_a?(Fixnum)
event = @events[val]
if event.tile_id >= 0 and event != self_event
return ret unless (ret = passable_tile?( bit, event)).nil?
end
else
for event_id in val
event = @events[event_id]
if event.tile_id >= 0 and event != self_event
return ret unless (ret = passable_tile?( bit, event)).nil?
end
end
end
end
for i in TILE_SET_WORK
tile_id = @map.data[x, y, i]
return false if tile_id.nil?
if (@terrain_tags[tile_id]).zero?
if (@passages[tile_id] & bit).nonzero?
return false
elsif @passages[tile_id] & 0x0f == 0x0f
return false
end
end
return true if (@priorities[tile_id]).zero?
end
return true
end
#--------------------------------------------------------------------------
# ● 表示 X 座標 * 128
#--------------------------------------------------------------------------
def display_x=(display_x)
if display_x.is_a?(Fixnum)
@display_x = display_x
@onscreen_x = @display_x + DISPLAY_X # 1280
end
end
#--------------------------------------------------------------------------
# ● 表示 Y 座標 * 128
#--------------------------------------------------------------------------
def display_y=(display_y)
if display_y.is_a?(Fixnum)
@display_y = display_y
@onscreen_y = @display_y + DISPLAY_Y # 960
end
end
#--------------------------------------------------------------------------
# ● 指定位置のイベント ID 取得
# x : X 座標
# y : Y 座標
#--------------------------------------------------------------------------
def check_event(x, y)
if ( val = @passages_char.include?( x , y ))
if val.is_a?(Fixnum)
return val
else
return val.at(0)
end
else
return nil
end
end
#--------------------------------------------------------------------------
# ● 指定位置のイベント ID 取得
#--------------------------------------------------------------------------
def check_event_player( x , y )
@passages_char.include?( x , y )
end
private
#--------------------------------------------------------------------------
# ◆(内部専用)◆ 通行可能判定 (タイル)
#--------------------------------------------------------------------------
def passable_tile?( bit , tile )
if (@terrain_tags[tile.tile_id]).zero?
if (@passages[tile.tile_id] & bit).nonzero?
return false
elsif @passages[tile.tile_id] & 0x0f == 0x0f
return false
end
end
return true if (@priorities[tile.tile_id]).zero?
nil
end
end
#==============================================================================
# ■ LargeCharacter
#------------------------------------------------------------------------------
# 当たり判定が巨大なキャラクターを扱うモジュールです。
#==============================================================================
module LargeCharacter
#--------------------------------------------------------------------------
# ◆ 移動情報更新
#--------------------------------------------------------------------------
def move_update
@pre_x = (@x << 7)
@pre_y = (@y << 7)
$game_map.passages_char.update( @id, passages( @old_x, @old_y),
passages( @x, @y),@x_size,@y_size)
end
#--------------------------------------------------------------------------
# ◆ 移動情報更新
#--------------------------------------------------------------------------
def move_update_setup
@pre_x = (@x << 7)
@pre_y = (@y << 7)
$game_map.passages_char.update( @id, nil,passages( @x, @y),@x_size,@y_size)
end
#--------------------------------------------------------------------------
# ◆ 大きさの更新
#--------------------------------------------------------------------------
def size_update( old_x_size , old_y_size )
$game_map.passages_char.update( @id, passages( @x, @y),nil,
old_x_size , old_y_size)
$game_map.passages_char.update( @id, nil,passages( @x, @y),@x_size,@y_size)
end
#--------------------------------------------------------------------------
# ● 通行可能判定
#--------------------------------------------------------------------------
def passable?(x, y, d)
case d
when 2
start_x = x - ( @x_size >> 1 )
end_x = start_x + @x_size
ry = y
for rx in start_x ... end_x
return false unless super( rx , ry , d )
end
when 4
start_y = y - @y_size + 1
end_y = y
rx = x - ( @x_size >> 1 )
for ry in start_y .. end_y
return false unless super( rx , ry , d )
end
when 6
start_y = y - @y_size + 1
end_y = y
rx = x + ( @x_size >> 1 )
for ry in start_y .. end_y
return false unless super( rx , ry , d )
end
when 8
start_x = x - ( @x_size >> 1 )
end_x = start_x + @x_size
ry = y - @y_size + 1
for rx in start_x ... end_x
return false unless super( rx , ry , d )
end
else
start_x = x - ( @x_size >> 1 )
start_y = y - @y_size + 1
end_x = start_x + @x_size
end_y = y
for rx in start_x ... end_x
for ry in start_y .. end_y
return false unless super( rx , ry , d )
end
end
end
return true
end
private
#--------------------------------------------------------------------------
# ◆(内部専用)◆ 接触イベントの起動判定
#--------------------------------------------------------------------------
def check_event_trigger_touch(x, y)
super if self.is_a?(Game_Player)
return false if $game_system.map_interpreter.running?
return false unless @trigger == 2 or @trigger == 1
x_left = x - ( @x_size >> 1 )
x_right = x + ( @x_size >> 1 )
y_up = ( y - @y_size + 1 )
if x_left <= $game_player.x and x_right >= $game_player.x and
y_up <= $game_player.y and y >= $game_player.y
if not jumping? and not over_trigger?
start
return true
end
end
return false
end
end
#==============================================================================
# ■ Game_Character (分割定義 1) (abstract class)
#------------------------------------------------------------------------------
# キャラクターを扱うクラスです。このクラスは Game_Player クラスと Game_Event
# クラスのスーパークラスとして使用されます。
#==============================================================================
class Game_Character
include Abstract
attr_reader :onscreen
#--------------------------------------------------------------------------
# ● 定数
#--------------------------------------------------------------------------
ONSCREEN_X = 1792 # 画面内X領域
ONSCREEN_Y = 1536 # 画面内Y領域
DISPLAY_X = 1280
DISPLAY_Y = 960
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
alias _wfrgss_initialize initialize
def initialize
_wfrgss_initialize
@old_x = @x # 前回の座標
@old_y = @y #
@x_size = 1
@y_size = 1
@pre_x = 0 # 実座標の移動判定に用いる 常に128の整数倍
@pre_y = 0 #
end
#--------------------------------------------------------------------------
# ◆ キャラクタ再更新メソッド
#--------------------------------------------------------------------------
def self.character_method( chrmethod )
__failure_type_call__( chrmethod ) unless chrmethod.is_a?(Method)
@@charchange = chrmethod
end
#--------------------------------------------------------------------------
# ◆ キャラクタ再更新メソッド クリア
#--------------------------------------------------------------------------
def self.clear_character_method
@@charchange = nil
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
sx = @real_x - $game_map.onscreen_x
sy = @real_y - $game_map.onscreen_y
if (@onscreen = (sx.abs <= ONSCREEN_X and sy.abs <= ONSCREEN_Y))
if jumping?
update_jump
elsif moving?
update_move
else
update_stop
end
if @anime_count > 36 - ( @move_speed * 2 )
if not @step_anime and @stop_count > 0
@pattern = @original_pattern
else
@pattern = (@pattern + 1) & 0x3
end
@anime_count = 0
end
else
if jumping?
update_jump
elsif moving?
update_move
else
update_stop
end
end
if @wait_count > 0
@wait_count -= 1
return
end
if @move_route_forcing
move_type_custom
return
end
return if @starting or lock?
return unless @onscreen
if @move_frequency != @reserve_move_frequency
@reserve_move_frequency = @move_frequency
@stop_frequency = (40 - @move_frequency * 2) * (6 - @move_frequency)
end
if @stop_count > @stop_frequency
case @move_type
when 0 # 停止
move_type_stop
when 1 # ランダム
move_type_random
when 2 # 近づく
move_type_toward_player
when 3 # カスタム
move_type_custom
end
end
end
#--------------------------------------------------------------------------
# ● 移動タイプ : 停止
#--------------------------------------------------------------------------
def move_type_stop
@wait_count = rand(36) + 36
end
#--------------------------------------------------------------------------
# ● フレーム更新 (ジャンプ)
#--------------------------------------------------------------------------
def update_jump
@jump_count -= 1
@real_x = (@real_x * @jump_count + @pre_x) / (@jump_count + 1)
@real_y = (@real_y * @jump_count + @pre_y) / (@jump_count + 1)
end
#--------------------------------------------------------------------------
# ● フレーム更新 (移動)
#--------------------------------------------------------------------------
def update_move
distance = (1 << (@move_speed - 1))
if @pre_y > @real_y
@real_y += distance
@real_y = @pre_y if @real_y > @pre_y
elsif @pre_y < @real_y
@real_y -= distance
@real_y = @pre_y if @real_y < @pre_y
end
if @pre_x < @real_x
@real_x -= distance
@real_x = @pre_x if @real_x < @pre_x
elsif @pre_x > @real_x
@real_x += distance
@real_x = @pre_x if @real_x > @pre_x
end
if @walk_anime
@anime_count += 3
elsif @step_anime
@anime_count += 2
end
end
#--------------------------------------------------------------------------
# ● フレーム更新 (停止)
#--------------------------------------------------------------------------
def update_stop
if @step_anime
@anime_count += 2
elsif @pattern != @original_pattern
@anime_count += 3
end
@stop_count += 2 unless @starting or lock?
end
#--------------------------------------------------------------------------
# ◆ 位置情報ID
#--------------------------------------------------------------------------
def passages( x , y )
( x << 9 ) + y
end
#--------------------------------------------------------------------------
# ◆ 移動情報更新
#--------------------------------------------------------------------------
def move_update
@pre_x = (@x << 7)
@pre_y = (@y << 7)
$game_map.passages_char.update( @id, passages( @old_x, @old_y),
passages( @x, @y))
end
#--------------------------------------------------------------------------
# ◆ 移動情報更新
#--------------------------------------------------------------------------
def move_update_setup
@pre_x = (@x << 7)
@pre_y = (@y << 7)
$game_map.passages_char.update( @id, nil, passages( @x, @y))
end
#--------------------------------------------------------------------------
# ● 移動中判定
#--------------------------------------------------------------------------
def moving?
(@real_x != @pre_x or @real_y != @pre_y)
end
#--------------------------------------------------------------------------
# ● 通行可能判定
#--------------------------------------------------------------------------
def passable_event?
@through
end
#--------------------------------------------------------------------------
# ● 通行可能判定
#--------------------------------------------------------------------------
def passable_player?
@through or @character_name.empty?
end
#--------------------------------------------------------------------------
# ● 通行可能判定
# x : X 座標
# y : Y 座標
# d : 方向 (0,2,4,6,8) ※ 0 = 全方向通行不可の場合を判定 (ジャンプ用)
#--------------------------------------------------------------------------
def passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
return false unless $game_map.valid?(new_x, new_y)
return true if @through
return false unless $game_map.passable?( x, y, d, self)
return false unless $game_map.passable?( new_x, new_y, 10 - d)
return false unless character_passable?( new_x , new_y )
true
end
#--------------------------------------------------------------------------
# ● キャラクターの大きさを設定
#--------------------------------------------------------------------------
def size_change( size_x , size_y )
return if size_x == @x_size and size_y == @y_size
if size_x <= 1 and size_y <= 1
if @x_size > 1 or @y_size > 1
old_x_size = @x_size
old_y_size = @y_size
@x_size = 1
@y_size = 1
size_update( old_x_size , old_y_size )
new_character = self.dup
$game_map.events[@id] = new_character
@@charchange.call( @id , new_character )
end
else
unless @x_size > 1 or @y_size > 1
@x_size = size_x
@y_size = size_y
self.extend(LargeCharacter)
size_update( 1 , 1 )
else
old_x_size = @x_size
old_y_size = @y_size
@x_size = size_x
@y_size = size_y
size_update( old_x_size , old_y_size )
end
end
nil
end
#--------------------------------------------------------------------------
# ● 以前の座標を記録
#--------------------------------------------------------------------------
def old_point
@old_x = @x
@old_y = @y
end
#--------------------------------------------------------------------------
# ● 指定位置に移動
# x : X 座標
# y : Y 座標
#--------------------------------------------------------------------------
def moveto(x, y)
old_point
@x = x % $game_map.width
@y = y % $game_map.height
move_update
@real_x = @x << 7
@real_y = @y << 7
@prelock_direction = 0
end
#--------------------------------------------------------------------------
# ● 下に移動
# turn_enabled : その場での向き変更を許可するフラグ
#--------------------------------------------------------------------------
def move_down(turn_enabled = true)
if turn_enabled
turn_down
end
if passable?(@x, @y, 2)
turn_down
old_point
@y += 1
move_update
increase_steps
else
check_event_trigger_touch(@x, @y+1)
end
end
#--------------------------------------------------------------------------
# ● 左に移動
# turn_enabled : その場での向き変更を許可するフラグ
#--------------------------------------------------------------------------
def move_left(turn_enabled = true)
if turn_enabled
turn_left
end
if passable?(@x, @y, 4)
turn_left
old_point
@x -= 1
move_update
increase_steps
else
check_event_trigger_touch(@x-1, @y)
end
end
#--------------------------------------------------------------------------
# ● 右に移動
# turn_enabled : その場での向き変更を許可するフラグ
#--------------------------------------------------------------------------
def move_right(turn_enabled = true)
if turn_enabled
turn_right
end
if passable?(@x, @y, 6)
turn_right
old_point
@x += 1
move_update
increase_steps
else
check_event_trigger_touch(@x+1, @y)
end
end
#--------------------------------------------------------------------------
# ● 上に移動
# turn_enabled : その場での向き変更を許可するフラグ
#--------------------------------------------------------------------------
def move_up(turn_enabled = true)
if turn_enabled
turn_up
end
if passable?(@x, @y, 8)
turn_up
old_point
@y -= 1
move_update
increase_steps
else
check_event_trigger_touch(@x, @y-1)
end
end
#--------------------------------------------------------------------------
# ● 左下に移動
#--------------------------------------------------------------------------
def move_lower_left
unless @direction_fix
@direction = (@direction == 6 ? 4 : @direction == 8 ? 2 : @direction)
end
if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 4)) or
(passable?(@x, @y, 4) and passable?(@x - 1, @y, 2))
old_point
@x -= 1
@y += 1
move_update
increase_steps
end
end
#--------------------------------------------------------------------------
# ● 右下に移動
#--------------------------------------------------------------------------
def move_lower_right
unless @direction_fix
@direction = (@direction == 4 ? 6 : @direction == 8 ? 2 : @direction)
end
if (passable?(@x, @y, 2) and passable?(@x, @y + 1, 6)) or
(passable?(@x, @y, 6) and passable?(@x + 1, @y, 2))
old_point
@x += 1
@y += 1
move_update
increase_steps
end
end
#--------------------------------------------------------------------------
# ● 左上に移動
#--------------------------------------------------------------------------
def move_upper_left
unless @direction_fix
@direction = (@direction == 6 ? 4 : @direction == 2 ? 8 : @direction)
end
if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 4)) or
(passable?(@x, @y, 4) and passable?(@x - 1, @y, 8))
old_point
@x -= 1
@y -= 1
move_update
increase_steps
end
end
#--------------------------------------------------------------------------
# ● 右上に移動
#--------------------------------------------------------------------------
def move_upper_right
unless @direction_fix
@direction = (@direction == 4 ? 6 : @direction == 2 ? 8 : @direction)
end
if (passable?(@x, @y, 8) and passable?(@x, @y - 1, 6)) or
(passable?(@x, @y, 6) and passable?(@x + 1, @y, 8))
old_point
@x += 1
@y -= 1
move_update
increase_steps
end
end
#--------------------------------------------------------------------------
# ● ジャンプ
# x_plus : X 座標加算値
# y_plus : Y 座標加算値
#--------------------------------------------------------------------------
def jump(x_plus, y_plus)
if x_plus != 0 or y_plus != 0
if x_plus.abs > y_plus.abs
x_plus < 0 ? turn_left : turn_right
else
y_plus < 0 ? turn_up : turn_down
end
end
new_x = @x + x_plus
new_y = @y + y_plus
if (x_plus == 0 and y_plus == 0) or passable?(new_x, new_y, 0)
straighten
old_point
@x = new_x
@y = new_y
move_update
distance = Math.sqrt(x_plus * x_plus + y_plus * y_plus).round
@jump_peak = 10 + distance - @move_speed
@jump_count = @jump_peak * 2
@stop_count = 0
end
end
end
#==============================================================================
# ■ Game_Event
#------------------------------------------------------------------------------
# イベントを扱うクラスです。条件判定によるイベントページ切り替えや、並列処理
# イベント実行などの機能を持っており、Game_Map クラスの内部で使用されます。
#==============================================================================
class Game_Event < Game_Character
alias __wfrgss_chr_initialize__ initialize
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# map_id : マップ ID
# event : イベント (RPG::Event)
#--------------------------------------------------------------------------
def initialize(map_id, event)
@event = event
moveto_setup(@event.x, @event.y)
__wfrgss_chr_initialize__(map_id, event)
end
#--------------------------------------------------------------------------
# ◆ キャラクタ通行可能判定
#--------------------------------------------------------------------------
def character_passable?( x , y )
$game_map.passages_char.passages_event( x , y )
end
#--------------------------------------------------------------------------
# ● 指定位置に移動
# x : X 座標
# y : Y 座標
#--------------------------------------------------------------------------
def moveto_setup(x, y)
@x = @old_x = ( x % $game_map.width )
@y = @old_y = ( y % $game_map.height )
move_update_setup
@real_x = (@x << 7)
@real_y = (@y << 7)
@prelock_direction = 0
end
#--------------------------------------------------------------------------
# ● オーバートリガー判定 (同位置を起動条件とするか否か)
#--------------------------------------------------------------------------
def over_trigger?
return false if @character_name != "" and not @through
return false unless $game_map.passable?(@x, @y, 0)
true
end
end
#==============================================================================
# ■ Game_Player
#------------------------------------------------------------------------------
# プレイヤーを扱うクラスです。イベントの起動判定や、マップのスクロールなどの
# 機能を持っています。このクラスのインスタンスは $game_player で参照されます。
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# ● 定数
#--------------------------------------------------------------------------
TRIGGER_DECISION = [0].freeze
TRIGGER_PLAYER = [1,2].freeze
TRIGGER_EVENT = [0,1,2].freeze
#--------------------------------------------------------------------------
# ● 起動トリガー
#--------------------------------------------------------------------------
def trigger
5
end
#--------------------------------------------------------------------------
# ● 起動中判定
#--------------------------------------------------------------------------
def starting
false
end
#--------------------------------------------------------------------------
# ● 通行可能判定
# x : X 座標
# y : Y 座標
# d : 方向 (0,2,4,6,8) ※ 0 = 全方向通行不可の場合を判定 (ジャンプ用)
#--------------------------------------------------------------------------
if $DEBUG
def passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
return false unless $game_map.valid?(new_x, new_y)
return true if Input.press?(Input::CTRL)
super
end
else
def passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
return false unless $game_map.valid?(new_x, new_y)
super
end
end
#--------------------------------------------------------------------------
# ◆ キャラクタ通行可能判定
#--------------------------------------------------------------------------
def character_passable?( x , y )
$game_map.passages_char.passages_player( x , y )
end
#--------------------------------------------------------------------------
# ● 指定位置に移動
# x : X 座標
# y : Y 座標
#--------------------------------------------------------------------------
def moveto_setup(x, y)
@x = x % $game_map.width
@y = y % $game_map.height
move_update_setup
@real_x = (@x << 7)
@real_y = (@y << 7)
@prelock_direction = 0
center(@x, @y)
end
#--------------------------------------------------------------------------
# ● 同位置のイベント起動判定
#--------------------------------------------------------------------------
def check_event_trigger_here(triggers)
return false if $game_system.map_interpreter.running?
if ( val = $game_map.check_event_player( x , y ))
if val.is_a?(Array)
for event_id in val
event = $game_map.events[event_id]
if triggers.include?(event.trigger)
if not event.jumping? and event.over_trigger?
event.start
return true
end
end
end
end
end
return false
end
#--------------------------------------------------------------------------
# ● 正面のイベント起動判定
#--------------------------------------------------------------------------
def check_event_trigger_there(triggers)
return false if $game_system.map_interpreter.running?
new_x = @x + (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y = @y + (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
if ( val = $game_map.check_event_player( new_x , new_y ))
if val.is_a?(Fixnum)
event = $game_map.events[val]
if triggers.include?(event.trigger)
unless event.jumping? or event.over_trigger?
event.start
return true
end
end
else
for event_id in val
event = $game_map.events[event_id]
if triggers.include?(event.trigger)
unless event.jumping? or event.over_trigger?
event.start
return true
end
end
end
end
end
return false unless $game_map.counter?(new_x, new_y)
new_x += (@direction == 6 ? 1 : @direction == 4 ? -1 : 0)
new_y += (@direction == 2 ? 1 : @direction == 8 ? -1 : 0)
if ( val = $game_map.check_event_player( new_x , new_y ))
if val.is_a?(Fixnum)
event = $game_map.events[val]
if TRIGGER_PLAYER.include?(event.trigger)
unless event.jumping? or event.over_trigger?
event.start
return true
end
end
else
for event_id in val
event = $game_map.events[event_id]
if TRIGGER_PLAYER.include?(event.trigger)
unless event.jumping? or event.over_trigger?
event.start
return true
end
end
end
end
end
return false
end
#--------------------------------------------------------------------------
# ● 接触イベントの起動判定
#--------------------------------------------------------------------------
def check_event_trigger_touch(x, y)
return false if $game_system.map_interpreter.running?
if ( val = $game_map.check_event_player( x , y ))
if val.is_a?(Fixnum)
event = $game_map.events[val]
if TRIGGER_PLAYER.include?(event.trigger)
unless event.jumping? or event.over_trigger?
event.start
return true
end
end
else
for event_id in val
event = $game_map.events[event_id]
if TRIGGER_PLAYER.include?(event.trigger)
unless event.jumping? or event.over_trigger?
event.start
return true
end
end
end
end
end
return false
end
end
#==============================================================================
# ■ Spriteset_Map
#------------------------------------------------------------------------------
# マップ画面のスプライトやタイルマップなどをまとめたクラスです。このクラスは
# Scene_Map クラスの内部で使用されます。
#==============================================================================
class Spriteset_Map
#--------------------------------------------------------------------------
# ● オブジェクト初期化
#--------------------------------------------------------------------------
def initialize
@viewport1 = Viewport.new(0, 0, 640, 480)
@viewport2 = Viewport.new(0, 0, 640, 480)
@viewport3 = Viewport.new(0, 0, 640, 480)
@viewport2.z = 200
@viewport3.z = 5000
@tilemap = Tilemap.new(@viewport1)
@tilemap.tileset = RPG::Cache.tileset($game_map.tileset_name)
for i in 0..6
autotile_name = $game_map.autotile_names
@tilemap.autotiles = RPG::Cache.autotile(autotile_name)
end
@tilemap.map_data = $game_map.data
@tilemap.priorities = $game_map.priorities
@panorama = Plane.new(@viewport1)
@panorama.z = -1000
@fog = Plane.new(@viewport1)
@fog.z = 3000
@character_sprites = Hash.new
$game_map.events.each do | i , event |
@character_sprites = Sprite_Character.new(@viewport1, event)
end
Game_Character.character_method( charcter_method )
@weather = RPG::Weather.new(@viewport1)
@picture_sprites = []
for i in 1..50
@picture_sprites.push(Sprite_Picture.new(@viewport2,
$game_screen.pictures))
end
@timer_sprite = Sprite_Timer.new
update
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
@tilemap.tileset.dispose
for i in 0..6
@tilemap.autotiles.dispose
end
@tilemap.dispose
@panorama.dispose
@fog.dispose
unless @character_sprites.nil?
@character_sprites.each_value do | sprite |
sprite.dispose unless sprite.nil?
end
end
@weather.dispose
for sprite in @picture_sprites
sprite.dispose
end
@timer_sprite.dispose
@viewport1.dispose
@viewport2.dispose
@viewport3.dispose
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
if @panorama_name != $game_map.panorama_name or
@panorama_hue != $game_map.panorama_hue
@panorama_name = $game_map.panorama_name
@panorama_hue = $game_map.panorama_hue
if @panorama.bitmap != nil
@panorama.bitmap.dispose
@panorama.bitmap = nil
end
if @panorama_name != ""
@panorama.bitmap = RPG::Cache.panorama(@panorama_name, @panorama_hue)
end
Graphics.frame_reset
end
if @fog_name != $game_map.fog_name or @fog_hue != $game_map.fog_hue
@fog_name = $game_map.fog_name
@fog_hue = $game_map.fog_hue
if @fog.bitmap != nil
@fog.bitmap.dispose
@fog.bitmap = nil
end
if @fog_name != ""
@fog.bitmap = RPG::Cache.fog(@fog_name, @fog_hue)
end
Graphics.frame_reset
end
@tilemap.ox = $game_map.display_x / 4
@tilemap.oy = $game_map.display_y / 4
@tilemap.update
@panorama.ox = $game_map.display_x / 8
@panorama.oy = $game_map.display_y / 8
@fog.zoom_x = $game_map.fog_zoom / 100.0
@fog.zoom_y = $game_map.fog_zoom / 100.0
@fog.opacity = $game_map.fog_opacity
@fog.blend_type = $game_map.fog_blend_type
@fog.ox = $game_map.display_x / 4 + $game_map.fog_ox
@fog.oy = $game_map.display_y / 4 + $game_map.fog_oy
@fog.tone = $game_map.fog_tone
$game_map.events.each do | i , event |
@character_sprites.update if event.onscreen
end
@weather.type = $game_screen.weather_type
@weather.max = $game_screen.weather_max
@weather.ox = $game_map.display_x / 4
@weather.oy = $game_map.display_y / 4
@weather.update
for sprite in @picture_sprites
sprite.update
end
@timer_sprite.update
@viewport1.tone = $game_screen.tone
@viewport1.ox = $game_screen.shake
@viewport3.color = $game_screen.flash_color
@viewport1.update
@viewport3.update
end
#--------------------------------------------------------------------------
# ● キャラクター再代入 メソッド
#--------------------------------------------------------------------------
def charcter_method
self.method(:charcter_change)
end
private
#--------------------------------------------------------------------------
# ◆(内部専用)◆ キャラクター再代入
#--------------------------------------------------------------------------
def charcter_change( character_id , character )
if @character_sprites[character_id]
@character_sprites[character_id].character = character
end
end
end
#==============================================================================
# ■ Sprite_Character
#------------------------------------------------------------------------------
# キャラクター表示用のスプライトです。Game_Character クラスのインスタンスを
# 監視し、スプライトの状態を自動的に変化させます。
#==============================================================================
class Sprite_Character < RPG::Sprite
#--------------------------------------------------------------------------
# ● 公開インスタンス変数
#--------------------------------------------------------------------------
attr_reader :character # キャラクター
#--------------------------------------------------------------------------
# ● オブジェクト初期化
# viewport : ビューポート
# character : キャラクター (Game_Character)
#--------------------------------------------------------------------------
def initialize(viewport, character = nil)
begin
super(viewport)
@character = character
update
rescue Exception
dispose
raise
end
end
#--------------------------------------------------------------------------
# ● 解放
#--------------------------------------------------------------------------
def dispose
unless self.bitmap.nil?
self.bitmap.dispose
self.bitmap = nil
end
super
end
#--------------------------------------------------------------------------
# ● キャラクター代入
#--------------------------------------------------------------------------
def character=(character)
if character.is_a?(Game_Character)
@character = character
end
end
#--------------------------------------------------------------------------
# ● フレーム更新
#--------------------------------------------------------------------------
def update
super
if (self.visible = (not @character.transparent))
if @tile_id != @character.tile_id or
@character_name != @character.character_name or
@character_hue != @character.character_hue
@tile_id = @character.tile_id
@character_name = @character.character_name
@character_hue = @character.character_hue
if @tile_id >= 384
self.bitmap = RPG::Cache.tile( $game_map.tileset_name ,
@tile_id , @character.character_hue )
self.src_rect.set(0, 0, 32, 32)
self.ox = 16
self.oy = 32
@character.size_change( 1, 1)
else
self.bitmap = RPG::Cache.character( @character.character_name ,
@character.character_hue )
@cw = bitmap.width >> 2
@ch = bitmap.height >> 2
self.ox = @cw >> 1
self.oy = @ch
if @cw >= LARGE_SET or @ch >= LARGE_SET
size_x = 1
size_y = 1
until @cw < ( LARGE_SET + LARGE_SIZE * size_x )
size_x += 1
end
until @ch < ( LARGE_SET + LARGE_SIZE * size_y )
size_y += 1
end
@character.size_change((size_x << 1) + 1, size_y + 1)
else
@character.size_change( 1, 1)
end
end
end
if @tile_id.zero?
sx = @character.pattern * @cw
sy = ((@character.direction - 2) >> 1 ) * @ch
self.src_rect.set(sx, sy, @cw, @ch)
end
self.x = @character.screen_x
self.y = @character.screen_y
self.z = @character.screen_z(@ch)
self.opacity = @character.opacity
self.blend_type = @character.blend_type
self.bush_depth = @character.bush_depth
unless @character.animation_id.zero?
animation = $data_animations.at(@character.animation_id)
animation(animation, true)
@character.animation_id = 0
end
end
end
end
[/pre]
base[pre lang="ruby"]# coding: utf-8
# ===========================================================================
# ★ WF-RGSS Scripts ★
# 共通スクリプト(XP/VX/VXAce両対応版)
# バージョン : rev-29 (2013-3-26)
# 作者 : WF-RGSS担当 (WHITE-FLUTE)
# サポート先URI: http://www.whiteflute.org/wfrgss/
# ---------------------------------------------------------------------------
# 機能:
# ・このセクションより後ろのスクリプトでSyntaxError が発生しても
# 別の例外にすりかえられるため、詳細情報が削除されなくなります。
# (VXAceでは標準で削除されなくなりました。)
# ・SyntaxErrorの情報をファイルに書き出します。
# ・不用意なデバッグモードへの遷移を防止します。
# (元からデバッグモードの場合は問題ありません。)
# ・不正なデバッグモードへの遷移を阻害します。
# ・デバッグコンソールを表示しデバッグしやすくします。
# ---------------------------------------------------------------------------
# 影響:
# ・外部コマンド実行など一部の組み込み関数が未定義になります。
# ・例外 SyntaxError は作成できません。(XP/VX)
# (※ ScriptSyntaxError にすりかえられます。)
# ---------------------------------------------------------------------------
# 設置場所:一番最初のセクション(Game_Temp(XP)/モジュール(VX/VXAce)よりも前)
# 必要スクリプト:
# ・共通実行スクリプト(VXAce は、Exit-EXで置き換える事ができます。)
# 注意事項:
# 共通実行スクリプトをMainセクションに上書きして利用することを推奨します。
# ===========================================================================
BEGIN {
module WFRGSS
# -------------------------------------------------------------------------
# ● 調整ポイント
# -------------------------------------------------------------------------
# デバッグモード遷移を阻害するかを設定します。
# 確実に保護できるわけではありませんので過信は禁物です。
DEBUG_CHECK = true
# -------------------------------------------------------------------------
# デバッグモード時、デバッグコンソールを表示します。
# (VXAceでは設定に関わらず標準装備されています。)
DEBUG_CONSOLE = false
# -------------------------------------------------------------------------
# リリースモード時、デバッグメッセージを消去します。
DELETE_DEBUG_MESSAGE = false
# -------------------------------------------------------------------------
# XPのみ。 デバッグフラグをVX/VXAce準拠に修正するか?
# (!)スクリプト対応が必要となります。
DEBUG_FLAG_CHANGE = false
# -------------------------------------------------------------------------
# 調整ポイント終わり
# -------------------------------------------------------------------------
end
# ---------------------------------------------------------------------------
# ● 例外定義
# ---------------------------------------------------------------------------
# 継承例外
class InheritanceError < Exception;end
# Mix-in 例外
class IncludeError < Exception;end
# 仮想クラス、メソッドの使用
class AbstractError < NotImplementedError;end
# ◆ バグ検出
# バグ以外、絶対にありえない状態になったときに発生させてください。
# ※ バグ報告を行うためのものなので途中で破棄してはいけません。
class BugDetected < Exception;end
# ◆ 内部バグ報告用
# これは、WFRGSS でバグしかありえない状態に陥ったときに発生します。
# ※ バグ報告を行うためのものなので途中で破棄してはいけません。
class InternalBugDetected < BugDetected;end
# イベント階層が深すぎる場合
class EventDeepError < SystemStackError;end
# 初期化失敗
class InitializeError < TypeError;end
# アサーション失敗
class AssertionError < Exception;end
# ◆ 例外 Hangup
# ハングアップしたとみなされたときに投げられる例外。
# 深い階層からでは捉えられないことがあるため、注意が必要
# RPGVX/VXAceにはありませんが、XPとの互換性を保つため、設定しています。
class Hangup < Exception;end
# ◆ 例外 Reset
# Graphics.update の呼び出し時にF12が押されていると投げられる例外。(XP)
# F12 が押されていると投げられる例外(VX)
# これがセクション外に出ると
# 最初のセクションから再び実行をやり直そうとします。
# この操作は、組み込みクラスのメソッドにて、
# alias や undef が使われていると
# 不具合の元になります。
class Reset < Exception;end
# セキュリティ違反
class SecurityHazard < Exception;end
# RPGXP互換性のため
if WFRGSS::DEBUG_FLAG_CHANGE
$TEST = $DEBUG
$DEBUG = false
else
$TEST = false unless $TEST
end
module WFRGSS
@@debug = ($TEST or $DEBUG)
def self.check
debug = ($TEST or $DEBUG)
if debug != @@debug or (@@debug and
(FileTest.file?("Game.rgssad") or FileTest.file?("Game.rgss2a") or
FileTest.file?("Game.rgss3a")))
raise(SecurityHazard ,"Insecure - debug flag can't be change.")
end
end
end
# ---------------------------------------------------------------------------
# ◆◆ デバッグモード阻止対策
# ---------------------------------------------------------------------------
# デバッグモード防止策
if defined? untrace_var
undef untrace_var
# デバッグモードでない場合、デバッグモードへの遷移を禁止する
proc = Proc.new {
if $DEBUG
$DEBUG = false
$TEST = false
$BTEST = false
raise(SecurityHazard ,"Insecure - debug flag can't be change.", caller(1))
end
}
trace_var( :$DEBUG , proc )
trace_var( :$-d , proc ) # $DEBUG の別名
proc = nil
# デバッグモードでない場合、デバッグモードへの遷移を禁止する
proc = Proc.new {
if $TEST
$DEBUG = false
$TEST = false
$BTEST = false
raise(SecurityHazard ,"Insecure - debug flag can't be change.", caller(1))
end
}
trace_var( :$TEST , proc ) # RPGVX デバッグフラグ
proc = nil
# 戦闘テストで無い場合、戦闘テストへの遷移を禁止する
proc = Proc.new {
if $BTEST
$DEBUG = false
$TEST = false
$BTEST = false
raise(SecurityHazard ,"Insecure - battle test flag can't be change.",
caller(1))
end
}
trace_var( :$BTEST , proc )
proc = nil
end
unless defined? ScriptSyntaxError
# RGSSでは、本来持っているSyntaxErrorの詳細情報をすべて削除してしまい、
# デバッグが非常に困難になってしまいます。
# そのために用意されている例外です。
# ※特にイベントスクリプト上でSyntaxErrorを出すととても悲惨なことに…
# 「スクリプト実行中に SyntaxError が発生しました。」だけで
# すぐに修正できるのでしょうか?
class ScriptSyntaxError < Exception;end
# -------------------------------------------------------------------------
# ◆ 組み込み例外クラス SyntaxError <obsolete>
# -------------------------------------------------------------------------
# RGSSでは、本来持っているSyntaxErrorの詳細情報をすべて削除してしまうため、
# SyntaxError のコンストラクタを乗っ取って別の例外にすりかえています。
# ※ SyntaxError のインスタンスは作成できません。
class SyntaxError < ScriptError
ERROR = Hash.new
end
class << SyntaxError
#--------------------------------------------------------------------------
# ◆ (!※継承禁止※!)
#--------------------------------------------------------------------------
def SyntaxError.inherited( subclass )
raise( InheritanceError ,
"can't inherit class #{subclass} from #{self}" , caller(1) )
end
private_class_method(:inherited)
unless defined? BasicObject
undef allocate
undef new
#------------------------------------------------------------------------
# ◆ 強制的に別の例外にすりかえる
#------------------------------------------------------------------------
def new( errors , *args )
error_message = make_error_message(errors)
error_message_dump(error_message)
ScriptSyntaxError.new(error_message)
end
else
alias __wfrgss__new__ new unless $!
def new( errors , *args )
error_message = make_error_message(errors)
error_message_dump(error_message)
__wfrgss__new__(errors)
end
end
private
#----------------------------------------------------------------------------
# ◆(内部専用)◆ エラーメッセージ作成
#----------------------------------------------------------------------------
def make_error_message( error_message )
extra = ""
unless (error_message[/^(?:Section)?{?(\d+)}?:(\d+):/]).nil?
nums = $1.to_i # セクションを拾い出した場合
extra = $RGSS_SCRIPTS.at(nums).at(1)
unless $2.nil?
lines = $2.to_i
unless ($RGSS_SCRIPTS.at(nums).at(3)).nil?
details = show_details_source_code( nums , lines )
unless details.empty?
error_message += "\n** script source code:\n#{details}"
else
error_message +=
"\n** script source code:#{lines} unknown data.\n"
end
end
end
end
error_message.gsub!(/^(?:Section)?{?(\d+)}?:/){"( #{extra} ):#{$1}:lines "}
error_message
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ 情報を書きこみ
#--------------------------------------------------------------------------
def error_message_dump(error_message)
e = Zlib::crc32(error_message)
return if SyntaxError::ERROR[e]
SyntaxError::ERROR[e] = true
File.open("syntaxerror.txt","a") do | file |
file.write("*SyntaxError - " +
(Time.now).strftime("%Y-%m-%d %H:%M:%S (%A)") + "\n")
file.write( "#{error_message}\n" )
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ ソースコード位置読み込み
#--------------------------------------------------------------------------
def show_details_source_code( nums , lines )
details = ""
splitstr = ($RGSS_SCRIPTS.at(nums).at(3)).split(/\r\n/)
if lines < 4
ranges = ( 0...( lines + 3 ))
else
ranges = (( lines - 4 )...( lines + 3 ))
end
for i in ranges
unless (splitstr.at(i)).nil?
if i != (lines - 1)
details += "|" + splitstr.at(i) + "\n"
else
details += ">" + splitstr.at(i) + "\n"
end
else
details += "[End of File]\n"
break
end
end
splitstr = nil
rpgvxace? ? details.force_encoding("UTF-8") : details
end
end
# -------------------------------------------------------------------------
# ◆ RGSS 組み込みモジュール Graphics
# -------------------------------------------------------------------------
class << Graphics
#------------------------------------------------------------------------
# ◆ リセットを無視する Graphics.update
#------------------------------------------------------------------------
def Graphics.safe_update
begin
update
rescue Reset
# リセット操作を無視する。
# ただしカーソルアニメーションなどが巻き戻される。
nil
end
end
if WFRGSS::DEBUG_CHECK
#------------------------------------------------------------------------
# ◆ Graphics.update にチェックを加える
#------------------------------------------------------------------------
alias ___original__update___ update
def Graphics.update
WFRGSS.check
___original__update___
end
private(:___original__update___)
end
end
module Graphics
# -----------------------------------------------------------------------
# ◆ クラス変数
# -----------------------------------------------------------------------
@@rate = 0
@@count = 0
# -----------------------------------------------------------------------
# ◆ フレームレートを一時的に変更
# -----------------------------------------------------------------------
def self.frame_workset( frame_rates )
@@rate = Graphics.frame_rate
@@count = Graphics.frame_count
Graphics.frame_rate = frame_rates
end
# -----------------------------------------------------------------------
# ◆ フレームレートを元に戻す
# -----------------------------------------------------------------------
def self.frame_restore
cnt = Graphics.frame_count - @@count
cnt *= @@rate
cnt /= Graphics.frame_rate
Graphics.frame_count = @@count + cnt
Graphics.frame_rate = @@rate
end
# -----------------------------------------------------------------------
# ◆ 解像度横の幅(VX/VXAceでは無視される)
# -----------------------------------------------------------------------
unless defined? Graphics.width
def self.width
640
end
end
# -----------------------------------------------------------------------
# ◆ 解像度縦の幅(VX/VXAceでは無視される)
# -----------------------------------------------------------------------
unless defined? Graphics.height
def self.height
480
end
end
end
end
# ---------------------------------------------------------------------------
# ◆ 組み込みモジュール GC
# ---------------------------------------------------------------------------
module GC
module_function
#--------------------------------------------------------------------------
# ◆ 安全にガーベージコレクションを行う
#--------------------------------------------------------------------------
def update_start
Graphics.safe_update
start
Graphics.safe_update
end
end
}
unless defined? Abstract
# -----------------------------------------------------------------------------
# ◆◆ 組み込みクラス Class
# -----------------------------------------------------------------------------
class Class
# ---------------------------------------------------------------------------
# ◆ クラス変数
# ---------------------------------------------------------------------------
@@_abstract_class = Hash.new
# ---------------------------------------------------------------------------
# ◆ 抽象クラス追加
# ---------------------------------------------------------------------------
def self.abstract_class( klass )
__failure_type_call__( klass ) unless klass.is_a?(Class)
unless @@_abstract_class[klass.__id__]
@@_abstract_class[klass.__id__] = klass
end
end
# ---------------------------------------------------------------------------
# ◆ 抽象クラス判定
# ---------------------------------------------------------------------------
def self.abstract?( klass )
@@_abstract_class[klass.__id__]
end
end
module Abstract
# ---------------------------------------------------------------------------
# ◆ 抽象化
# ---------------------------------------------------------------------------
def self.included( klass )
if klass.include?(FinalClass)
# FinalClass モジュールが既にインクルードされている
raise( IncludeError ,
"can't include #{klass} from #{self}" , caller(1) )
end
Class.abstract_class( klass )
klass.extend(Abstract_Class__)
end
private_class_method(:included)
end
# ---------------------------------------------------------------------------
# ◆ 抽象化 ※ 特異メソッド専用 ※
# ---------------------------------------------------------------------------
module Abstract_Class__
# -------------------------------------------------------------------------
# ◆ ※ 抽象クラス
# -------------------------------------------------------------------------
def allocate
return super unless Class.abstract?( self )
raise( AbstractError ,
"class #{self} cannot use it because of the abstraction class.",
caller(1) )
end
# -------------------------------------------------------------------------
# ◆ ※ 抽象クラス
# -------------------------------------------------------------------------
def new( *args )
return super unless Class.abstract?( self )
raise( AbstractError ,
"class #{self} cannot use it because of the abstraction class.",
caller(1) )
end
# -------------------------------------------------------------------------
# ◆ ※ Mix-in 制限
# -------------------------------------------------------------------------
def self.included( klass )
unless self.is_a?(Class)
raise( IncludeError ,
"can't include #{klass} from #{self}" , caller(1) )
end
end
end
module FinalClass
# ---------------------------------------------------------------------------
# ◆ 継承できないクラス
# ---------------------------------------------------------------------------
def self.included( klass )
if Class.abstract?( klass )
# Abstract モジュールが既にインクルードされている
raise( IncludeError ,
"can't include #{klass} from #{self}" , caller(1) )
end
klass.module_eval(<<-End)
def self.inherited( subclass )
raise( InheritanceError ,
sprintf(\"can't inherit class %s from %s\",subclass.inspect,
self.inspect ) , caller(1) )
end
private_class_method(:inherited)
End
end
private_class_method(:included)
end
# ---------------------------------------------------------------------------
# ◆ 組み込みモジュール Kernel
# ---------------------------------------------------------------------------
module Kernel
# ---------------------------------------------------------------------------
# ◆ 危険な関数を未定義に設定
# ---------------------------------------------------------------------------
# 外部コマンド読み込みなど危険な操作は明示的に禁止にします。
# ※ これらのコマンドの必要性が(通常は)ないうえ、
# 危険(システム破壊をもたらすことがある)なため取り外しています。
# ※ もし、これらを使用する場合は、効果と危険性を考慮してください。
# ---------------------------------------------------------------------------
# 外部コマンドを実行する。
undef ` #` # 外部コマンドを実行する。
undef exec # 外部コマンドを実行する 制御を返さない。
undef fork # サブシェルを生成する。
undef system # 外部コマンドを実行する。
undef abort # 後処理を行わずに強制終了する。後処理が必要な時に困る。
undef exit! # abort と同じ。
undef open # コマンドが実行できる。(ファイルを開くならIO.openを用いる)
#--------------------------------------------------------------------------
private
#--------------------------------------------------------------------------
# ◆ RPGVX/VXAce かどうか
#--------------------------------------------------------------------------
def rpgvx?
defined? Graphics.resize_screen
end
#--------------------------------------------------------------------------
# ◆ RPGVXAce かどうか
#--------------------------------------------------------------------------
def rpgvxace?
defined? BasicObject
end
#--------------------------------------------------------------------------
# ◆ RGSSのバージョン
#--------------------------------------------------------------------------
def rgss_version
rpgvx? ? (rpgvxace? ? 3 : 2 ) : 1
end
#--------------------------------------------------------------------------
# ◆ テストモードかどうか
#--------------------------------------------------------------------------
def debug?
$DEBUG or $TEST
end
#--------------------------------------------------------------------------
# ◆ デバッグコンソール
#--------------------------------------------------------------------------
if WFRGSS::DEBUG_CONSOLE and debug? and (not rpgvxace?)
unless $@
$VERBOSE = true
alias wfrgss_p p
Win32API.new("kernel32","AllocConsole",'v','l').call
$stdout.reopen("conout$","w")
def p(*a)
a.each{|v|$stdout.puts(String.utf82ansi(v.inspect))}
end
end
elsif WFRGSS::DELETE_DEBUG_MESSAGE
unless $@
alias display_p p
def p(*a)
# 何も出力しない
end
end
end
#--------------------------------------------------------------------------
# ◆ 例外セット
# 例外を発生させます。
#--------------------------------------------------------------------------
# ◆ method_missing と同様
#--------------------------------------------------------------------------
def __failure_method_call__( method_name , *args )
raise( NoMethodError ,
"undefined method `#{method_name}' for #{self}" , caller(2) )
end
#--------------------------------------------------------------------------
# ◆ オーバーライドが必要
#--------------------------------------------------------------------------
def __override_required_call__( method_name , *args )
raise( AbstractError ,
"It is necessary to do override to use method `#{method_name}'" +
" of this class #{self}. " +
"(or, it tried to call the method of a super-class.)" , caller(2))
end
#--------------------------------------------------------------------------
# ◆ 例外 TypeErrorを発生させる
#--------------------------------------------------------------------------
def __failure_type_call__( object_type )
e = ( object_type.class ).to_s
raise( TypeError , "no implicit conversion from #{e}" , caller(2) )
end
#--------------------------------------------------------------------------
# ◆ 例外 RangeErrorを発生させる ( num が Numeric でない場合はBugDetected )
#--------------------------------------------------------------------------
def __outof_range_call__( num , str , call_value = 2 )
if num.is_a?(Numeric)
if str.is_a?(String)
raise( RangeError , "#{num} out of range of #{str}",caller(call_value))
else
e = ( str.class ).to_s
raise(TypeError,"no implicit conversion from #{e}",caller(call_value))
end
else
e = ( num.class ).to_s
raise( BugDetected, "[BUG] no implicit conversion from #{e} (TypeError)",
caller(1))
end
end
#--------------------------------------------------------------------------
# ◆ 例外 ArgumentErrorを発生させる ( str が String でない場合はBugDetected )
#--------------------------------------------------------------------------
def __invalid_value_call__( str , value , call_value = 2 )
if str.is_a?(String)
raise( ArgumentError , "invalid #{str} for #{value.to_s}")
else
e = ( str.class ).to_s
raise( BugDetected, "[BUG] no implicit conversion from #{e} (TypeError)",
caller(1))
end
end
#--------------------------------------------------------------------------
# ◆ 例外 SecurityErrorを発生させる ( str が String でない場合はBugDetected )
#--------------------------------------------------------------------------
def __insecure_call__( str )
if str.is_a?(String)
raise( SecurityError , "Insecure operation - #{str}" , caller(2) )
else
e = ( str.class ).to_s
raise( BugDetected, "[BUG] no implicit conversion from #{e} (TypeError)",
caller(1))
end
end
#--------------------------------------------------------------------------
# ◆ バグを報告する。 ( str が String でない場合も BugDetected )
#--------------------------------------------------------------------------
def __report_bug( str )
if str.is_a?(String)
raise( BugDetected , str , caller(1))
else
e = ( str.class ).to_s
raise( BugDetected ,
"[BUG] no implicit conversion from #{e} (TypeError)" , caller(1) )
end
end
#--------------------------------------------------------------------------
# ◆ バグを報告する。(異常な値を検出)
#--------------------------------------------------------------------------
def __report_bug_invalid_value( value )
raise( BugDetected , "[BUG] invalid value for #{value}", caller(1))
end
#--------------------------------------------------------------------------
# ◆※!※◆ WF-RGSS の バグを報告する。
# ※ このメソッドは WF-RGSS 内部バグを報告するためのものです。
# ※ カスタマイズ時にバグを報告したい場合は、
# __report_bug( str ) を使用してください。
#--------------------------------------------------------------------------
def __report_internal_bug( str )
if str.is_a?(String)
raise( InternalBugDetected , str , caller(1))
else
e = ( str.class ).to_s
raise( InternalBugDetected ,
"[BUG] no implicit conversion from #{e} (TypeError)" , caller(1) )
end
end
#--------------------------------------------------------------------------
# ◆ チェック関連メソッド
# 型や範囲をチェックします。
#--------------------------------------------------------------------------
# ◆ 型が合わない場合、例外 TypeErrorを発生させる
# (※ klass が異常な場合はBugDetected )
#--------------------------------------------------------------------------
def _type_check_( object_type , klass , call_value = 2 )
begin
return if object_type.is_a?(klass)
e = ( object_type.class ).to_s
raise( TypeError,"no implicit conversion from #{e}")
rescue TypeError => errobj
# 例外の報告位置をすりかえる
if errobj.message[/^no/].nil?
raise( BugDetected , "[BUG] #{errobj.message} (TypeError)",caller(1))
else
raise( TypeError , errobj.message , caller(call_value))
end
end
end
#--------------------------------------------------------------------------
# ◆ Fixnum の範囲を検証する ※範囲が異常なら例外を発生させる
#--------------------------------------------------------------------------
def _fixnum_range_check( value , minimum , maximum )
__failure_type_call__( value , 3 ) unless value.is_a?(Fixnum)
unless value >= minimum and value <= maximum
# 範囲外のため、例外を発生させる
call_ary = caller(1)
if call_ary.size > 0
sections = call_ary.at(0)
str = sections + " ( range #{minimum} .. #{maximum} )"
else
str = "caller method (unknown) ( range #{minimum} .. #{maximum} )"
end
__outof_range_call__( value , str , 3 )
end
end
#--------------------------------------------------------------------------
# ◆ Integer の範囲にまとめる (※処理速度が求められる箇所では用いない)
# ※異常範囲が認められていない場合は、↑のメソッドを用いること
#--------------------------------------------------------------------------
def _integer_range_value( value , minimum , maximum )
__failure_type_call__( value , 3 ) unless value.is_a?(Integer)
if value < minimum
return minimum
elsif value > maximum
return maximum
else
return value
end
end
# ---------------------------------------------------------------------------
# 可視性を変更
public
# これ以降はモジュール関数として定義
module_function
# ---------------------------------------------------------------------------
# ◆ 真 を検証
# ---------------------------------------------------------------------------
def assert_if( value )
unless value
raise(AssertionError,"Assertion Failed (false for true)",caller(1))
end
end
# ---------------------------------------------------------------------------
# ◆ 偽 を検証
# ---------------------------------------------------------------------------
def assert_unless( value )
if value
raise(AssertionError,"Assertion Failed (true for false)",caller(1))
end
end
end
# ---------------------------------------------------------------------------
# ◆ 組み込みクラス Object
# ---------------------------------------------------------------------------
class Object
# 可視性を変更
private
#--------------------------------------------------------------------------
# ◆ Mix-in禁止を実装
#--------------------------------------------------------------------------
def self.__cannot_mixin( klass )
raise( IncludeError ,
"can't include #{klass} from #{self}" , caller(2) )
end
#--------------------------------------------------------------------------
# ◆ 継承禁止を実装
#--------------------------------------------------------------------------
def self.__cannot_inherited( subclass )
raise( InheritanceError ,
"can't inherit class #{subclass} from #{self}" , caller(2) )
end
#--------------------------------------------------------------------------
# ◆ 抽象クラス (かならず継承が必要となる)
#--------------------------------------------------------------------------
def __abstract_class( target )
klass = self.class
unless target.is_a?(Class) or target.is_a?(Module)
__report_bug("[BUG] class or modules required (TypeError)")
end
until ( klass = klass.superclass ) == Object
return if klass == target
end
raise( AbstractError ,
"class #{target} cannot use it because of the abstraction class.",
caller(2) )
end
end
# ---------------------------------------------------------------------------
# ◆ 組み込みクラス String
# ---------------------------------------------------------------------------
class String
# ---------------------------------------------------------------------------
# ◆ 定数
# ---------------------------------------------------------------------------
CP_ACP = 0 # ANSI コード
CP_UTF7 = 65000 # UTF-7 コード
CP_UTF8 = 65001 # UTF-8 コード
EMPTY_STR = "".freeze
#--------------------------------------------------------------------------
# ◆ クラス変数
#--------------------------------------------------------------------------
@@rm = Win32API.new('kernel32','RtlZeroMemory',%w(p l),'l').freeze
# 文字列をワイド文字列(Unicode)にマップするAPI
@@mb2wc = Win32API.new('kernel32',
'MultiByteToWideChar', %w(i l p i p i), 'l').freeze
# ワイド文字列を新しい文字列にマップするAPI
@@wc2mb = Win32API.new('kernel32',
'WideCharToMultiByte', %w(i l p i p i p p), 'l').freeze
#--------------------------------------------------------------------------
# ◆ クリア
#--------------------------------------------------------------------------
unless rpgvxace?
def clear
@@rm.call( self , self.size )
self.replace("")
end
end
#--------------------------------------------------------------------------
# ◆ エンコード
#--------------------------------------------------------------------------
def encode_by_
for i in 0...self.size
self = 256 - self
end
end
#--------------------------------------------------------------------------
# ◆ UTF-8 → ANSI 変換
#--------------------------------------------------------------------------
unless rpgvxace?
def self.utf82ansi( str )
to_multibyte( to_widechar( str , CP_UTF8 ) , CP_ACP )
end
else
def self.utf82ansi( str )
to_multibyte(to_widechar(str,CP_UTF8),CP_ACP).force_encoding("ASCII-8BIT")
end
end
#--------------------------------------------------------------------------
# ◆ ANSI → UTF-8 変換
#--------------------------------------------------------------------------
unless rpgvxace?
def self.ansi2utf8( str )
to_multibyte( to_widechar( str , CP_ACP ) , CP_UTF8 )
end
else
def self.ansi2utf8( str )
to_multibyte(to_widechar(str,CP_ACP),CP_UTF8).force_encoding("UTF-8")
end
end
private # 可視性を private に変更
#--------------------------------------------------------------------------
# ◆(内部専用)◆ ワイド文字列( Unicode ) へ変換
#--------------------------------------------------------------------------
def self.to_widechar( str , codepage )
length = @@mb2wc.call( codepage , 0 , str , -1 , nil , 0 )
unless length.zero?
buffer = "\x00" * ( length << 1 )
unless (@@mb2wc.call( codepage ,0,str,-1,buffer,length)).zero?
return buffer
else
return ""
end
else
return ""
end
end
private_class_method(:to_widechar)
#--------------------------------------------------------------------------
# ◆(内部専用)◆ ワイド文字列( Unicode ) から 文字列を取得する
#--------------------------------------------------------------------------
def self.to_multibyte( str , codepage )
length = @@wc2mb.call( codepage , 0 , str , -1 , nil , 0 , nil , nil )
unless length.zero?
buffer = "\x00" * length
unless (@@wc2mb.call(codepage,0,str,-1,buffer,buffer.size,nil,nil)).zero?
return buffer
else
return ""
end
else
return ""
end
end
private_class_method(:to_multibyte)
end
# ---------------------------------------------------------------------------
# ◆ モジュール ErrorLogWriter
# ---------------------------------------------------------------------------
module ErrorLogWriter
#--------------------------------------------------------------------------
# ◆(内部専用)◆ Mix-in 禁止
#--------------------------------------------------------------------------
def self.included( klass )
__cannot_mixin( klass )
end
private_class_method(:included)
ERROR_SECTION_NUM = (/^(?:Section)?{?(\d+)}?:/).freeze
ERROR_SECTION = (/^(?:Section)?{?\d+}?:/).freeze
DOUBLE_CRLF = (/\n\n/).freeze
# -------------------------------------------------------------------------
# ◆ エラー情報を記録 ( DEBUG のみ )
# -------------------------------------------------------------------------
def self.write( errobj )
return unless debug?
begin
begin
Graphics.safe_update
rescue SecurityHazard
end
sleep(0.1)
File.open("errors.txt","a") do | file |
file.write("*Error - " +
(Time.now).strftime("%Y-%m-%d %H:%M:%S (%A)") + "\n")
file.write( "Exception : #{errobj.class}\n" )
file.write( errobj.message )
unless $@.nil? and $@.empty?
backtrace = ""
for str in $@.dup
unless (str[ERROR_SECTION_NUM]).nil?
extra = $RGSS_SCRIPTS.at($1.to_i).at(1)
str.gsub!(ERROR_SECTION) { "( " + extra + " ):" }
end
backtrace += str
end
file.write( "\ntrace:\n" + $@.inspect + "\n" )
end
end
rescue Exception => errs
raise( errs ,
errs.message + "\n (" + (errobj.class).to_s + " )\n" + errobj.message )
end
end
end
end
module MessageBox
#----------------------------------------------------------------------------
# ◆(内部専用)◆ Mix-in 禁止
#----------------------------------------------------------------------------
def self.included( klass )
raise( IncludeError , "can't include #{klass} from #{self}" , caller(1) )
end
private_class_method(:included)
# ---------------------------------------------------------------------------
# ◆ 定数
# ---------------------------------------------------------------------------
MB_OK = 0x0 #
MB_OKCANCEL = 0x1 #
MB_ABORTRETRYIGNORE = 0x2 #
MB_YESNOCANCEL = 0x3 #
MB_YESNO = 0x4 #
MB_RETRYCANCEL = 0x5 #
MB_ICONERROR = 0x10 # エラー
MB_ICONQUESTION = 0x20 # 問い合わせ
MB_ICONWARNING = 0x30 # 警告
MB_ICONINFORMATION = 0x40 # 情報
MB_SYSTEMMODAL = 0x1000 # システムモーダル
MB_TASKMODAL = 0x2000 # タスクモーダル
MB_TOPMOST = 0x040000 # 最前面
MB_FATAL = 0x042010 # 致命的エラー用
MB_WARN = 0x042030 # 警告
IDOK = 1
IDCANCEL = 2
IDABORT = 3
IDRETRY = 4
IDIGNORE = 5
IDYES = 6
IDNO = 7
# ---------------------------------------------------------------------------
# ◆ 内部使用定数
# ---------------------------------------------------------------------------
ERROR_SECTION_NUM = (/^(?:Section)?{?(\d+)}?:/).freeze
ERROR_SECTION = (/^(?:Section)?{?\d+}?:/).freeze
DOUBLE_CRLF = (/\n\n/).freeze
begin
# メッセージボックス
@@mb = Win32API.new('user32', 'MessageBoxA', %w(p p p i), 'i').freeze
rescue Exception
# 取得失敗
Script_Deleter.finalizer
raise( LoadError , "cannot read modules.(user32.dll)",caller(0))
end
begin
# ini ファイルから、セクションのキーを取得するAPI
@@gpps = Win32API.new('kernel32',
'GetPrivateProfileStringA',%w(p p p p l p),'l').freeze
rescue Exception
# 取得失敗
Script_Deleter.finalizer
raise( LoadError , "cannot read modules.(kernel32.dll)",caller(0))
end
#--------------------------------------------------------------------------
# ◆(!要注意メソッド!)◆ メッセージボックスを表示
# ※警告 :例外 Hangup 対策をかならず行うこと!
#--------------------------------------------------------------------------
def self.messagebox( message , title , type )
begin
# 停止対策用
begin
Graphics.safe_update
rescue SecurityHazard
end
@@mb.call(0, String.utf82ansi( message ), String.utf82ansi( title ),type)
rescue Hangup
nil # !※例外時にここを通過せずに外部に投げられる恐れあり
ensure
# !※例外時にここを通過せずに外部に投げられる恐れあり
begin
Graphics.safe_update
rescue SecurityHazard
end
end
end
#--------------------------------------------------------------------------
# ◆(!特定外使用禁止!)◆ 致命的エラーを通知
# ※警告 :例外 Hangup 対策をかならず行うこと!
#--------------------------------------------------------------------------
def self.fatalerror( errobj )
begin
ErrorLogWriter.write( errobj )
error_message , tracer = error_message_setup( errobj )
# 瞬間消去
Graphics.transition(0)
Audio.bgm_stop
Audio.bgs_stop
Audio.me_stop
Audio.se_stop
if debug? and ( not (tracer[/^(?:Section)?{?(\d+)}?:(\d+)/]).nil? )
# セクションを拾い出した場合
nums = $1.to_i
extra = $RGSS_SCRIPTS.at(nums).at(1)
lines = $2.to_i
tracer = "#{extra} の #{lines} 行目で、\n"
error_message = tracer + error_message
end
title = "\x00" * 256
@@gpps.call( 'Game' , 'Title' , '' , title , 255 , '.\\Game.ini' )
title = String.ansi2utf8(title)
title.tr("\x00","")
# マウスカーソルを表示
Input.mouse_show if Input.method_defined?(:mouse_show)
# メッセージボックス
messagebox( error_message , title , MB_FATAL )
rescue Hangup
nil # !※例外時にここを通過せずに外部に投げられる恐れあり
end
rescue Hangup
nil
end
# ---------------------------------------------------------------------------
# ◆ 異常終了のメッセージを整形
# ---------------------------------------------------------------------------
def self.error_message_setup( errobj )
Graphics.freeze
begin
Graphics.safe_update
rescue SecurityHazard
end
_message = ""
# バックトレースを記憶する
unless $@.nil? or ($@.at(0)).nil?
tracer = ($@.at(0)).dup
# バックトレースを解析する
backtrace = ""
i = 0
for str in $@.dup
unless (str[ERROR_SECTION_NUM]).nil?
extra = $RGSS_SCRIPTS.at($1.to_i).at(1)
str.gsub!(ERROR_SECTION) { "( " + extra + " ):" }
end
backtrace += str
end
unless errobj.is_a?(SystemStackError)
if rpgvxace?
_message = errobj.message.force_encoding("UTF-8") +
"\n** backtrace:\n" + backtrace
else
_message = errobj.message + "\n** backtrace:\n" + backtrace
end
end
else
tracer = "" # バックトレース取得失敗
if rpgvxace?
_message = errobj.message.force_encoding("UTF-8")
else
_message = errobj.message
end
end
until (_message[DOUBLE_CRLF]).nil?
_message.gsub!(DOUBLE_CRLF){ "\n" }
end
if debug?
_message = "解決できない例外 " + (errobj.class).inspect +
" が発生したため、処理を継続できません。\n" +
_message
else
_message = "解決できない例外 " + (errobj.class).inspect +
" が発生したため、処理を継続できませんでした。\n" +
"お手数をおかけして申し訳ありません。\n\n詳細情報:\n" +
_message
end
return _message, tracer
end
end
# RGSS2 環境だと、リセットは阻止できない。
if $@ and WFRGSS::DEBUG_CONSOLE and debug?
p "例外 Reset が外部へ投げられました。"
end
[/pre]
main[pre lang="ruby"]# coding: utf-8
# ===========================================================================
# ★ WF-RGSS Scripts ★
# 共通実行スクリプト(XP/VX/VXAce両対応版)
# バージョン : rev-29 (2013-3-26)
# 作者 : WF-RGSS担当 (WHITE-FLUTE)
# サポート先URI: http://www.whiteflute.org/wfrgss/
# ---------------------------------------------------------------------------
# 機能:
# ・デバッグモードで例外が発生したとき、エラーを errors.txt に記録します。
# ・高速なリセットを利用できるようになります。
# ---------------------------------------------------------------------------
# 影響:
# ・ファイルが見つからない例外は、 元の Errno::ENOENT が補足されます。
# ---------------------------------------------------------------------------
# 設置場所 :Mainセクション(一番最後)に上書き
# または、Mainセクションの直前
# 必要スクリプト:
# ・共通スクリプト
# 注意事項:
# ▽ 共通スクリプトが必要です。
# 改造して使用することを推奨しますが、そのまま使ってもOKです。
# ▽ デバッグモードでエラーを記録する場合、
# 現在のユーザで書き込みを行えることが必要になります。
#==============================================================================
# ◆ Main ( Execute )
#------------------------------------------------------------------------------
# 各クラスの定義が終わった後、ここから実際の処理が始まります。
#==============================================================================
# ---------------------------------------------------------------------------
# ◆ 処理実行
# ---------------------------------------------------------------------------
# スレッド例外で即座に中断しないようにする。(デバッグ時は無効)
# ※ true に設定する場合はご注意ください。
# 終了する前に解放が必要なものもあります。
Thread.abort_on_exception = false
# RPGVX 互換
if rpgvx? and (not rpgvxace?)
unless Font.exist?("UmePlus Gothic")
print "UmePlus Gothic フォントが見つかりません。"
exit
end
end
begin
unless rpgvxace?
# トランジション準備
Graphics.freeze
# シーンオブジェクトを作成
# ★ 最初のシーンはここに設定します。 ★
$scene = Scene_Title.new
# ★ --------------------------------------------------------------------
# $scene が有効な限り main メソッドを呼び出す
$scene.main until $scene.nil?
# フェードアウト
Graphics.transition(20)
else
rgss_main { SceneManager.run }
end
# 以下、例外処理
rescue BugDetected, InternalBugDetected => errobj
begin
MessageBox.fatalerror( errobj )
raise SystemExit.new(1)
rescue Hangup
nil
end
rescue Reset
# -------------------------------------------------------------------------
# ◆ F12 リセット( 例外 Reset < Exception )
# -------------------------------------------------------------------------
# ※retry する場合は、
# かならず、ウィンドウやスプライトが確実に解放される必要があります。
# ※ RGSS2環境ではF12の機構を封じないと封じ込められません。
raise
rescue Hangup => errobj
# -------------------------------------------------------------------------
# ◆ 致命的例外 Hangup
# -------------------------------------------------------------------------
begin
MessageBox.fatalerror( errobj )
raise SystemExit.new(1)
rescue Hangup
nil
end
rescue SystemExit => errobj
# -------------------------------------------------------------------------
# ◆ 終了要求 ( Alt + F4 など )
# -------------------------------------------------------------------------
# 例外が正常終了で無い場合は、例外 SystemExitを再発生させます。
raise unless (errobj.status).zero?
rescue Exception => errobj
# -------------------------------------------------------------------------
# ◆ 例外処理
# 特に指定されていない例外を補足します。
# ※ rev-2 より、Errno::ENOENT もここで補足します。
# -------------------------------------------------------------------------
begin
MessageBox.fatalerror( errobj )
raise SystemExit.new(1)
rescue Hangup
nil
end
ensure
unless $!.is_a?(Reset)
# -------------------------------------------------------------------------
# ● 後処理
# -------------------------------------------------------------------------
# 後処理を記述します。
# スクリプト内容によってはここで解放処理が必要になることがあります。
# ★ 後処理を記述します。 ★
# ★ ----------------------------------------------------------------------
else
$! = nil unless rpgvxace?
end
end
exit # Mainセクションが後に控えている時に処理が渡らないようにする
[/pre]
xppatch[pre lang="ruby"]# ===========================================================================
# ★ WF-RGSS Scripts ★
# デバッグ修正スクリプト(XP専用)
# バージョン : rev-1 (2013-3-26)
# 作者 : WF-RGSS担当 (WHITE-FLUTE)
# サポート先URI: http://www.whiteflute.org/wfrgss/
# ---------------------------------------------------------------------------
# 機能:
# ・RPGツクールXP上にて、デバッグ時にスレッドを使えるようにします。
# ---------------------------------------------------------------------------
# 設置場所:Scene_Debugより下、Mainより上
# 必要スクリプト:
# ・共通スクリプト(rev-29以降)
# 注意事項:
# 共通スクリプトを導入しないとエラーになります。
# ===========================================================================
raise "It doesn't correspond to RGSS of this version." if rpgvx?
class Game_Player < Game_Character
#--------------------------------------------------------------------------
# ● 通行可能判定 (再定義)
#--------------------------------------------------------------------------
def passable?(x, y, d)
new_x = x + (d == 6 ? 1 : d == 4 ? -1 : 0)
new_y = y + (d == 2 ? 1 : d == 8 ? -1 : 0)
return false unless $game_map.valid?(new_x, new_y)
return true if debug? and Input.press?(Input::CTRL)
super
end
#--------------------------------------------------------------------------
# ● フレーム更新 (再定義)
#--------------------------------------------------------------------------
def update
last_moving = moving?
update_moving
last_real_x = @real_x
last_real_y = @real_y
super
update_scroll
update_encounter_and_event_check( last_moving )
end
private
#--------------------------------------------------------------------------
# ◆(内部専用)◆ 移動制御
#--------------------------------------------------------------------------
def update_moving
unless moving? or $game_system.map_interpreter.running? or
@move_route_forcing or $game_temp.message_window_showing
case Input.dir4
when 2
move_down
when 4
move_left
when 6
move_right
when 8
move_up
end
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ スクロール制御
#--------------------------------------------------------------------------
def update_scroll
if @real_y > last_real_y and @real_y - $game_map.display_y > CENTER_Y
$game_map.scroll_down(@real_y - last_real_y)
elsif @real_y < last_real_y and @real_y - $game_map.display_y < CENTER_Y
$game_map.scroll_up(last_real_y - @real_y)
end
if @real_x < last_real_x and @real_x - $game_map.display_x < CENTER_X
$game_map.scroll_left(last_real_x - @real_x)
elsif @real_x > last_real_x and @real_x - $game_map.display_x > CENTER_X
$game_map.scroll_right(@real_x - last_real_x)
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ エンカウントとイベントの処理
#--------------------------------------------------------------------------
def update_encounter_and_event_check( last_moving )
unless moving?
update_encounter( last_moving )
event_check
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ エンカウントの処理
#--------------------------------------------------------------------------
def update_encounter( last_moving )
if last_moving
result = check_event_trigger_here([1,2])
unless result
unless debug? and Input.press?(Input::CTRL)
if @encounter_count > 0
@encounter_count -= 1
end
end
end
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ イベントの処理
#--------------------------------------------------------------------------
def event_check
if Input.trigger?(Input::C)
check_event_trigger_here([0])
check_event_trigger_there([0,1,2])
end
end
end
class Scene_Map
private
#--------------------------------------------------------------------------
# ● フレーム更新 (再定義)
#--------------------------------------------------------------------------
def update
main_update
update_goto_scene
update_transition
return if $game_temp.message_window_showing
update_encounter
update_menu_calling
update_debug
update_call_scene
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ 更新処理
#--------------------------------------------------------------------------
def main_update
loop do
$game_map.update
$game_system.map_interpreter.update
$game_player.update
$game_system.update
$game_screen.update
break unless $game_temp.player_transferring
transfer_player
break if $game_temp.transition_processing
end
@spriteset.update
@message_window.update
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ シーン直行
#--------------------------------------------------------------------------
def update_goto_scene
if $game_temp.gameover
$scene = Scene_Gameover.new
return
end
if $game_temp.to_title
$scene = Scene_Title.new
return
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ トランジションの処理
#--------------------------------------------------------------------------
def update_transition
if $game_temp.transition_processing
$game_temp.transition_processing = false
if $game_temp.transition_name == ""
Graphics.transition(20)
else
Graphics.transition(40, "Graphics/Transitions/" +
$game_temp.transition_name)
end
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ エンカウントの処理
#--------------------------------------------------------------------------
def update_encounter
if $game_player.encounter_count == 0 and $game_map.encounter_list != []
unless $game_system.map_interpreter.running? or
$game_system.encounter_disabled
n = rand($game_map.encounter_list.size)
troop_id = $game_map.encounter_list[n]
if $data_troops[troop_id]
$game_temp.battle_calling = true
$game_temp.battle_troop_id = troop_id
$game_temp.battle_can_escape = true
$game_temp.battle_can_lose = false
$game_temp.battle_proc = nil
end
end
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ メニュー遷移
#--------------------------------------------------------------------------
def update_menu_calling
if Input.trigger?(Input::B)
unless $game_system.map_interpreter.running? or
$game_system.menu_disabled
$game_temp.menu_calling = true
$game_temp.menu_beep = true
end
end
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ デバッグ遷移
#--------------------------------------------------------------------------
def update_debug
$game_temp.debug_calling = true if debug? and Input.press?(Input::F9)
end
#--------------------------------------------------------------------------
# ◆(内部専用)◆ シーン呼び出し
#--------------------------------------------------------------------------
def update_call_scene
unless $game_player.moving?
if $game_temp.battle_calling
call_battle
elsif $game_temp.shop_calling
call_shop
elsif $game_temp.name_calling
call_name
elsif $game_temp.menu_calling
call_menu
elsif $game_temp.save_calling
call_save
elsif $game_temp.debug_calling
call_debug
end
end
end
end
[/pre]
拜访顺序是base,largechara,main,xppatch
这个脚本另外还有两个部件脚本,不过只是和这个冲突。
这两个哪个在下面,就哪个生效,另一个失效。
NPC名字脚本就是在NPC头上显示名字的脚本。
NPC大小判断就是可以判断事件的图片大小,根据图片位图进行事件的判断。比如大的事件不能通过小的通道。 |
|