| 
 
| 赞 | 6 |  
| VIP | 0 |  
| 好人卡 | 0 |  
| 积分 | 10 |  
| 经验 | 0 |  
| 最后登录 | 2024-7-15 |  
| 在线时间 | 90 小时 |  
 Lv3.寻梦者 
	梦石0 星屑1021 在线时间90 小时注册时间2022-12-26帖子102 | 
| 
本帖最后由 爱羊真知己 于 2023-1-24 19:46 编辑
x
加入我们,或者,欢迎回来。您需要 登录 才可以下载或查看,没有帐号?注册会员  
 我在使用Kahs的灯光脚本后,直接使用脚本DataManager.setup_new_game会崩溃。请问怎么避免这个情况呢?
 脚本如下:
 =begin#-------------------------------------------------------------------------------# * [ACE] Khas Awesome Light Effects#-------------------------------------------------------------------------------# * 作者 Khas Arcthunder - arcthunder.site40.net# * 版本: 1.0 EN# * Released on: 17/01/2012##-------------------------------------------------------------------------------# * Terms of Use#-------------------------------------------------------------------------------# When using any Khas script, you agree with the following terms:# 1. You must give credit to Khas;# 2. All Khas scripts are licensed under a Creative Commons license;# 3. All Khas scripts are for non-commercial projects. If you need some script #    for your commercial project (I accept requests for this type of project), # 4. All Khas scripts are for personal use, you can use or edit for your own #    project, but you are not allowed to post any modified version;# 5. You can’t give credit to yourself for posting any Khas script;# 6. If you want to share a Khas script, don’t post the direct download link, #    please redirect the user to arcthunder.site40.net##-------------------------------------------------------------------------------# * 特点#-------------------------------------------------------------------------------# - 真实的灯光# - 灯光不会穿过墙、遮挡物和天花板# - 静态光源# - 动态光源(角色手电)# - 多种效果# - 使用简单 (注释)##-------------------------------------------------------------------------------# * 警告 - 表现效果#-------------------------------------------------------------------------------# 这个脚本对于老人机杀伤力巨大! 本脚本测试于 Core 2 Duo E4500 和 Core i5, # 以下为会影响表现效果的地方:## 1. 地图大小# 本脚本会在地图表面搜索,为了剪切灯光图片.大地图会增加表面的读取,影响动态光源  的表现效果。地图大小不会影响静态灯光的效果。 ## 2. 灯光效果数量# 本脚本在屏幕上绘制,绘制之前还会判断灯光效果是否在屏幕之外。 (在地图外的话脚本将不会绘制超出的灯光效果). 太多灯光将会使游戏卡吨,这是我猜的。 # 3. 灯光效果图片大小# 图片越大,将其绘制成动态光源耗时越长,建议图片最大为200x200像素#-------------------------------------------------------------------------------# * 注意 - 灯光的图片#-------------------------------------------------------------------------------#      1. 图片大小必须是2的倍数 例如: 150x150#      2. 图片长宽相等,例如: 156x156#      3. 图片颜色必须要反色#-------------------------------------------------------------------------------# * 介绍 - 1. 设定你的效果!#-------------------------------  ------------------------------------------------## 189行为灯光设定# 查看默认效果来学习如何使用.##-------------------------------------------------------------------------------# * 介绍 - 2. 使用你设定的效果!#-------------------------------------------------------------------------------# 在事件中添加注释## [light x]## x为效果ID# #-------------------------------------------------------------------------------# * 介绍 - 3. 灯笼效果!#-------------------------------------------------------------------------------# 动态光源(灯笼)默认是不可见的,这需要你使用脚本呼出来显示灯笼T:# # l = $game_map.lantern#    将手灯放入变量 # l.set_graphic(i)##   设定灯笼的图片为i,i为在Graphics/Lights  里的灯笼图片名 # l.set_multiple_graphics(h)# 将灯笼的图片设定为 h, h必须在下面的哈希表中填写有# 结构:## h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"}# # 其中: # "ld" 当用灯笼的角色向下看时的灯光图片# "ll" 当用灯笼的角色向左看时的灯光图片# "lr" 当用灯笼的角色向右看时的灯光图片# "lu" 当用灯笼的角色向上看时的灯光图片## l.change_owner(角色)# 将灯笼的主人交给某一角色. 角色必须为以下:  # $game_player           <= 玩家# self_event             <= 事件# $game_map.events[x]    <= 事件ID## l.set_opacity(o,p)# 设定灯笼不透明度, # o 自身的不透明度;# p 是透明度的变化(闪烁).## l.show# 以上命令都打完后要以此命令作为结束。## l.hide# 设定灯笼不可见.##-------------------------------------------------------------------------------# * 介绍 - 4. 修改画面颜色(黑夜、黄昏效果)!#-------------------------------------------------------------------------------# 在灯光之下、游戏画面之上还需要有一层暗暗的画面来突出灯光效果,这层画面默认的   不透明度为0,你可以用以下脚本来修改画面颜色:## s = $game_map.effect_surface  以这个脚本为开头#  将画面表面设置变量## s.set_color(r,g,b)# 立即改变画面颜色, 其中:# r => 红色含量;# g => 绿色含量;# b => 蓝色含量;## s.set_alpha(a)# 立即改变画面颜色为 a.## s.change_color(时间,r,g,b)# 在一定时间内逐渐改变画面颜色, 其中:# 时间 => 变成黑夜的时间 (帧);# r => 红色含量;# g => 绿色含量;# b => 蓝色含量;## s.change_color(时间,r,g,b,a)# 在一定时间内逐渐改变画面颜色和不透明度, 其中:# 时间 => 变成黑夜的时间 (帧);# r => 红色含量;# g => 绿色含量;# b => 蓝色含量;# a => 不透明度## s.change_alpha(时间,a)# 在一定时间内逐渐改变表面不透明度, where:# 时间 => 变成黑夜的时间 (帧);# a => 不透明度##-------------------------------------------------------------------------------# * 介绍 - 5. 更改画面色调!#-------------------------------------------------------------------------------# 你可以使用事件命令中的更改画面色调,请将204行的"Surface_UE" 设定改为 true.## 如果你决定使用这个功能, 请设置一些细节:# 1. 颜色的数值必须在 0 到 255;# 2. 时间按帧计算;# 3. "灰色" 值将等同于不透明度的数值##-------------------------------------------------------------------------------# * Instructions - 6. 设定你的图块标志!#-------------------------------------------------------------------------------# 为了使效果图片有遮挡效果, 地图有三种遮挡效果: 墙, 障碍和屋顶.#   墙会和真的墙一样有影子, 所以要和障碍与屋顶区分开来.# # #-------------------------------------------------------------------------------# * Setup Part#-------------------------------------------------------------------------------=endmodule Light_Core  Effects = { #  <= 不要碰这个#-------------------------------------------------------------------------------# 效果设定#-------------------------------------------------------------------------------# 格式:X => [图片,不透明度,变化,裁剪图片],   <= 记得在这里加一个逗号!## X => 在事件中使用,效果的ID. # 图片 => 在 Graphics/Lights 文件夹里;# 不透明度 => 灯光效果的不透明度;# 变化 => 灯光效果的不透明度变化(闪烁);# 裁剪图片 => true:裁剪,false:不裁剪;(制造光线被墙壁遮挡的效果) # X => [图片,不透明度,变化,裁剪]  0 => ["light",255,0,true],  1 => ["torch",200,20,true],  2 => ["torch_m",180,30,true],  3 => ["light_s",255,0,true],  #-------------------------------------------------------------------------------# 其他设定#-------------------------------------------------------------------------------   } #  <= 不要碰这个!   # 灯光效果的z轴坐标  Surface_Z = 600   # 是否允许使用事件的更改画面色调命令?  Surface_UE = true   # 屋顶的地形标志  Roof_Tag = 5  # 墙壁的地形标志  Wall_Tag = 6  # 障碍物的地形标志  Block_Tag = 7   # 别动它!  ACC = Math.tan(Math::PI/26)end#-------------------------------------------------------------------------------# Script#-------------------------------------------------------------------------------module Cache  def self.light(filename)    load_bitmap("Graphics/Lights/", filename)  endendmodule Light_Bitcore  include Light_Core  def self.initialize    @@buffer = {}    Effects.values.each { |effect| Light_Bitcore.push(effect[0])}  end  def self::[](key)    return @@buffer[key]  end  def self.push(key)    return if @@buffer.keys.include?(key)    @@buffer[key] = Cache.light(key)  endendLight_Bitcore.initializeclass Light_SSource  attr_reader :real_x  attr_reader :real_y  attr_reader :range  attr_accessor :bitmap  attr_reader :w  attr_reader :h  attr_reader :hs  def initialize(char,bitmap,opacity,plus,hs)    sync(char)    @key = bitmap    @bitmap = Light_Bitcore[@key].clone    @range = @bitmap.width/2    @w = @bitmap.width    @h = @bitmap.height    @mr = @range - 16    @opacity = opacity    @plus = plus    @hs = hs    render if @hs  end  def render    tx = x    ty = y    tsx = x + @range    tsy = y + @range    dr = @range*2    for s in $game_map.surfaces      next if !s.visible?(tsx,tsy) || !s.within?(tx,tx+dr,ty,ty+dr)      s.render_shadow(tx,ty,tsx,tsy,@range,@bitmap)    end  end  def restore    return unless @bitmap.nil?    @bitmap = Light_Bitcore[@key].clone    render if @hs  end  def opacity    @plus == 0 ? @opacity : (@opacity + rand(@plus))  end  def sx    return $game_map.adjust_x(@real_x)*32-@mr  end  def sy    return $game_map.adjust_y(@real_y)*32-@mr  end  def sync(char)    @real_x = char.real_x    @real_y = char.real_y  end  def x    return (@real_x*32 - @mr).to_f  end  def y    return (@real_y*32 - @mr).to_f  end  def dispose    return if @bitmap.nil?    @bitmap.dispose    @bitmap = nil  endendclass Light_DSource < Light_SSource  attr_reader :bitmap  attr_reader :visible  def initialize    @key = nil    @bitmap = nil    @opacity = 255    @plus = 0    @char = $game_player    @visible = false  end  def set_opacity(o,p)    @opacity = o    @plus = p  end  def set_graphic(sb)    dispose    @key = {2=>sb,4=>sb,6=>sb,8=>sb}    Light_Bitcore.push(sb)    @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}    @range = @bitmap[2].width/2    @w = @bitmap[2].width    @h = @bitmap[2].height    @mr = @range - 16  end  def set_multiple_graphics(ba)    dispose    @key = ba    @key.values.each {|key| Light_Bitcore.push(key)}    @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}    @range = @bitmap[2].width/2    @w = @bitmap[2].width    @h = @bitmap[2].height    @mr = @range - 16  end  def get_graphic    return @bitmap[@char.direction].clone  end  def show    return if @bitmap.nil?    @visible = true  end  def hide    @visible = false  end  def restore    return if @key.nil?    @key.values.each {|key| Light_Bitcore.push(key)}    @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}  end  def dispose    return if @bitmap.nil?    @bitmap.values.each { |b| b.dispose }    @bitmap = nil  end  def change_owner(char)    @char = char  end  def render  end  def sx    return $game_map.adjust_x(@char.real_x)*32-@mr  end  def sy    return $game_map.adjust_y(@char.real_y)*32-@mr  end  def x    return (@char.real_x*32 - @mr).to_f  end  def y    return (@char.real_y*32 - @mr).to_f  endendclass Light_Surface  def initialize    @ta = @a = 0    @tr = @r = 255    @tg = @g = 255    @tb = @b = 255    @va = @vr = @vg = @vb = 0.0    @timer = 0  end  def refresh    return if @timer == 0    @a += @va    @r += @vr    @g += @vg    @b += @vb    $game_map.light_surface.opacity = @a    @timer -= 1  end  def change_color(time,r,g,b,a=nil)    r = 0 if r < 0; r = 255 if r > 255    g = 0 if g < 0; g = 255 if g > 255    b = 0 if b < 0; b = 255 if b > 255    unless a.nil?      a = 0 if a < 0; a = 255 if a > 255    end    @timer = time    @tr = 255-r    @tg = 255-g    @tb = 255-b    @va = (a.nil? ? 0 : (a-@a).to_f/@timer)    @vr = (@tr - @r).to_f/@timer    @vg = (@tg - @g).to_f/@timer    @vb = (@tb - @b).to_f/@timer  end  def change_alpha(time,a)    a = 0 if a < 0; a = 255 if a > 255    @timer = time    @ta = a    @vr = @vg = @vb = 0.0    @va = (a-@a).to_f/@timer  end  def set_color(r,g,b)    r = 0 if r < 0; r = 255 if r > 255    g = 0 if g < 0; g = 255 if g > 255    b = 0 if b < 0; b = 255 if b > 255    @tr = @r = 255-r    @tg = @g = 255-g    @tb = @b = 255-b    @va = @vr = @vg = @vb = 0.0    @timer = 0  end  def set_alpha(a)    a = 0 if a < 0; a = 255 if a > 255    @ta = @a = a    $game_map.light_surface.opacity = @a    @va = @vr = @vg = @vb = 0.0    @timer = 0  end  def alpha    return @a  end  def color    return Color.new(@r,@g,@b)  endendclass Game_Map  include Light_Core  attr_accessor :light_surface  attr_accessor :light_sources  attr_accessor :surfaces  attr_accessor :effect_surface  attr_accessor :lantern  alias kbl_setup_events setup_events  alias kbl_initialize initialize  alias kbl_update update  def initialize    kbl_initialize    @effect_surface = Light_Surface.new    @lantern = Light_DSource.new  end  def update(arg)    @effect_surface.refresh if arg    kbl_update(arg)  end  def first_tag(x,y)    tag = tileset.flags[tile_id(x,y,0)] >> 12    return tag > 0 ? tag : 0  end  def setup_events    @light_sources.nil? ? @light_sources = [] : @light_sources.clear    setup_surfaces    merge_surfaces    kbl_setup_events  end  def setup_surfaces    @surfaces = []    for x in 0..(width-1)      for y in 0..(height-1)        tag = first_tag(x,y)        if tag == Wall_Tag          i = tile_id(x,y,0)          if i & 0x02 == 0x02            @surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32)          end          if i & 0x04 == 0x04            @surfaces << Block_WR.new(x*32+31,y*32,x*32+31,y*32+32)            @surfaces << Block_IL.new(x*32+32,y*32,x*32+32,y*32+32)          end          if i & 0x01 == 0x01            @surfaces << Block_IR.new(x*32-1,y*32,x*32-1,y*32+32)            @surfaces << Block_WL.new(x*32,y*32,x*32,y*32+32)          end        elsif tag == Roof_Tag          i = tile_id(x,y,0)          @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if i & 0x02 == 0x02          @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if i & 0x04 == 0x04          @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if i & 0x01 == 0x01        elsif tag == Block_Tag          f = tileset.flags[tile_id(x,y,0)]          @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if f & 0x02 == 0x02          @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if f & 0x04 == 0x04          @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if f & 0x08 == 0x08        end      end    end  end  def merge_surfaces    new_surfaces = []    hs = []; vs = []    ws = []; is = []    for surface in @surfaces      if surface.type & 0x05 == 0        hs << surface      else        if surface.type & 0x010 == 0          vs << surface        else          if surface.type & 0x08 == 0            ws << surface          else            is << surface          end        end      end    end    for surface in hs      surface.ready ? next : surface.ready = true      for s in hs        next if s.ready || s.y1 != surface.y1 || surface.type != s.type        if s.x2 == surface.x1          surface.x1 = s.x1          s.trash = true          s.ready = true          surface.ready = false        elsif s.x1 == surface.x2          surface.x2 = s.x2          s.trash = true          s.ready = true          surface.ready = false        end      end    end    hs.each { |s| @surfaces.delete(s) if s.trash}    for surface in vs      surface.ready ? next : surface.ready      for s in vs        next if s.ready || s.x1 != surface.x1        if s.y2 == surface.y1          surface.y1 = s.y1          s.trash = true          s.ready = true          surface.ready = false        elsif s.y1 == surface.y2          surface.y2 = s.y2          s.trash = true          s.ready = true          surface.ready = false        end      end    end    vs.each { |s| @surfaces.delete(s) if s.trash}    for surface in ws      surface.ready ? next : surface.ready      for s in ws        next if s.ready || s.x1 != surface.x1        if s.y2 == surface.y1          surface.y1 = s.y1          s.trash = true          s.ready = true          surface.ready = false        elsif s.y1 == surface.y2          surface.y2 = s.y2          s.trash = true          s.ready = true          surface.ready = false        end      end    end    ws.each { |s| @surfaces.delete(s) if s.trash}    for surface in is      surface.ready ? next : surface.ready      for s in is        next if s.ready || s.x1 != surface.x1        if s.y2 == surface.y1          surface.y1 = s.y1          s.trash = true          s.ready = true          surface.ready = false        elsif s.y1 == surface.y2          surface.y2 = s.y2          s.trash = true          s.ready = true          surface.ready = false        end      end    end    is.each { |s| @surfaces.delete(s) if s.trash}  endendclass Game_Event < Game_Character  alias kbl_initialize initialize  alias kbl_setup_page setup_page  def initialize(m,e)    @light = nil    kbl_initialize(m,e)  end  def setup_page(np)    kbl_setup_page(np)    setup_light(np.nil?)  end  def setup_light(dispose)    unless @light.nil?      $game_map.light_sources.delete(self)      @light.dispose      @light = nil    end    unless dispose && @list.nil?      for command in @list        if command.code == 108 && command.parameters[0].include?("[light")          command.parameters[0].scan(/\[light ([0.0-9.9]+)\]/)          effect = Light_Core::Effects[$1.to_i]          @light = Light_SSource.new(self,effect[0],effect[1],effect[2],effect[3])          $game_map.light_sources << self          return        end      end    end  end  def draw_light    sx = @light.sx    sy = @light.sy    w = @light.w    h = @light.h    return if sx > 544 && sy > 416 && sx + w < 0 && sy + h < 0    $game_map.light_surface.bitmap.blt(sx,sy,@light.bitmap,Rect.new(0,0,w,h),@light.opacity)  end  def dispose_light    @light.dispose  end  def restore_light    @light.restore  endendif Light_Core::Surface_UE  class Game_Interpreter    def command_223      $game_map.effect_surface.change_color(@params[1],@params[0].red,@params[0].green,@params[0].blue,@params[0].gray)      wait(@params[1]) if @params[2]    end  endendclass Game_Interpreter  def self_event    return $game_map.events[@event_id]  endendclass Block_Surface  include Light_Core  attr_accessor :x1  attr_accessor :y1  attr_accessor :x2  attr_accessor :y2  attr_accessor :ready  attr_accessor :trash  def initialize(x1,y1,x2,y2)    @x1 = x1    @y1 = y1    @x2 = x2    @y2 = y2    @ready = false    @trash = false  end  def within?(min_x,max_x,min_y,max_y)    return @x2 > min_x && @x1 < max_x && @y2 > min_y && @y1 < max_y  endendclass Block_SL < Block_Surface  attr_reader :type  def initialize(x1,y1,x2,y2)    super(x1,y1,x2,y2)    @type = 0x01  end  def visible?(sx,sy)    return sx < @x1   end  def render_shadow(phx,phy,sx,sy,range,bitmap)    @m1 = (@y1-sy)/(@x1-sx)    @n1 = sy - @m1*sx    @m2 = (@y2-sy)/(@x2-sx)    @n2 = sy - @m2*sx    for x in @x1..(sx+range)      init = shadow_iy(x)      bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)    end  end  def shadow_iy(x)    return @m1*x+@n1  end  def shadow_fy(x)    return @m2*x+@n2  endendclass Block_SR < Block_Surface  attr_reader :type  def initialize(x1,y1,x2,y2)    super(x1,y1,x2,y2)    @type = 0x04  end  def visible?(sx,sy)    return sx > @x1   end  def render_shadow(phx,phy,sx,sy,range,bitmap)    @m1 = (@y1-sy)/(@x1-sx)    @n1 = sy - @m1*sx    @m2 = (@y2-sy)/(@x2-sx)    @n2 = sy - @m2*sx    for x in (sx-range).to_i..@x1      init = shadow_iy(x)      bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)    end  end  def shadow_iy(x)    return @m1*x+@n1  end  def shadow_fy(x)    return @m2*x+@n2  endendclass Block_IL < Block_Surface  attr_reader :type  def initialize(x1,y1,x2,y2)    super(x1,y1,x2,y2)    @type = 0x019  end  def visible?(sx,sy)    return sx < @x1 && sy > @y1  end  def render_shadow(phx,phy,sx,sy,range,bitmap)    @m1 = (@y1-sy)/(@x1-sx)    @n1 = @y1 - @m1*@x1    @m2 = (@y2-sy)/(@x2-sx)    @m2 = 0 if @m2 > 0    @n2 = @y2 - @m2*@x2    for x in @x1..(sx+range)      init = shadow_iy(x).floor      bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)    end  end  def shadow_iy(x)    return @m1*x+@n1  end  def shadow_fy(x)    return @m2*x+@n2  endendclass Block_IR < Block_Surface  attr_reader :type  def initialize(x1,y1,x2,y2)    super(x1,y1,x2,y2)    @type = 0x01c  end  def visible?(sx,sy)    return sx > @x1 && sy > @y1  end  def render_shadow(phx,phy,sx,sy,range,bitmap)    @m1 = (@y1-sy)/(@x1-sx)    @n1 = @y1 - @m1*@x1    @m2 = (@y2-sy)/(@x2-sx)    @m2 = 0 if @m2 < 0    @n2 = @y2 - @m2*@x2    for x in (sx-range).to_i..@x1      init = shadow_iy(x).floor      bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)    end  end  def shadow_iy(x)    return @m1*x+@n1  end  def shadow_fy(x)    return @m2*x+@n2  endendclass Block_WL < Block_Surface  attr_reader :type  def initialize(x1,y1,x2,y2)    super(x1,y1,x2,y2)    @type = 0x011  end  def visible?(sx,sy)    return sx < @x1 && sy < @y2  end  def render_shadow(phx,phy,sx,sy,range,bitmap)    @m1 = (@y1-sy)/(@x1-sx)    @n1 = sy - @m1*sx    @m2 = (@y2-sy)/(@x2-sx)    @n2 = sy - @m2*sx    for x in @x1..(sx+range)      init = shadow_iy(x)      bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)    end  end  def shadow_iy(x)    return @m1*x+@n1  end  def shadow_fy(x)    return @m2*x+@n2  endendclass Block_WR < Block_Surface  attr_reader :type  def initialize(x1,y1,x2,y2)    super(x1,y1,x2,y2)    @type = 0x014  end  def visible?(sx,sy)    return sx > @x1 && sy < @y2  end  def render_shadow(phx,phy,sx,sy,range,bitmap)    @m1 = (@y1-sy)/(@x1-sx)    @n1 = sy - @m1*sx    @m2 = (@y2-sy)/(@x2-sx)    @n2 = sy - @m2*sx    for x in (sx-range).to_i..@x1      init = shadow_iy(x)      bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)    end  end  def shadow_iy(x)    return @m1*x+@n1  end  def shadow_fy(x)    return @m2*x+@n2  endendclass Block_SU < Block_Surface  attr_reader :type  def initialize(x1,y1,x2,y2)    super(x1,y1,x2,y2)    @type = 0x02  end  def visible?(sx,sy)    return sy < @y1  end  def render_shadow(phx,phy,sx,sy,range,bitmap)    if @x1 == sx      @m1 = nil    else      @m1 = (@y1-sy)/(@x1-sx)      @m1 += ACC if @m1 < -ACC      @n1 = @y1 - @m1*@x1    end    if @x2 == sx      @m2 = nil    else      @m2 = (@y2-sy)/(@x2-sx)      @n2 = sy - @m2*sx    end    for y in @y1..(sy+range)      init = shadow_ix(y)      bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)    end  end  def shadow_ix(y)    return @m1.nil? ? @x1 : (y-@n1)/@m1  end  def shadow_fx(y)    return @m2.nil? ? @x2 : (y-@n2)/@m2  endendclass Block_SD < Block_Surface  attr_reader :type  def initialize(x1,y1,x2,y2)    super(x1,y1,x2,y2)    @type = 0x08  end  def visible?(sx,sy)    return sy > @y1  end  def render_shadow(phx,phy,sx,sy,range,bitmap)    if @x1 == sx      @m1 = nil    else      @m1 = (@y1-sy)/(@x1-sx)      @m1 -= ACC if @m1 > ACC      @n1 = sy - @m1*sx    end    if x2 == sx      @m2 = nil    else      @m2 = (@y2-sy)/(@x2-sx)      @n2 = sy - @m2*sx    end    for y in (sy-range).to_i..@y1      init = shadow_ix(y)      bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)    end  end  def shadow_ix(y)    return @m1.nil? ? @x1 : (y-@n1)/@m1  end  def shadow_fx(y)    return @m2.nil? ? @x2 : (y-@n2)/@m2  endendclass Spriteset_Map  include Light_Core  alias kbl_initialize initialize  alias kbl_update update  alias kbl_dispose dispose  def initialize    setup_lights    kbl_initialize  end  def update    kbl_update    update_lights  end  def dispose    kbl_dispose    dispose_lights  end  def dispose_lights    $game_map.lantern.dispose    $game_map.light_sources.each { |source| source.dispose_light }    $game_map.light_surface.bitmap.dispose    $game_map.light_surface.dispose    $game_map.light_surface = nil  end  def update_lights    $game_map.light_surface.bitmap.clear    $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color)    $game_map.light_sources.each { |source| source.draw_light }    return unless $game_map.lantern.visible    @btr = $game_map.lantern.get_graphic    x = $game_map.lantern.x    y = $game_map.lantern.y    r = $game_map.lantern.range    sx = x + r    sy = y + r    dr = r*2    $game_map.surfaces.each { |s| s.render_shadow(x,y,sx,sy,r,@btr) if s.visible?(sx,sy) && s.within?(x,x+dr,y,y+dr) }    $game_map.light_surface.bitmap.blt($game_map.lantern.sx,$game_map.lantern.sy,@btr,Rect.new(0,0,dr,dr),$game_map.lantern.opacity)  end  def setup_lights    @btr = nil    $game_map.lantern.restore    $game_map.light_sources.each { |source| source.restore_light }    $game_map.light_surface = Sprite.new    $game_map.light_surface.bitmap = Bitmap.new(544,416)    $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color)    $game_map.light_surface.blend_type = 2    $game_map.light_surface.opacity = $game_map.effect_surface.alpha    $game_map.light_surface.z = Surface_Z  endend
