# @taroxd metadata 1.0
# @require taroxd_core
# @display 设置地图通行度
# @id set_passage
# @help
#
# 使用方法2:** require 显示地图通行度 **
#
# 测试模式下,把 EDIT_MODE 设为 true,
# 然后在地图上按下确定键即可改变当前位置的通行度。
# 该模式下,角色可以自由穿透。
#
# △表示不改变,○表示可以通行,×表示不可通行。颜色表示最终的通行度。
#
# 需要清空设置的话,删除设置文件(见 FILE 常量)即可。
#
# 需要重置一张地图的设置的话,可以调用如下脚本:
# Taroxd::Passage.clear(map_id)
# 其中 map_id 为地图 ID。若要清除当前地图的通行度,map_id 可以不填。
# 注意,清除后,通行度的显示并不会立即改变。重新打开游戏即可看到效果。
module Taroxd::Passage
# 地图通行度信息会保存到这个文件。建议每次编辑前备份该文件。
FILE = 'Data/MapPassage.rvdata2'
# 是否打开编辑模式。需要前置脚本“显示地图通行度”才可打开。
EDIT_MODE = false
# 编辑方式(可整合鼠标脚本)
EDIT_TRIGGER = -> { Input.trigger?(:C) }
EDIT_POINT = -> { [$game_player.x, $game_player.y] }
# 常量,不建议改动
DEFAULT = 0
PASSABLE = 1
IMPASSABLE = 2
TEXTS = ['△', '○', '×']
SIZE = TEXTS.size
# 设置区域通行度。一个以区域ID为键的哈希表。(未设置的区域,ID为0)
# 哈希表值的意义如下
# PASSABLE / true:该区域强制可以通行。
# IMPASSABLE / false:该区域强制不可通行。
# [区域ID1, 区域ID2, ...]:该区域只能通行至指定的区域。
# 设置例:
# REGIONS = {
# 1 => PASSABLE,
# 2 => false,
# 3 => [3, 4], # 只有通过4号区域才能出入3号区域
# 5 => [*0..63] - [6] # 5号区域与6号区域的边界线不可通行
# }
REGIONS = {}
# 通行度的哈希表。以地图ID为键,以通行度的二维 Table 为值。
@data = File.exist?(FILE) ? load_data(FILE) : {}
class << self
# 获取 x, y 坐标处的 d 方向通行度设定。(DEFAULT/PASSABLE/IMPASSABLE)
def [](x, y, d)
data[x, y] == DEFAULT ? region_passable(x, y, d) : data[x, y]
end
# 更新,编辑模式下应每帧调用一次
def update
return unless EDIT_TRIGGER.call
x, y = EDIT_POINT.call
data[x, y] = (data[x, y] + 1) % SIZE
save
end
# 获取当前地图的数据
def data
table = @data[map_id] ||= Table.new(width, height)
if table.xsize < width || table.ysize < height
update_table(table)
else
table
end
end
# 清除一个地图的设置
def clear(map_id = $game_map.map_id)
@data.delete(map_id)
save
end
private
# 区域设置中能否通行(DEFAULT/PASSABLE/IMPASSABLE)
def region_passable(x, y, d)
settings = REGIONS[$game_map.region_id(x, y)]
case settings
when true, PASSABLE then PASSABLE
when false, IMPASSABLE then IMPASSABLE
when Enumerable
x2 = $game_map.round_x_with_direction(x, d)
y2 = $game_map.round_y_with_direction(y, d)
settings.include?($game_map.region_id(x2, y2)) ? DEFAULT : IMPASSABLE
else DEFAULT
end
end
# 如果表格不够大,那么重新建立表格
def update_table(table)
@data[map_id] = new_table = Table.new(width, height)
table.xsize.times do |x|
table.ysize.times do |y|
new_table[x, y] = table[x, y]
end
end
new_table
end
# 将所有数据保存到文件
def save
save_data(@data, FILE)
end
# 获取当前地图信息
def map_id
$game_map.map_id
end
def width
$game_map.width
end
def height
$game_map.height
end
end
end
class Game_Map
psg = Taroxd::Passage
def_chain :passable? do |old, x, y, d|
case psg[x, y, d]
when psg::DEFAULT then old.call(x, y, d)
when psg::PASSABLE then true
when psg::IMPASSABLE then false
end
end
end
if $TEST && Taroxd::Passage::EDIT_MODE
class Game_Player < Game_Character
# 每帧调用一次 Taroxd::Passage.update
def_after :update, Taroxd::Passage.method(:update)
def debug_through?
true
end
end
class Taroxd::PlanePassage < Plane
TEXT_RECT = Rect.new(0, 0, 32, 32)
const_set :VISIBLE, true
psg = Taroxd::Passage
include psg
# 通行度文字的位图缓存
def text_bitmaps
@text_bitmap_cache ||= TEXTS.map do |text|
bitmap = Bitmap.new(TEXT_RECT.width, TEXT_RECT.height)
bitmap.draw_text(TEXT_RECT, text, 1)
bitmap
end
end
# 绘制通行度的设置情况
def_after :draw_point do |x, y|
bitmap.blt(x * 32, y * 32, text_bitmaps[psg.data[x, y]], TEXT_RECT)
end
# 更新通行度的变化
def_after :update do
return unless EDIT_TRIGGER.call
x, y = EDIT_POINT.call
bitmap.clear_rect(x * 32, y * 32, 32, 32)
draw_point(x, y)
end
def_before :dispose do
@text_bitmaps_cache.each(&:dispose) if @text_bitmaps
end
end
end