#==============================================================================
# □ Etude87's KMS MiniMap Add-on ver.1.3.7
#==============================================================================
# * 한국어
# 작성자 : 습작
# 설 명 : KMS MiniMap에 이동경로 그리기 및 포그 기능 등을 추가해주는 스크립트 입니다.
#==============================================================================
# * ENG
# Author : etude87
# Explanation : It is a script that adds movement path drawing and fog function to KMS MiniMap.
#==============================================================================
#
# 현재 문제점 : 지붕타일 정상 작동 안함, FOV 화면 스크롤과 이격, 타일 id 기반 지붕타일 예외 추가 처리 안됨, inRange 필요 여부
#
#==============================================================================
module Etude87_KMS_MiniMap
#--------------------------------------------------------------------------
# 현재 위치 그리기 설정 모음
# Collection of current location drawing settings
#--------------------------------------------------------------------------
# 세모꼴 위치 표시 사용 여부
# Whether to use the triangle mark
USE_TRIANGLE_POINT = true
# 세모꼴 위치 표시 정렬 방식(0:상단, 1:중단, 2:하단)
# Triangle mark position display alignment method(0:top, 1:middle, 2:bottom)
ALIGN_TRIANGLE_POINT = 1
#--------------------------------------------------------------------------
# 미니맵 이동 경로 그리기 설정 모음
# Mini Map Drawing Path Drawing Set Collection
#--------------------------------------------------------------------------
# 이동 경로 그리기 사용 여부
# Whether to use draw path
USE_MOVE_ROUTE = true
# 이동 경로 색상
# Path color
MOVE_ROUTE_COLOR = Color.new(255, 0, 0, 192)
# 이동 경로 길이( 1보다 작은 경우 무제한 )
# Path length (unlimited if less than 1)
MOVE_ROUTE_LENGTH = 50
# 이동 경로 선 굵기
# Thickness of the moving path
LINE_THICKNESS = 1
# 점점 흐려지기 사용 여부
# Increasingly blurred
USE_TRANSPARENCY = true
#--------------------------------------------------------------------------
# 미니맵 포그 기능 설정 모음
# Mini Map fog feature set
#--------------------------------------------------------------------------
# 미니맵 포그 기능 사용 여부
# Whether mini-map fog function is used
USE_FOG = true
# 시야범위 최 외각 처리여부
# Whether the outline of the field is processed
USE_OUTLINE = true
# 시야범위 최 외각 굵기
# Outline thickness
OUTLINE_THICKNESS = 5
# 맵별 예외처리
# Handle exceptions by map
EXCEPTION = {
# ID 1번맵 마름모 시야범위
# ID 1 map rhombus view
#1 => [:lozenge, 5],
# ID 2번맵 정사각형 시야범
# ID 2 map square view
2 => [:square, 4],
# ID 3번맵 원형 시야범위
# ID 3 map round view
#3 => [:circle, 5],
# ID 4번맵 마름모 시야범위
# ID 4 map rhombus view
#4 => [:lozenge, 5],
# ID 5번맵 포그 미사용
# ID 5 map fog unused
#5 => :none,
}#<= 지우지 말것 / Do not erase
#--------------------------------------------------------------------------
# 미니맵 시야각 기능 설정 모음
# Mini Map field of view feature set
#--------------------------------------------------------------------------
# 미니맵 시야각 기능 사용 여부
# Whether mini-map field of view function is used
USE_FOV = true
# 통행설정 기반 시야각 판별 사용 여부
# Use of traffic setting based viewing angle discrimination
Auto_FOV = true
# 지붕 및 벽 시야각 처리 여부
# Handle roof and wall viewing angles
Roof_Wall = true
# 시야각 처리 예외 지형 태그
# Viewing angle handling exception terrain tag
Exception_Terrain_Tag = 1
# 시야각 처리 추가 지형 태그
# View angle handling added terrain tag
Additional_Terrain_Tag = 2
# 시야각 처리 대상 이벤트 이름 키워드
# Viewing angle processing target event name keyword
FOV_Ev_Name_Keyword = "[FOV]"
#--------------------------------------------------------------------------
end
#==============================================================================
#==============================================================================
class Game_System
attr_reader :route
attr_reader :drawable
#--------------------------------------------------------------------------
alias etude87_initialize initialize
def initialize
@route = []
@drawable = {}
etude87_initialize
end
#--------------------------------------------------------------------------
def add_route(pos)
@route.shift if (Etude87_KMS_MiniMap::MOVE_ROUTE_LENGTH <= @route.size && Etude87_KMS_MiniMap::MOVE_ROUTE_LENGTH >= 1)
@route.push(pos)
px = $game_player.x
py = $game_player.y
m = Etude87_KMS_MiniMap::EXCEPTION[$game_map.map_id]
o = Etude87_KMS_MiniMap::USE_OUTLINE
t = Etude87_KMS_MiniMap::OUTLINE_THICKNESS
tx = $game_map.screen_tile_x.to_i
ty = $game_map.screen_tile_y.to_i
dx = $game_map.display_x.to_i
dy = $game_map.display_y.to_i
mw = $game_map.width.to_i
mh = $game_map.height.to_i
if Etude87_KMS_MiniMap::EXCEPTION[$game_map.map_id] && Etude87_KMS_MiniMap::EXCEPTION[$game_map.map_id] != :none
min_x = px - m[1]
max_x = px + m[1]
min_y = py - m[1]
max_y = py + m[1]
else
min_x = [[px - (tx - 1)/2, 0].max, mw - tx].min
max_x = min_x + tx - 1
min_y = [[py - (ty - 1)/2, 0].max, mh - ty].min
max_y = min_y + ty - 1
if o
min_x -= t if min_x == 0
max_x += t if max_x == mw - 1
min_y -= t if min_y == 0
max_y += t if max_y == mh - 1
end
end
@drawable[pos[0]] ||= {}
for i in dx..(dx + tx)
for j in dy..(dy + ty)
@drawable[pos[0]][i] ||= {}
if Etude87_KMS_MiniMap::USE_FOV
unless checkFOV(px, py, i, j, false)
if @drawable[pos[0]][i][j]
@drawable[pos[0]][i][j] = 1
end
next
end
end
end
end
for x in min_x..max_x
for y in min_y..max_y
@drawable[pos[0]][x] ||= {}
if Etude87_KMS_MiniMap::USE_FOV
unless checkFOV(px, py, x, y, true)
if @drawable[pos[0]][x][y]
@drawable[pos[0]][x][y] = 1
end
next
end
end
if m
case m[0]
when :circle
next if m[1] < Math.sqrt((px - x)**2 + (py - y)**2).to_i
when :lozenge
next if (px - x).abs + (py - y).abs > m[1]
end
end
r = offset(x, min_x, max_x, y, min_y, max_y, px, py)
if @drawable[pos[0]][x][y]
if @drawable[pos[0]][x][y] < r
@drawable[pos[0]][x][y] = r
end
else
@drawable[pos[0]][x][y] = r
end
end
end
end
#--------------------------------------------------------------------------
def checkFOV(x1, y1, x2, y2, inRange)
return true if x1 == x2 && y1 == y2
x = x1
y = y1
counter = 0
result = true
dx = x2 - x1
dy = y2 - y1
if dx.abs > dy.abs
d = dx > 0 ? 6 : 4
elsif dy != 0
d = dy > 0 ? 2 : 8
end
if dx < 0
addX = -1
dx = -dx
else
addX = 1
end
if dy < 0
addY = -1
dy = -dy
else
addY = 1
end
if dx >= dy
for i in 0...dx
x += addX
counter += dy
if counter >= dx
y += addY
counter -= dx
end
unless $game_map.viewable?(x, y, d)
result = false unless (x == x2 && y == y2)
break
end
end
else
for i in 0...dy
y += addY
counter += dx
if counter >= dy
x += addX
counter -= dy
end
unless $game_map.viewable?(x, y, d)
result = false unless (x == x2 && y == y2)
break
end
end
end
return result
end
#--------------------------------------------------------------------------
def offset(x, min_x, max_x, y, min_y, max_y, px, py)
t = Etude87_KMS_MiniMap::OUTLINE_THICKNESS
return t unless Etude87_KMS_MiniMap::USE_OUTLINE
if Etude87_KMS_MiniMap::EXCEPTION[$game_map.map_id]
m = Etude87_KMS_MiniMap::EXCEPTION[$game_map.map_id]
case m[0]
when :square
a = (x - min_x).abs if (x - min_x).abs < t
b = (x - max_x).abs if (x - max_x).abs < t
c = (y - min_y).abs if (y - min_y).abs < t
d = (y - max_y).abs if (y - max_y).abs < t
when :circle
i = m[1] - Math.sqrt((px - x)**2 + (py - y)**2).to_i
a = i if i < t
when :lozenge
a = m[1] - ((px - x).abs + (py - y).abs) if m[1] - ((px - x).abs + (py - y).abs) < t
end
else
a = (x - min_x).abs if (x - min_x).abs < t
b = (x - max_x).abs if (x - max_x).abs < t
c = (y - min_y).abs if (y - min_y).abs < t
d = (y - max_y).abs if (y - max_y).abs < t
end
return [a,b,c,d,t].compact.min
end
#--------------------------------------------------------------------------
def clear_route
@route = []
end
#--------------------------------------------------------------------------
end
#==============================================================================
#==============================================================================
class Game_Event < Game_Character
#--------------------------------------------------------------------------
attr_reader :event
#--------------------------------------------------------------------------
end
#==============================================================================
#==============================================================================
class Game_Map
#--------------------------------------------------------------------------
def viewable?(x, y, d)
check_view(x, y, (1 << (d / 2 - 1)) & 0x0f)
end
#--------------------------------------------------------------------------
def check_view(x, y, bit)
all_tiles(x, y).each do |tile_id|
unless events_xy(x, y).empty?
ev = events_xy(x, y)[0]
return false if ev.event.name.include?(Etude87_KMS_MiniMap::FOV_Ev_Name_Keyword) && ev.normal_priority?
end
return false if terrain_tag(x, y) == Etude87_KMS_MiniMap::Additional_Terrain_Tag
flag = tileset.flags[tile_id]
if flag & 0x10 != 0
next if flag & bit == 0
else
return true if flag & bit == 0
end
return true if terrain_tag(x, y) == Etude87_KMS_MiniMap::Exception_Terrain_Tag
return false if tile_id >= 4352 && tile_id <= 8191 && Etude87_KMS_MiniMap::Roof_Wall
return false if flag & bit == bit && Etude87_KMS_MiniMap::Auto_FOV
end
return false
end
#--------------------------------------------------------------------------
def reveal_tiles(x, y, distance = Theo::VisiRange, reveal = true)
return if no_fog?
sprset = SceneManager.scene.spriteset
sprset.fogofwar.reveal_fogs if sprset
end
#--------------------------------------------------------------------------
end
#==============================================================================
#==============================================================================
class Game_Player < Game_Character
#--------------------------------------------------------------------------
alias etude87_moveto moveto
def moveto(x, y)
etude87_moveto(x, y)
@last_pos = [$game_map.map_id, @x, @y, 5]
$game_system.add_route(@last_pos)
end
#--------------------------------------------------------------------------
alias etude87_increase_steps increase_steps
def increase_steps
$game_system.add_route(@last_pos) if @last_pos
@last_pos = [$game_map.map_id, @x, @y, @direction]
etude87_increase_steps
end
#--------------------------------------------------------------------------
alias etude87_reserve_transfer reserve_transfer
def reserve_transfer(map_id, x, y, d = 2)
etude87_reserve_transfer(map_id, x, y, d)
$game_system.clear_route
end
#--------------------------------------------------------------------------
end
#==============================================================================
#==============================================================================
class Game_MiniMap
#--------------------------------------------------------------------------
alias etude87_create_sprites create_sprites
def create_sprites
unless Etude87_KMS_MiniMap::USE_TRIANGLE_POINT
etude87_create_sprites
else
@viewport = Viewport.new(@map_rect)
@viewport.z = KMS_MiniMap::MAP_Z
@bmp_size = Size.new(
(@grid_num.x + 2) * @grid_size,
(@grid_num.y + 2) * @grid_size
)
@buf_bitmap = Bitmap.new(@bmp_size.width, @bmp_size.height)
@map_sprite = Sprite.new(@viewport)
@map_sprite.x = -@grid_size
@map_sprite.y = -@grid_size
@map_sprite.z = 0
@map_sprite.bitmap = Bitmap.new(@bmp_size.width, @bmp_size.height)
@object_sprite = Sprite_MiniMapIcon.new(@viewport)
@object_sprite.x = -@grid_size
@object_sprite.y = -@grid_size
@object_sprite.z = 1
@object_sprite.bitmap = Bitmap.new(@bmp_size.width, @bmp_size.height)
@position_sprite = Sprite_MiniMapIcon.new
@position_sprite.x = @map_rect.x + @grid_num.x / 2 * @grid_size
@position_sprite.y = @map_rect.y + @grid_num.y / 2 * @grid_size
@position_sprite.z = @viewport.z + 2
bitmap = Bitmap.new(@grid_size, @grid_size)
case Etude87_KMS_MiniMap::ALIGN_TRIANGLE_POINT
when 0
align_tp = 0
when 1
align_tp = @grid_size/4
when 2
align_tp = @grid_size/2
end
@last_dir = $game_player.direction
for i in 0...(@grid_size/2 + @grid_size%2)
case @last_dir
when 2
bitmap.fill_rect(@grid_size/2-i, @grid_size-i-1-align_tp, 2*i+1, 1, KMS_MiniMap::POSITION_COLOR)
when 4
bitmap.fill_rect(i+align_tp, @grid_size/2-i, 1, 2*i+1, KMS_MiniMap::POSITION_COLOR)
when 6
bitmap.fill_rect(@grid_size-i-1-align_tp, @grid_size/2-i, 1, 2*i+1, KMS_MiniMap::POSITION_COLOR)
when 8
bitmap.fill_rect(@grid_size/2-i, i+align_tp, 2*i+1, 1, KMS_MiniMap::POSITION_COLOR)
end
end
@position_sprite.bitmap = bitmap
end
end
#--------------------------------------------------------------------------
alias etude87_update_position update_position
def update_position
etude87_update_position
return unless Etude87_KMS_MiniMap::USE_TRIANGLE_POINT
return unless @last_dir != $game_player.direction
@position_sprite.bitmap.clear
bitmap = Bitmap.new(@grid_size, @grid_size)
case Etude87_KMS_MiniMap::ALIGN_TRIANGLE_POINT
when 0
align_tp = 0
when 1
align_tp = @grid_size/4
when 2
align_tp = @grid_size/2
end
@last_dir = $game_player.direction
for i in 0...(@grid_size/2 + @grid_size%2)
case @last_dir
when 2
bitmap.fill_rect(@grid_size/2-i, @grid_size-i-1-align_tp, 2*i+1, 1, KMS_MiniMap::POSITION_COLOR)
when 4
bitmap.fill_rect(i+align_tp, @grid_size/2-i, 1, 2*i+1, KMS_MiniMap::POSITION_COLOR)
when 6
bitmap.fill_rect(@grid_size-i-1-align_tp, @grid_size/2-i, 1, 2*i+1, KMS_MiniMap::POSITION_COLOR)
when 8
bitmap.fill_rect(@grid_size/2-i, i+align_tp, 2*i+1, 1, KMS_MiniMap::POSITION_COLOR)
end
end
@position_sprite.bitmap = bitmap
end
#--------------------------------------------------------------------------
alias etude87_draw_map_foreground draw_map_foreground
def draw_map_foreground(bitmap)
if Etude87_KMS_MiniMap::USE_FOG && Etude87_KMS_MiniMap::EXCEPTION[$game_map.map_id] != :none
range_x = (@draw_range_begin.x)..(@draw_range_end.x)
range_y = (@draw_range_begin.y)..(@draw_range_end.y)
map_w = $game_map.width - 1
map_h = $game_map.height - 1
rect = Rect.new(0, 0, @grid_size, @grid_size)
range_x.each { |x|
next unless x.between?(0, map_w)
next unless $game_system.drawable[$game_map.map_id][x]
range_y.each { |y|
next unless y.between?(0, map_h)
next unless $game_system.drawable[$game_map.map_id][x][y]
next if @passage_table[x, y] == 0
next if @wall_events.find { |e| e.x == x && e.y == y }
rect.set(0, 0, @grid_size, @grid_size)
rect.x = (x - @draw_range_begin.x) * @grid_size
rect.y = (y - @draw_range_begin.y) * @grid_size
flag = @passage_table[x, y]
if flag & 0x01 == 0
rect.height -= 1
end
if flag & 0x02 == 0
rect.x += 1
rect.width -= 1
end
if flag & 0x04 == 0
rect.width -= 1
end
if flag & 0x08 == 0
rect.y += 1
rect.height -= 1
end
color = outline_color($game_system.drawable[$game_map.map_id][x][y])
bitmap.fill_rect(rect, color)
}
}
else
etude87_draw_map_foreground(bitmap)
end
if Etude87_KMS_MiniMap::USE_MOVE_ROUTE
if $game_system.route.size > 0
for i in 0...$game_system.route.size
draw_route(bitmap, i)
end
end
end
end
#--------------------------------------------------------------------------
alias etude87_draw_map_move_event draw_map_move_event
def draw_map_move_event(bitmap)
if Etude87_KMS_MiniMap::USE_FOG
rect = Rect.new(0, 0, @grid_size, @grid_size)
@move_events.each { |e|
rect.x = (e.x - @draw_range_begin.x) * @grid_size
rect.y = (e.y - @draw_range_begin.y) * @grid_size
bitmap.fill_rect(rect, KMS_MiniMap::MOVE_EVENT_COLOR) if map_visible?(e.x, e.y)
}
else
etude87_draw_map_move_event(bitmap)
end
end
#--------------------------------------------------------------------------
alias etude87_draw_object draw_object
def draw_object
if Etude87_KMS_MiniMap::USE_FOG
bitmap = @object_sprite.bitmap
bitmap.clear
rect = Rect.new(0, 0, @grid_size, @grid_size)
@object_list.each { |obj|
next unless in_draw_range?(obj.x, obj.y)
color = KMS_MiniMap::OBJECT_COLOR[obj.minimap_object_type - 1]
next if color.nil?
rect.x = (obj.real_x - @draw_range_begin.x) * @grid_size
rect.y = (obj.real_y - @draw_range_begin.y) * @grid_size
bitmap.fill_rect(rect, color) if map_visible?(obj.real_x, obj.real_y)
}
$game_map.vehicles.each { |vehicle|
next if vehicle.transparent
rect.x = (vehicle.real_x - @draw_range_begin.x) * @grid_size
rect.y = (vehicle.real_y - @draw_range_begin.y) * @grid_size
bitmap.fill_rect(rect, KMS_MiniMap::VEHICLE_COLOR) if map_visible?(vehicle.real_x, vehicle.real_y)
}
else
etude87_draw_object
end
end
#--------------------------------------------------------------------------
def outline_color(i)
t = Etude87_KMS_MiniMap::OUTLINE_THICKNESS
c1 = KMS_MiniMap::BACKGROUND_COLOR
c2 = KMS_MiniMap::FOREGROUND_COLOR
red = c2.red + (c1.red - c2.red) /(t + 1) * (t - i)
green = c2.green + (c1.green - c2.green)/(t + 1) * (t - i)
blue = c2.blue + (c1.blue - c2.blue) /(t + 1) * (t - i)
alpha = c2.alpha + (c1.alpha - c2.alpha)/(t + 1) * (t - i)
return Color.new(red, green, blue, alpha)
end
#--------------------------------------------------------------------------
def map_visible?(x, y)
return false unless $game_system.drawable[$game_map.map_id]
return false unless $game_system.drawable[$game_map.map_id][x]
return false unless $game_system.drawable[$game_map.map_id][x][y]
return true
end
#--------------------------------------------------------------------------
def draw_route(bitmap, i)
a = i+1 < $game_system.route.size ? $game_system.route[i+1][3] : $game_player.direction
r = $game_system.route[i]
x = (r[1] - @draw_range_begin.x) * @grid_size
y = (r[2] - @draw_range_begin.y) * @grid_size
draw_line(bitmap, x, y, a, i)
draw_line(bitmap, x, y, 10-r[3], i)
end
#--------------------------------------------------------------------------
def draw_line(bitmap, x, y, dir, i)
t = Etude87_KMS_MiniMap::LINE_THICKNESS
l = ((@grid_size - t) - (@grid_size - t)%2)/2 + t
case dir
when 2
rect = Rect.new(0, 0, t, l)
rect.x = x + l - t
rect.y = y + l - t
when 4
rect = Rect.new(0, 0, l, t)
rect.x = x
rect.y = y + l - t
when 6
rect = Rect.new(0, 0, l, t)
rect.x = x + l - t
rect.y = y + l - t
when 8
rect = Rect.new(0, 0, t, l)
rect.x = x + l - t
rect.y = y
end
bitmap.fill_rect(rect, line_color(KMS_MiniMap::FOREGROUND_COLOR, Etude87_KMS_MiniMap::MOVE_ROUTE_COLOR, i)) if rect
end
#--------------------------------------------------------------------------
def line_color(c1, c2, i)
return c2 unless Etude87_KMS_MiniMap::USE_TRANSPARENCY
red = c2.red + (c1.red - c2.red)/$game_system.route.size * ($game_system.route.size - i)
green = c2.green + (c1.green - c2.green)/$game_system.route.size * ($game_system.route.size - i)
blue = c2.blue + (c1.blue - c2.blue)/$game_system.route.size * ($game_system.route.size - i)
alpha = c2.alpha + (c1.alpha - c2.alpha)/$game_system.route.size * ($game_system.route.size - i)
return Color.new(red, green, blue, alpha)
end
#--------------------------------------------------------------------------
end
#==============================================================================
#==============================================================================
class Fog_of_War < Plane
#----------------------------------------------------------------------------
def update_bitmap
bmp = @@bitmap_cache[@id]
unless bmp && !bmp.disposed?
bmp = Bitmap.new(@width * 32, @height * 32)
@@bitmap_cache[@id] = bmp
end
self.bitmap = bmp
return if $game_map.no_fog?
bitmap.entire_fill(Color.new(0,0,0,Theo::FogOpacity))
reveal_fogs
end
#----------------------------------------------------------------------------
def reveal_fogs
for x in 0..@width
for y in 0..@height
next unless ($game_system.drawable[$game_map.map_id][x] && $game_system.drawable[$game_map.map_id][x][y])
width = 32
height = 32
fog_x = x * width
fog_y = y * height
bitmap.clear_rect(fog_x,fog_y,width,height)
if $game_system.drawable[$game_map.map_id][x] && $game_system.drawable[$game_map.map_id][x][y]
t = Etude87_KMS_MiniMap::OUTLINE_THICKNESS
i = $game_system.drawable[$game_map.map_id][x][y]
alpha = 255 / (t + 1) * (t - i)
bitmap.fill_rect(fog_x,fog_y,width,height,Color.new(0,0,0,alpha)) if alpha > 0
end
end
end unless disposed?
end
#----------------------------------------------------------------------------
end