=begin 
#------------------------------------------------------------------------------- 
# * [ACE] Khas Awesome Light Effects 
#------------------------------------------------------------------------------- 
# * 作者 Khas Arcthunder - arcthunder.site40.net 
# * 版本: 1.0 EN 
# * Released on: 17/01/2012 
# 
#------------------------------------------------------------------------------- 
# * Terms of Use 
#------------------------------------------------------------------------------- 
# When using any Khas script, you agree with the following terms: 
# 1. You must give credit to Khas; 
# 2. All Khas scripts are licensed under a Creative Commons license; 
# 3. All Khas scripts are for non-commercial projects. If you need some script  
#    for your commercial project (I accept requests for this type of project),  
# 4. All Khas scripts are for personal use, you can use or edit for your own  
#    project, but you are not allowed to post any modified version; 
# 5. You can’t give credit to yourself for posting any Khas script; 
# 6. If you want to share a Khas script, don’t post the direct download link,  
#    please redirect the user to arcthunder.site40.net 
# 
#------------------------------------------------------------------------------- 
# * 特点 
#------------------------------------------------------------------------------- 
# - 真实的灯光 
# - 灯光不会穿过墙、遮挡物和天花板 
# - 静态光源 
# - 动态光源(角色手电) 
# - 多种效果 
# - 使用简单 (注释) 
# 
#------------------------------------------------------------------------------- 
# * 警告 - 表现效果 
#------------------------------------------------------------------------------- 
# 这个脚本对于老人机杀伤力巨大! 本脚本测试于 Core 2 Duo E4500 和 Core i5,  
# 以下为会影响表现效果的地方: 
# 
# 1. 地图大小 
# 本脚本会在地图表面搜索,为了剪切灯光图片.大地图会增加表面的读取,影响动态光源 
  的表现效果。地图大小不会影响静态灯光的效果。 
  
