479 lines
14 KiB
Ruby
479 lines
14 KiB
Ruby
#******************************************************************************
|
||
#
|
||
# * <拡張> ピクチャの操作
|
||
#
|
||
# --------------------------------------------------------------------------
|
||
# バージョン : 0.0.1
|
||
# 対 応 : RPGツクールVX Ace : RGSS3
|
||
# 制 作 者 : CACAO
|
||
# 配 布 元 : http://cacaosoft.web.fc2.com/
|
||
# --------------------------------------------------------------------------
|
||
# == 概 要 ==
|
||
#
|
||
# : ピクチャに関する機能を拡張します。
|
||
#
|
||
#
|
||
#******************************************************************************
|
||
|
||
|
||
#==============================================================================
|
||
# ◆ 設定項目
|
||
#==============================================================================
|
||
module CAO
|
||
module PicEx
|
||
|
||
#--------------------------------------------------------------------------
|
||
# ◇ フォント設定
|
||
#--------------------------------------------------------------------------
|
||
FONT_NAME = []
|
||
FONT_NAME[0] = nil
|
||
FONT_NAME[1] = "MS ゴシック"
|
||
FONT_NAME[2] = ["MS 明朝", 28, :OF, :ST]
|
||
FONT_NAME[3] = ["みかちゃん", 18, :OF, :ST]
|
||
FONT_NAME[4] = ["RN-SwingingJohn-PaintedOver", 24, :OF, :ST]
|
||
FONT_NAME[5] = ["MagicRing", 24, :OF, :ST]
|
||
FONT_NAME[6] = ["いろはマルみかみ Mediam", 22, :OF, :ST]
|
||
FONT_NAME[7] = ["eromangasimaji", 22, :OF, :ST]
|
||
|
||
end # module PicEx
|
||
end # module CAO
|
||
|
||
|
||
#/////////////////////////////////////////////////////////////////////////////#
|
||
# #
|
||
# 下記のスクリプトを変更する必要はありません。 #
|
||
# #
|
||
#/////////////////////////////////////////////////////////////////////////////#
|
||
|
||
|
||
class Game_Temp
|
||
#--------------------------------------------------------------------------
|
||
# ● 公開インスタンス変数
|
||
#--------------------------------------------------------------------------
|
||
attr_accessor :picture_writable_id #
|
||
#--------------------------------------------------------------------------
|
||
# ○ オブジェクト初期化
|
||
#--------------------------------------------------------------------------
|
||
alias _cao_picex_initialize initialize
|
||
def initialize
|
||
_cao_picex_initialize
|
||
@picture_writable_id = 0
|
||
end
|
||
end
|
||
|
||
class Game_Interpreter
|
||
#--------------------------------------------------------------------------
|
||
# ○ スクロール文章の表示
|
||
#--------------------------------------------------------------------------
|
||
alias _cao_picex_command_105 command_105
|
||
def command_105
|
||
if $game_temp.picture_writable_id == 0
|
||
_cao_picex_command_105
|
||
else
|
||
pic = screen.pictures[$game_temp.picture_writable_id]
|
||
pic.texts = []
|
||
while next_event_code == 405
|
||
@index += 1
|
||
pic.texts << @list[@index].parameters[0]
|
||
end
|
||
pic.need_refresh = true
|
||
end
|
||
end
|
||
end
|
||
|
||
module Pictures
|
||
class << self
|
||
def list
|
||
if $game_party.in_battle
|
||
return $game_troop.screen.pictures
|
||
else
|
||
return $game_map.screen.pictures
|
||
end
|
||
end
|
||
def [](id)
|
||
return self.list[id]
|
||
end
|
||
def refresh
|
||
self.list.each {|pic| pic.refresh }
|
||
end
|
||
def dissoc(id)
|
||
self.list.each {|pic| pic.dissoc if pic.assocpic_id == id } if id > 0
|
||
end
|
||
def erase
|
||
self.list.each {|pic| pic.erase }
|
||
end
|
||
end
|
||
end
|
||
class Game_Picture
|
||
attr_accessor :mirror
|
||
attr_reader :windowskin
|
||
attr_reader :width
|
||
attr_reader :height
|
||
attr_reader :type
|
||
attr_reader :assocpic_id
|
||
attr_accessor :texts
|
||
attr_accessor :window_padding
|
||
attr_accessor :need_refresh
|
||
alias _cao_picex_initialize initialize
|
||
def initialize(number)
|
||
_cao_picex_initialize(number)
|
||
init_ext
|
||
end
|
||
alias _cao_picex_init_basic init_basic
|
||
def init_basic
|
||
_cao_picex_init_basic
|
||
@mirror = false
|
||
end
|
||
def init_ext
|
||
@type = :picture
|
||
@windowskin = ""
|
||
@width = 0
|
||
@height = 0
|
||
@texts = []
|
||
@window_padding = 8
|
||
@need_refresh = false
|
||
@assocpic_id = 0
|
||
end
|
||
def erase
|
||
Pictures.dissoc(@number)
|
||
init_basic
|
||
init_ext
|
||
@type = :none
|
||
end
|
||
alias _cao_picex_show show
|
||
def show(name, origin, x, y, zoom_x, zoom_y, opacity, blend_type)
|
||
_cao_picex_show(name, origin, x, y, zoom_x, zoom_y, opacity, blend_type)
|
||
init_ext
|
||
end
|
||
def create_contents(width, height)
|
||
@type = :text
|
||
@width = width
|
||
@height = height
|
||
end
|
||
def show_window(*args)
|
||
case args.size
|
||
when 0
|
||
@windowskin = "Window"
|
||
when 1
|
||
@windowskin = args[0]
|
||
when 2
|
||
w = args[0] - @window_padding * 2
|
||
h = args[1] - @window_padding * 2
|
||
create_contents(w, h)
|
||
@windowskin = "Window"
|
||
when 3
|
||
w = args[0] - @window_padding * 2
|
||
h = args[1] - @window_padding * 2
|
||
create_contents(w, h)
|
||
@windowskin = args[2]
|
||
end
|
||
end
|
||
end
|
||
class Game_Picture
|
||
def permitw
|
||
$game_temp.picture_writable_id = self.number
|
||
end
|
||
def bitmap
|
||
set = SceneManager.scene.instance_variable_get(:@spriteset)
|
||
sp = set.instance_variable_get(:@picture_sprites)[self.number]
|
||
return sp && sp.bitmap
|
||
end
|
||
def refresh
|
||
@need_refresh = true
|
||
end
|
||
def reflex(x = nil, y = nil)
|
||
@mirror = !@mirror
|
||
@x = x if x
|
||
@y = y if y
|
||
end
|
||
end
|
||
class Game_Picture
|
||
def x
|
||
return @x if @assocpic_id == 0
|
||
pic = Pictures[@assocpic_id]
|
||
return @x + pic.x if pic.origin == 0
|
||
obj = (pic.width == 0) ? Cache.picture(pic.name) : pic
|
||
return @x + pic.x - (obj.width / 2)
|
||
end
|
||
def y
|
||
return @y if @assocpic_id == 0
|
||
pic = Pictures[@assocpic_id]
|
||
return @y + pic.y if pic.origin == 0
|
||
obj = (pic.height == 0) ? Cache.picture(pic.name) : pic
|
||
return @y + pic.y - (obj.height / 2)
|
||
end
|
||
def assoc(id)
|
||
@assocpic_id = id
|
||
end
|
||
def dissoc
|
||
@assocpic_id = 0
|
||
end
|
||
def zoom(x, y)
|
||
@zoom_x = x
|
||
@zoom_y = y
|
||
end
|
||
end
|
||
class CAO::PicEx::Canvas
|
||
attr_writer :bitmap
|
||
def initialize(picture)
|
||
@bitmap = nil
|
||
@picture = picture
|
||
@rect = Rect.new
|
||
end
|
||
def update
|
||
refresh if @picture.need_refresh
|
||
end
|
||
def reset_font_settings
|
||
@bitmap.font = Font.new
|
||
change_color(text_color(0))
|
||
end
|
||
def calc_line_height(text)
|
||
result = 0
|
||
now = @bitmap.font.size
|
||
text = text.dup
|
||
until text.empty?
|
||
next if text.slice!(0) != "\e"
|
||
case text.slice!(0)
|
||
when '{'
|
||
now += 8
|
||
when '}'
|
||
now -= 8
|
||
when 'S'
|
||
now = obtain_escape_param(text)
|
||
when 'F'
|
||
param = CAO::PicEx::FONT_NAME[obtain_escape_param(text)]
|
||
now = Font.default_size if param == nil || param[1] == nil
|
||
now = param[1] if param && param[1].kind_of?(Integer)
|
||
end
|
||
now = Font.default_size if now == 0
|
||
now = [6, [now, 96].min].max
|
||
result = now if result < now
|
||
end
|
||
result = @bitmap.font.size if result == 0
|
||
return result + 4
|
||
end
|
||
def translucent_alpha
|
||
return 160
|
||
end
|
||
def text_color(n)
|
||
return Cache.system("Window").get_pixel(64 + (n % 8) * 8, 96 + (n / 8) * 8)
|
||
end
|
||
def change_color(color, enabled = true)
|
||
@bitmap.font.color.set(color)
|
||
@bitmap.font.color.alpha = translucent_alpha unless enabled
|
||
end
|
||
def change_size(value)
|
||
if value == 0
|
||
@bitmap.font.size = Font.default_size
|
||
else
|
||
@bitmap.font.size = [6, [value, 96].min].max
|
||
end
|
||
end
|
||
def change_font(id)
|
||
params = CAO::PicEx::FONT_NAME[id]
|
||
case params
|
||
when nil
|
||
reset_font_settings
|
||
when String
|
||
@bitmap.font.name = params
|
||
else
|
||
@bitmap.font.name = params[0] if params[0].kind_of?(String)
|
||
change_size(params[1]) if params[1].kind_of?(Integer)
|
||
@bitmap.font.color = text_color(params[2]) if params[2].kind_of?(Integer)
|
||
@bitmap.font.color = Color.new(*params[2]) if params[2].kind_of?(Array)
|
||
@bitmap.font.out_color=text_color(params[3]) if params[3].kind_of?(Integer)
|
||
@bitmap.font.out_color=Color.new(*params[3]) if params[3].kind_of?(Array)
|
||
params.select {|param| param.kind_of?(Symbol) }.each do |param|
|
||
case param
|
||
when :BT; @bitmap.font.bold = true
|
||
when :BF; @bitmap.font.bold = false
|
||
when :IT; @bitmap.font.italic = true
|
||
when :IF; @bitmap.font.italic = false
|
||
when :OT; @bitmap.font.outline = true
|
||
when :OF; @bitmap.font.outline = false
|
||
when :ST; @bitmap.font.shadow = true
|
||
when :SF; @bitmap.font.shadow = false
|
||
end
|
||
end
|
||
end
|
||
end
|
||
def actor_name(n)
|
||
actor = n >= 1 ? $game_actors[n] : nil
|
||
actor ? actor.name : ""
|
||
end
|
||
def party_member_name(n)
|
||
actor = n >= 1 ? $game_party.members[n - 1] : nil
|
||
actor ? actor.name : ""
|
||
end
|
||
def refresh
|
||
return unless @bitmap && !@bitmap.disposed?
|
||
reset_font_settings
|
||
@bitmap.clear
|
||
@rect.y = 0
|
||
@picture.texts.each do |text|
|
||
text = convert_escape_characters(text)
|
||
@rect.x = 0
|
||
@rect.height = calc_line_height(text)
|
||
process_character(text.slice!(0), text) until text.empty?
|
||
@rect.y += @rect.height
|
||
end
|
||
@picture.need_refresh = false
|
||
end
|
||
def process_character(c, text)
|
||
case c
|
||
when "\e"
|
||
process_escape_character(obtain_escape_code(text), text)
|
||
else
|
||
@rect.width = @bitmap.text_size(c).width + 8
|
||
@bitmap.draw_text(@rect, c)
|
||
@rect.x += @rect.width - 8
|
||
end
|
||
end
|
||
def process_escape_character(code, text)
|
||
case code.upcase
|
||
when 'C'
|
||
change_color(text_color(obtain_escape_param(text)))
|
||
when 'I'
|
||
process_draw_icon(obtain_escape_param(text))
|
||
when 'S'
|
||
change_size(obtain_escape_param(text))
|
||
when '{'
|
||
@bitmap.font.size += 8 if @bitmap.font.size + 8 <= 96
|
||
when '}'
|
||
@bitmap.font.size -= 8 if @bitmap.font.size - 8 >= 6
|
||
when 'X'
|
||
@rect.x += obtain_escape_param(text)
|
||
when 'Y'
|
||
@rect.y += obtain_escape_param(text)
|
||
when 'F'
|
||
change_font(obtain_escape_param(text))
|
||
end
|
||
end
|
||
def convert_escape_characters(text)
|
||
result = text.to_s.clone
|
||
result.gsub!(/\r\n/) { "\n" }
|
||
result.gsub!(/\\/) { "\e" }
|
||
result.gsub!(/\e\e/) { "\\" }
|
||
result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
|
||
result.gsub!(/\eV\[(\d+)\]/i) { $game_variables[$1.to_i] }
|
||
result.gsub!(/\eN\[(\d+)\]/i) { actor_name($1.to_i) }
|
||
result.gsub!(/\eP\[(\d+)\]/i) { party_member_name($1.to_i) }
|
||
result.gsub!(/\e\$/i) { $game_party.gold }
|
||
result.gsub!(/\eG/i) { Vocab::currency_unit }
|
||
return result
|
||
end
|
||
def obtain_escape_code(text)
|
||
text.slice!(/^[\$\.\|\^!><\{\}\\]|^[A-Z]+/i)
|
||
end
|
||
def obtain_escape_param(text)
|
||
text.slice!(/^\[-?\d+\]/)[/-?\d+/].to_i rescue 0
|
||
end
|
||
def draw_icon(icon_index, x, y, enabled = true)
|
||
bitmap = Cache.system("Iconset")
|
||
rect = Rect.new(icon_index % 16 * 24, icon_index / 16 * 24, 24, 24)
|
||
@bitmap.blt(x, y, bitmap, rect, enabled ? 255 : translucent_alpha)
|
||
end
|
||
def process_draw_icon(icon_index)
|
||
draw_icon(icon_index, @rect.x, @rect.y + (@rect.height - 24) / 2)
|
||
@rect.x += 24
|
||
end
|
||
def draw_gauge(x, y, width, height, rate, c1, c2, bg = 19)
|
||
fill_w = (width * rate).to_i
|
||
@bitmap.fill_rect(x, y, width, height, text_color(bg))
|
||
@bitmap.gradient_fill_rect(
|
||
x, y, fill_w, height, text_color(c1), text_color(c2))
|
||
end
|
||
end
|
||
class Sprite_Picture
|
||
alias _cao_picex_initialize initialize
|
||
def initialize(viewport, picture)
|
||
@window = Window.new
|
||
@window.contents.dispose
|
||
@window.viewport = viewport
|
||
@window.visible = false
|
||
@canvas = CAO::PicEx::Canvas.new(picture)
|
||
@window.contents_opacity = 0
|
||
@last_data = {}
|
||
_cao_picex_initialize(viewport, picture)
|
||
end
|
||
def dispose
|
||
if @picture.type == :none
|
||
screen = ($game_party.in_battle ? $game_troop : $game_map).screen
|
||
pictures = screen.instance_variable_get(:@pictures)
|
||
pictures.instance_variable_get(:@data)[@picture.number] = nil
|
||
end
|
||
@window.dispose if @window
|
||
self.bitmap.dispose if self.bitmap
|
||
super
|
||
end
|
||
alias _cao_picex_update update
|
||
def update
|
||
_cao_picex_update
|
||
update_window
|
||
@canvas.update
|
||
end
|
||
def update_bitmap
|
||
case @picture.type
|
||
when :text
|
||
if @picture.width != @last_data[:p_width] ||
|
||
@picture.height != @last_data[:p_height]
|
||
self.bitmap.dispose if @last_data[:type] == :text
|
||
self.bitmap = Bitmap.new(@picture.width, @picture.height)
|
||
@picture.name == ""
|
||
@last_data[:p_width] = @picture.width
|
||
@last_data[:p_height] = @picture.height
|
||
@canvas.bitmap = self.bitmap
|
||
@picture.need_refresh = true
|
||
end
|
||
else
|
||
self.bitmap.dispose if @last_data[:type] == :text
|
||
self.bitmap = Cache.picture(@picture.name)
|
||
@last_data[:p_width] = 0
|
||
@last_data[:p_height] = 0
|
||
end
|
||
@last_data[:type] = @picture.type
|
||
end
|
||
def update_other
|
||
self.opacity = @picture.opacity
|
||
self.blend_type = @picture.blend_type
|
||
self.angle = @picture.angle
|
||
self.mirror = @picture.mirror
|
||
if @picture.windowskin.empty?
|
||
self.tone.set(@picture.tone)
|
||
else
|
||
self.tone.set(0, 0, 0, 0)
|
||
end
|
||
end
|
||
def update_window
|
||
if @picture.windowskin.empty?
|
||
@window.visible = false
|
||
@last_data[:w_width] = 0
|
||
@last_data[:w_height] = 0
|
||
else
|
||
@window.visible = true
|
||
@window.windowskin = Cache.system(@picture.windowskin)
|
||
ww = Integer(self.bitmap.width * @picture.zoom_x / 100.0)
|
||
wh = Integer(self.bitmap.height * @picture.zoom_y / 100.0)
|
||
ww += @picture.window_padding * 2
|
||
wh += @picture.window_padding * 2
|
||
if @last_data[:w_width] != ww || @last_data[:w_height] != wh
|
||
@window.move(@window.x, @window.y, ww, wh)
|
||
@last_data[:w_width] = ww
|
||
@last_data[:w_height] = wh
|
||
end
|
||
@window.x = @picture.x
|
||
@window.y = @picture.y
|
||
@window.z = @picture.number
|
||
if @picture.origin == 0
|
||
self.x += @picture.window_padding
|
||
self.y += @picture.window_padding
|
||
else
|
||
@window.x = @window.x - (@window.width / 2)
|
||
@window.y = @window.y - (@window.height / 2)
|
||
end
|
||
@window.opacity = @picture.opacity
|
||
@window.tone.set(@picture.tone)
|
||
end
|
||
@window.update
|
||
end
|
||
end
|