# 
# 2. 灯光效果数量 
# 本脚本在屏幕上绘制,绘制之前还会判断灯光效果是否在屏幕之外。 
 (在地图外的话脚本将不会绘制超出的灯光效果). 太多灯光将会使游戏卡吨,这是我猜的。 
  
# 3. 灯光效果图片大小 
# 图片越大,将其绘制成动态光源耗时越长,建议图片最大为200x200像素 
#------------------------------------------------------------------------------- 
# * 注意 - 灯光的图片 
#------------------------------------------------------------------------------- 
#      1. 图片大小必须是2的倍数 例如: 150x150 
#      2. 图片长宽相等,例如: 156x156 
#      3. 图片颜色必须要反色 
#------------------------------------------------------------------------------- 
# * 介绍 - 1. 设定你的效果! 
#-------------------------------  ------------------------------------------------ 
# 
# 189行为灯光设定 
# 查看默认效果来学习如何使用. 
# 
#------------------------------------------------------------------------------- 
# * 介绍 - 2. 使用你设定的效果! 
#------------------------------------------------------------------------------- 
# 在事件中添加注释 
# 
# [light x] 
# 
# x为效果ID 
#  
#------------------------------------------------------------------------------- 
# * 介绍 - 3. 灯笼效果! 
#------------------------------------------------------------------------------- 
# 动态光源(灯笼)默认是不可见的,这需要你使用脚本呼出来显示灯笼T: 
#  
# l = $game_map.lantern 
#  
   将手灯放入变量 
  
# l.set_graphic(i) 
# 
#   设定灯笼的图片为i,i为在Graphics/Lights  里的灯笼图片名 
  
# l.set_multiple_graphics(h) 
# 将灯笼的图片设定为 h, h必须在下面的哈希表中填写有 
# 结构: 
# 
# h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"} 
#  
# 其中:  
# "ld" 当用灯笼的角色向下看时的灯光图片 
# "ll" 当用灯笼的角色向左看时的灯光图片 
# "lr" 当用灯笼的角色向右看时的灯光图片 
# "lu" 当用灯笼的角色向上看时的灯光图片 
# 
# l.change_owner(角色) 
# 将灯笼的主人交给某一角色. 角色必须为以下: 
   
# $game_player           <= 玩家 
# self_event             <= 事件 
# $game_map.events[x]    <= 事件ID 
# 
# l.set_opacity(o,p) 
# 设定灯笼不透明度,  
# o 自身的不透明度; 
# p 是透明度的变化(闪烁). 
# 
# l.show 
# 以上命令都打完后要以此命令作为结束。 
# 
# l.hide 
# 设定灯笼不可见. 
# 
#------------------------------------------------------------------------------- 
# * 介绍 - 4. 修改画面颜色(黑夜、黄昏效果)! 
#------------------------------------------------------------------------------- 
# 在灯光之下、游戏画面之上还需要有一层暗暗的画面来突出灯光效果,这层画面默认的 
   不透明度为0,你可以用以下脚本来修改画面颜色: 
# 
# s = $game_map.effect_surface  以这个脚本为开头 
#  将画面表面设置变量 
# 
# s.set_color(r,g,b) 
# 立即改变画面颜色, 其中: 
# r => 红色含量; 
# g => 绿色含量; 
# b => 蓝色含量; 
# 
# s.set_alpha(a) 
# 立即改变画面颜色为 a. 
# 
# s.change_color(时间,r,g,b) 
# 在一定时间内逐渐改变画面颜色, 其中: 
# 时间 => 变成黑夜的时间 (帧); 
# r => 红色含量; 
# g => 绿色含量; 
# b => 蓝色含量; 
# 
# s.change_color(时间,r,g,b,a) 
# 在一定时间内逐渐改变画面颜色和不透明度, 其中: 
# 时间 => 变成黑夜的时间 (帧); 
# r => 红色含量; 
# g => 绿色含量; 
# b => 蓝色含量; 
# a => 不透明度 
# 
# s.change_alpha(时间,a) 
# 在一定时间内逐渐改变表面不透明度, where: 
# 时间 => 变成黑夜的时间 (帧); 
# a => 不透明度 
# 
#------------------------------------------------------------------------------- 
# * 介绍 - 5. 更改画面色调! 
#------------------------------------------------------------------------------- 
# 你可以使用事件命令中的更改画面色调,请将204行的"Surface_UE" 设定改为 true. 
# 
# 如果你决定使用这个功能, 请设置一些细节: 
# 1. 颜色的数值必须在 0 到 255; 
# 2. 时间按帧计算; 
# 3. "灰色" 值将等同于不透明度的数值 
# 
#------------------------------------------------------------------------------- 
# * Instructions - 6. 设定你的图块标志! 
#------------------------------------------------------------------------------- 
# 为了使效果图片有遮挡效果, 地图有三种遮挡效果: 墙, 障碍和屋顶. 
#   墙会和真的墙一样有影子, 所以要和障碍与屋顶区分开来. 
#  
#  
#------------------------------------------------------------------------------- 
# * Setup Part 
#------------------------------------------------------------------------------- 
=end 
module Light_Core 
  Effects = { #  <= 不要碰这个 
#------------------------------------------------------------------------------- 
# 效果设定 
#------------------------------------------------------------------------------- 
# 格式:X => [图片,不透明度,变化,裁剪图片],   <= 记得在这里加一个逗号! 
# 
# X => 在事件中使用,效果的ID.  
# 图片 => 在 Graphics/Lights 文件夹里; 
# 不透明度 => 灯光效果的不透明度; 
# 变化 => 灯光效果的不透明度变化(闪烁); 
# 裁剪图片 => true:裁剪,false:不裁剪;(制造光线被墙壁遮挡的效果) 
  
# X => [图片,不透明度,变化,裁剪] 
  0 => ["light",255,0,true], 
  1 => ["torch",200,20,true], 
  2 => ["torch_m",180,30,true], 
  3 => ["light_s",255,0,true], 
  
  
#------------------------------------------------------------------------------- 
# 其他设定 
#-------------------------------------------------------------------------------  
  } #  <= 不要碰这个! 
  
  # 灯光效果的z轴坐标 
  Surface_Z = 600 
  
  # 是否允许使用事件的更改画面色调命令? 
  Surface_UE = true 
  
  # 屋顶的地形标志 
  Roof_Tag = 5 
  # 墙壁的地形标志 
  Wall_Tag = 6 
  # 障碍物的地形标志 
  Block_Tag = 7 
  
  # 别动它! 
  ACC = Math.tan(Math::PI/26) 
end 
#------------------------------------------------------------------------------- 
# Script 
#------------------------------------------------------------------------------- 
module Cache 
  def self.light(filename) 
    load_bitmap("Graphics/Lights/", filename) 
  end 
end 
module Light_Bitcore 
  include Light_Core 
  def self.initialize 
    @@buffer = {} 
    Effects.values.each { |effect| Light_Bitcore.push(effect[0])} 
  end 
  def self::[](key) 
    return @@buffer[key] 
  end 
  def self.push(key) 
    return if @@buffer.keys.include?(key) 
    @@buffer[key] = Cache.light(key) 
  end 
end 
Light_Bitcore.initialize 
class Light_SSource 
  attr_reader :real_x 
  attr_reader :real_y 
  attr_reader :range 
  attr_accessor :bitmap 
  attr_reader :w 
  attr_reader :h 
  attr_reader :hs 
  def initialize(char,bitmap,opacity,plus,hs) 
    sync(char) 
    @key = bitmap 
    @bitmap = Light_Bitcore[@key].clone 
    @range = @bitmap.width/2 
    @w = @bitmap.width 
    @h = @bitmap.height 
    @mr = @range - 16 
    @opacity = opacity 
    @plus = plus 
    @hs = hs 
    render if @hs 
  end 
  def render 
    tx = x 
    ty = y 
    tsx = x + @range 
    tsy = y + @range 
    dr = @range*2 
    for s in $game_map.surfaces 
      next if !s.visible?(tsx,tsy) || !s.within?(tx,tx+dr,ty,ty+dr) 
      s.render_shadow(tx,ty,tsx,tsy,@range,@bitmap) 
    end 
  end 
  def restore 
    return unless @bitmap.nil? 
    @bitmap = Light_Bitcore[@key].clone 
    render if @hs 
  end 
  def opacity 
    @plus == 0 ? @opacity : (@opacity + rand(@plus)) 
  end 
  def sx 
    return $game_map.adjust_x(@real_x)*32-@mr 
  end 
  def sy 
    return $game_map.adjust_y(@real_y)*32-@mr 
  end 
  def sync(char) 
    @real_x = char.real_x 
    @real_y = char.real_y 
  end 
  def x 
    return (@real_x*32 - @mr).to_f 
  end 
  def y 
    return (@real_y*32 - @mr).to_f 
  end 
  def dispose 
    return if @bitmap.nil? 
    @bitmap.dispose 
    @bitmap = nil 
  end 
end 
class Light_DSource < Light_SSource 
  attr_reader :bitmap 
  attr_reader :visible 
  def initialize 
    @key = nil 
    @bitmap = nil 
    @opacity = 255 
    @plus = 0 
    @char = $game_player 
    @visible = false 
  end 
  def set_opacity(o,p) 
    @opacity = o 
    @plus = p 
  end 
  def set_graphic(sb) 
    dispose 
    @key = {2=>sb,4=>sb,6=>sb,8=>sb} 
    Light_Bitcore.push(sb) 
    @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone} 
    @range = @bitmap[2].width/2 
    @w = @bitmap[2].width 
    @h = @bitmap[2].height 
    @mr = @range - 16 
  end 
  def set_multiple_graphics(ba) 
    dispose 
    @key = ba 
    @key.values.each {|key| Light_Bitcore.push(key)} 
    @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone} 
    @range = @bitmap[2].width/2 
    @w = @bitmap[2].width 
    @h = @bitmap[2].height 
    @mr = @range - 16 
  end 
  def get_graphic 
    return @bitmap[@char.direction].clone 
  end 
  def show 
    return if @bitmap.nil? 
    @visible = true 
  end 
  def hide 
    @visible = false 
  end 
  def restore 
    return if @key.nil? 
    @key.values.each {|key| Light_Bitcore.push(key)} 
    @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone} 
  end 
  def dispose 
    return if @bitmap.nil? 
    @bitmap.values.each { |b| b.dispose } 
    @bitmap = nil 
  end 
  def change_owner(char) 
    @char = char 
  end 
  def render 
  end 
  def sx 
    return $game_map.adjust_x(@char.real_x)*32-@mr 
  end 
  def sy 
    return $game_map.adjust_y(@char.real_y)*32-@mr 
  end 
  def x 
    return (@char.real_x*32 - @mr).to_f 
  end 
  def y 
    return (@char.real_y*32 - @mr).to_f 
  end 
end 
class Light_Surface 
  def initialize 
    @ta = @a = 0 
    @tr = @r = 255 
    @tg = @g = 255 
    @tb = @b = 255 
    @va = @vr = @vg = @vb = 0.0 
    @timer = 0 
  end 
  def refresh 
    return if @timer == 0 
    @a += @va 
    @r += @vr 
    @g += @vg 
    @b += @vb 
    $game_map.light_surface.opacity = @a 
    @timer -= 1 
  end 
  def change_color(time,r,g,b,a=nil) 
    r = 0 if r < 0; r = 255 if r > 255 
    g = 0 if g < 0; g = 255 if g > 255 
    b = 0 if b < 0; b = 255 if b > 255 
    unless a.nil? 
      a = 0 if a < 0; a = 255 if a > 255 
    end 
    @timer = time 
    @tr = 255-r 
    @tg = 255-g 
    @tb = 255-b 
    @va = (a.nil? ? 0 : (a-@a).to_f/@timer) 
    @vr = (@tr - @r).to_f/@timer 
    @vg = (@tg - @g).to_f/@timer 
    @vb = (@tb - @b).to_f/@timer 
  end 
  def change_alpha(time,a) 
    a = 0 if a < 0; a = 255 if a > 255 
    @timer = time 
    @ta = a 
    @vr = @vg = @vb = 0.0 
    @va = (a-@a).to_f/@timer 
  end 
  def set_color(r,g,b) 
    r = 0 if r < 0; r = 255 if r > 255 
    g = 0 if g < 0; g = 255 if g > 255 
    b = 0 if b < 0; b = 255 if b > 255 
    @tr = @r = 255-r 
    @tg = @g = 255-g 
    @tb = @b = 255-b 
    @va = @vr = @vg = @vb = 0.0 
    @timer = 0 
  end 
  def set_alpha(a) 
    a = 0 if a < 0; a = 255 if a > 255 
    @ta = @a = a 
    $game_map.light_surface.opacity = @a 
    @va = @vr = @vg = @vb = 0.0 
    @timer = 0 
  end 
  def alpha 
    return @a 
  end 
  def color 
    return Color.new(@r,@g,@b) 
  end 
end 
class Game_Map 
  include Light_Core 
  attr_accessor :light_surface 
  attr_accessor :light_sources 
  attr_accessor :surfaces 
  attr_accessor :effect_surface 
  attr_accessor :lantern 
  alias kbl_setup_events setup_events 
  alias kbl_initialize initialize 
  alias kbl_update update 
  def initialize 
    kbl_initialize 
    @effect_surface = Light_Surface.new 
    @lantern = Light_DSource.new 
  end 
  def update(arg) 
    @effect_surface.refresh if arg 
    kbl_update(arg) 
  end 
  def first_tag(x,y) 
    tag = tileset.flags[tile_id(x,y,0)] >> 12 
    return tag > 0 ? tag : 0 
  end 
  def setup_events 
    @light_sources.nil? ? @light_sources = [] : @light_sources.clear 
    setup_surfaces 
    merge_surfaces 
    kbl_setup_events 
  end 
  def setup_surfaces 
    @surfaces = [] 
    for x in 0..(width-1) 
      for y in 0..(height-1) 
        tag = first_tag(x,y) 
        if tag == Wall_Tag 
          i = tile_id(x,y,0) 
          if i & 0x02 == 0x02 
            @surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32) 
          end 
          if i & 0x04 == 0x04 
            @surfaces << Block_WR.new(x*32+31,y*32,x*32+31,y*32+32) 
            @surfaces << Block_IL.new(x*32+32,y*32,x*32+32,y*32+32) 
          end 
          if i & 0x01 == 0x01 
            @surfaces << Block_IR.new(x*32-1,y*32,x*32-1,y*32+32) 
            @surfaces << Block_WL.new(x*32,y*32,x*32,y*32+32) 
          end 
        elsif tag == Roof_Tag 
          i = tile_id(x,y,0) 
          @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if i & 0x02 == 0x02 
          @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if i & 0x04 == 0x04 
          @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if i & 0x01 == 0x01 
        elsif tag == Block_Tag 
          f = tileset.flags[tile_id(x,y,0)] 
          @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if f & 0x02 == 0x02 
          @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if f & 0x04 == 0x04 
          @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if f & 0x08 == 0x08 
        end 
      end 
    end 
  end 
  def merge_surfaces 
    new_surfaces = [] 
    hs = []; vs = [] 
    ws = []; is = [] 
    for surface in @surfaces 
      if surface.type & 0x05 == 0 
        hs << surface 
      else 
        if surface.type & 0x010 == 0 
          vs << surface 
        else 
          if surface.type & 0x08 == 0 
            ws << surface 
          else 
            is << surface 
          end 
        end 
      end 
    end 
    for surface in hs 
      surface.ready ? next : surface.ready = true 
      for s in hs 
        next if s.ready || s.y1 != surface.y1 || surface.type != s.type 
        if s.x2 == surface.x1 
          surface.x1 = s.x1 
          s.trash = true 
          s.ready = true 
          surface.ready = false 
        elsif s.x1 == surface.x2 
          surface.x2 = s.x2 
          s.trash = true 
          s.ready = true 
          surface.ready = false 
        end 
      end 
    end 
    hs.each { |s| @surfaces.delete(s) if s.trash} 
    for surface in vs 
      surface.ready ? next : surface.ready 
      for s in vs 
        next if s.ready || s.x1 != surface.x1 
        if s.y2 == surface.y1 
          surface.y1 = s.y1 
          s.trash = true 
          s.ready = true 
          surface.ready = false 
        elsif s.y1 == surface.y2 
          surface.y2 = s.y2 
          s.trash = true 
          s.ready = true 
          surface.ready = false 
        end 
      end 
    end 
    vs.each { |s| @surfaces.delete(s) if s.trash} 
    for surface in ws 
      surface.ready ? next : surface.ready 
      for s in ws 
        next if s.ready || s.x1 != surface.x1 
        if s.y2 == surface.y1 
          surface.y1 = s.y1 
          s.trash = true 
          s.ready = true 
          surface.ready = false 
        elsif s.y1 == surface.y2 
          surface.y2 = s.y2 
          s.trash = true 
          s.ready = true 
          surface.ready = false 
        end 
      end 
    end 
    ws.each { |s| @surfaces.delete(s) if s.trash} 
    for surface in is 
      surface.ready ? next : surface.ready 
      for s in is 
        next if s.ready || s.x1 != surface.x1 
        if s.y2 == surface.y1 
          surface.y1 = s.y1 
          s.trash = true 
          s.ready = true 
          surface.ready = false 
        elsif s.y1 == surface.y2 
          surface.y2 = s.y2 
          s.trash = true 
          s.ready = true 
          surface.ready = false 
        end 
      end 
    end 
    is.each { |s| @surfaces.delete(s) if s.trash} 
  end 
end 
class Game_Event < Game_Character 
  alias kbl_initialize initialize 
  alias kbl_setup_page setup_page 
  def initialize(m,e) 
    @light = nil 
    kbl_initialize(m,e) 
  end 
  def setup_page(np) 
    kbl_setup_page(np) 
    setup_light(np.nil?) 
  end 
  def setup_light(dispose) 
    unless @light.nil? 
      $game_map.light_sources.delete(self) 
      @light.dispose 
      @light = nil 
    end 
    unless dispose && @list.nil? 
      for command in @list 
        if command.code == 108 && command.parameters[0].include?("[light") 
          command.parameters[0].scan(/\[light ([0.0-9.9]+)\]/) 
          effect = Light_Core::Effects[$1.to_i] 
          @light = Light_SSource.new(self,effect[0],effect[1],effect[2],effect[3]) 
          $game_map.light_sources << self 
          return 
        end 
      end 
    end 
  end 
  def draw_light 
    sx = @light.sx 
    sy = @light.sy 
    w = @light.w 
    h = @light.h 
    return if sx > 544 && sy > 416 && sx + w < 0 && sy + h < 0 
    $game_map.light_surface.bitmap.blt(sx,sy,@light.bitmap,Rect.new(0,0,w,h),@light.opacity) 
  end 
  def dispose_light 
    @light.dispose 
  end 
  def restore_light 
    @light.restore 
  end 
end 
if Light_Core::Surface_UE 
  class Game_Interpreter 
    def command_223 
      $game_map.effect_surface.change_color(@params[1],@params[0].red,@params[0].green,@params[0].blue,@params[0].gray) 
      wait(@params[1]) if @params[2] 
    end 
  end 
end 
class Game_Interpreter 
  def self_event 
    return $game_map.events[@event_id] 
  end 
end 
class Block_Surface 
  include Light_Core 
  attr_accessor :x1 
  attr_accessor :y1 
  attr_accessor :x2 
  attr_accessor :y2 
  attr_accessor :ready 
  attr_accessor :trash 
  def initialize(x1,y1,x2,y2) 
    @x1 = x1 
    @y1 = y1 
    @x2 = x2 
    @y2 = y2 
    @ready = false 
    @trash = false 
  end 
  def within?(min_x,max_x,min_y,max_y) 
    return @x2 > min_x && @x1 < max_x && @y2 > min_y && @y1 < max_y 
  end 
end 
class Block_SL < Block_Surface 
  attr_reader :type 
  def initialize(x1,y1,x2,y2) 
    super(x1,y1,x2,y2) 
    @type = 0x01 
  end 
  def visible?(sx,sy) 
    return sx < @x1  
  end 
  def render_shadow(phx,phy,sx,sy,range,bitmap) 
    @m1 = (@y1-sy)/(@x1-sx) 
    @n1 = sy - @m1*sx 
    @m2 = (@y2-sy)/(@x2-sx) 
    @n2 = sy - @m2*sx 
    for x in @x1..(sx+range) 
      init = shadow_iy(x) 
      bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3) 
    end 
  end 
  def shadow_iy(x) 
    return @m1*x+@n1 
  end 
  def shadow_fy(x) 
    return @m2*x+@n2 
  end 
end 
class Block_SR < Block_Surface 
  attr_reader :type 
  def initialize(x1,y1,x2,y2) 
    super(x1,y1,x2,y2) 
    @type = 0x04 
  end 
  def visible?(sx,sy) 
    return sx > @x1  
  end 
  def render_shadow(phx,phy,sx,sy,range,bitmap) 
    @m1 = (@y1-sy)/(@x1-sx) 
    @n1 = sy - @m1*sx 
    @m2 = (@y2-sy)/(@x2-sx) 
    @n2 = sy - @m2*sx 
    for x in (sx-range).to_i..@x1 
      init = shadow_iy(x) 
      bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3) 
    end 
  end 
  def shadow_iy(x) 
    return @m1*x+@n1 
  end 
  def shadow_fy(x) 
    return @m2*x+@n2 
  end 
end 
class Block_IL < Block_Surface 
  attr_reader :type 
  def initialize(x1,y1,x2,y2) 
    super(x1,y1,x2,y2) 
    @type = 0x019 
  end 
  def visible?(sx,sy) 
    return sx < @x1 && sy > @y1 
  end 
  def render_shadow(phx,phy,sx,sy,range,bitmap) 
    @m1 = (@y1-sy)/(@x1-sx) 
    @n1 = @y1 - @m1*@x1 
    @m2 = (@y2-sy)/(@x2-sx) 
    @m2 = 0 if @m2 > 0 
    @n2 = @y2 - @m2*@x2 
    for x in @x1..(sx+range) 
      init = shadow_iy(x).floor 
      bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3) 
    end 
  end 
  def shadow_iy(x) 
    return @m1*x+@n1 
  end 
  def shadow_fy(x) 
    return @m2*x+@n2 
  end 
end 
class Block_IR < Block_Surface 
  attr_reader :type 
  def initialize(x1,y1,x2,y2) 
    super(x1,y1,x2,y2) 
    @type = 0x01c 
  end 
  def visible?(sx,sy) 
    return sx > @x1 && sy > @y1 
  end 
  def render_shadow(phx,phy,sx,sy,range,bitmap) 
    @m1 = (@y1-sy)/(@x1-sx) 
    @n1 = @y1 - @m1*@x1 
    @m2 = (@y2-sy)/(@x2-sx) 
    @m2 = 0 if @m2 < 0 
    @n2 = @y2 - @m2*@x2 
    for x in (sx-range).to_i..@x1 
      init = shadow_iy(x).floor 
      bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3) 
    end 
  end 
  def shadow_iy(x) 
    return @m1*x+@n1 
  end 
  def shadow_fy(x) 
    return @m2*x+@n2 
  end 
end 
class Block_WL < Block_Surface 
  attr_reader :type 
  def initialize(x1,y1,x2,y2) 
    super(x1,y1,x2,y2) 
    @type = 0x011 
  end 
  def visible?(sx,sy) 
    return sx < @x1 && sy < @y2 
  end 
  def render_shadow(phx,phy,sx,sy,range,bitmap) 
    @m1 = (@y1-sy)/(@x1-sx) 
    @n1 = sy - @m1*sx 
    @m2 = (@y2-sy)/(@x2-sx) 
    @n2 = sy - @m2*sx 
    for x in @x1..(sx+range) 
      init = shadow_iy(x) 
      bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2) 
    end 
  end 
  def shadow_iy(x) 
    return @m1*x+@n1 
  end 
  def shadow_fy(x) 
    return @m2*x+@n2 
  end 
end 
class Block_WR < Block_Surface 
  attr_reader :type 
  def initialize(x1,y1,x2,y2) 
    super(x1,y1,x2,y2) 
    @type = 0x014 
  end 
  def visible?(sx,sy) 
    return sx > @x1 && sy < @y2 
  end 
  def render_shadow(phx,phy,sx,sy,range,bitmap) 
    @m1 = (@y1-sy)/(@x1-sx) 
    @n1 = sy - @m1*sx 
    @m2 = (@y2-sy)/(@x2-sx) 
    @n2 = sy - @m2*sx 
    for x in (sx-range).to_i..@x1 
      init = shadow_iy(x) 
      bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2) 
    end 
  end 
  def shadow_iy(x) 
    return @m1*x+@n1 
  end 
  def shadow_fy(x) 
    return @m2*x+@n2 
  end 
end 
class Block_SU < Block_Surface 
  attr_reader :type 
  def initialize(x1,y1,x2,y2) 
    super(x1,y1,x2,y2) 
    @type = 0x02 
  end 
  def visible?(sx,sy) 
    return sy < @y1 
  end 
  def render_shadow(phx,phy,sx,sy,range,bitmap) 
    if @x1 == sx 
      @m1 = nil 
    else 
      @m1 = (@y1-sy)/(@x1-sx) 
      @m1 += ACC if @m1 < -ACC 
      @n1 = @y1 - @m1*@x1 
    end 
    if @x2 == sx 
      @m2 = nil 
    else 
      @m2 = (@y2-sy)/(@x2-sx) 
      @n2 = sy - @m2*sx 
    end 
    for y in @y1..(sy+range) 
      init = shadow_ix(y) 
      bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1) 
    end 
  end 
  def shadow_ix(y) 
    return @m1.nil? ? @x1 : (y-@n1)/@m1 
  end 
  def shadow_fx(y) 
    return @m2.nil? ? @x2 : (y-@n2)/@m2 
  end 
end 
class Block_SD < Block_Surface 
  attr_reader :type 
  def initialize(x1,y1,x2,y2) 
    super(x1,y1,x2,y2) 
    @type = 0x08 
  end 
  def visible?(sx,sy) 
    return sy > @y1 
  end 
  def render_shadow(phx,phy,sx,sy,range,bitmap) 
    if @x1 == sx 
      @m1 = nil 
    else 
      @m1 = (@y1-sy)/(@x1-sx) 
      @m1 -= ACC if @m1 > ACC 
      @n1 = sy - @m1*sx 
    end 
    if x2 == sx 
      @m2 = nil 
    else 
      @m2 = (@y2-sy)/(@x2-sx) 
      @n2 = sy - @m2*sx 
    end 
    for y in (sy-range).to_i..@y1 
      init = shadow_ix(y) 
      bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1) 
    end 
  end 
  def shadow_ix(y) 
    return @m1.nil? ? @x1 : (y-@n1)/@m1 
  end 
  def shadow_fx(y) 
    return @m2.nil? ? @x2 : (y-@n2)/@m2 
  end 
end 
class Spriteset_Map 
  include Light_Core 
  alias kbl_initialize initialize 
  alias kbl_update update 
  alias kbl_dispose dispose 
  def initialize 
    setup_lights 
    kbl_initialize 
  end 
  def update 
    kbl_update 
    update_lights 
  end 
  def dispose 
    kbl_dispose 
    dispose_lights 
  end 
  def dispose_lights 
    $game_map.lantern.dispose 
    $game_map.light_sources.each { |source| source.dispose_light } 
    $game_map.light_surface.bitmap.dispose 
    $game_map.light_surface.dispose 
    $game_map.light_surface = nil 
  end 
  def update_lights 
    $game_map.light_surface.bitmap.clear 
    $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color) 
    $game_map.light_sources.each { |source| source.draw_light } 
    return unless $game_map.lantern.visible 
    @btr = $game_map.lantern.get_graphic 
    x = $game_map.lantern.x 
    y = $game_map.lantern.y 
    r = $game_map.lantern.range 
    sx = x + r 
    sy = y + r 
    dr = r*2 
    $game_map.surfaces.each { |s| s.render_shadow(x,y,sx,sy,r,@btr) if s.visible?(sx,sy) && s.within?(x,x+dr,y,y+dr) } 
    $game_map.light_surface.bitmap.blt($game_map.lantern.sx,$game_map.lantern.sy,@btr,Rect.new(0,0,dr,dr),$game_map.lantern.opacity) 
  end 
  def setup_lights 
    @btr = nil 
    $game_map.lantern.restore 
    $game_map.light_sources.each { |source| source.restore_light } 
    $game_map.light_surface = Sprite.new 
    $game_map.light_surface.bitmap = Bitmap.new(544,416) 
    $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color) 
    $game_map.light_surface.blend_type = 2 
    $game_map.light_surface.opacity = $game_map.effect_surface.alpha 
    $game_map.light_surface.z = Surface_Z 
  end 
end 
 | 
 |