Advertisement
Loque

Khas Awesome Light Effects

Nov 13th, 2014
285
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Ruby 27.90 KB | None | 0 0
  1. #-------------------------------------------------------------------------------
  2. # * [ACE] Khas Awesome Light Effects
  3. #-------------------------------------------------------------------------------
  4. # * By Khas Arcthunder - arcthunder.blogspot.com
  5. # * Version: 1.0 EN
  6. # * Released on: 17/01/2012
  7. #
  8. #-------------------------------------------------------------------------------
  9. # * Terms of Use
  10. #-------------------------------------------------------------------------------
  11. # When using any Khas script, you agree with the following terms:
  12. # 1. You must give credit to Khas;
  13. # 2. All Khas scripts are licensed under a Creative Commons license;
  14. # 3. All Khas scripts are for non-commercial projects. If you need some script
  15. #    for your commercial project (I accept requests for this type of project),
  16. #    send an email to nilokruch@live.com with your request;
  17. # 4. All Khas scripts are for personal use, you can use or edit for your own
  18. #    project, but you are not allowed to post any modified version;
  19. # 5. You can’t give credit to yourself for posting any Khas script;
  20. # 6. If you want to share a Khas script, don’t post the direct download link,
  21. #    please redirect the user to arcthunder.site40.net
  22. #
  23. #-------------------------------------------------------------------------------
  24. # * Features
  25. #-------------------------------------------------------------------------------
  26. # - Realistic Light
  27. # - Light does not pass over walls, blocks and roofs
  28. # - Static Light Sources
  29. # - Dynamic Light Sources (like a player's lantern)
  30. # - Multiple effects
  31. # - Easy to use (comments)
  32. #
  33. #-------------------------------------------------------------------------------
  34. # * WARNING - Performance
  35. #-------------------------------------------------------------------------------
  36. # This script may be too heavy to old processors! The Awesome Light Effects was
  37. # tested on a Core 2 Duo E4500 and on a Core i5, without any lag. However,
  38. # there's other factors that may influence the script performance:
  39. #
  40. # 1. Map size
  41. # This script searches surfaces on the map, in order to cut the light pictures.
  42. # In a huge map, the number of surfaces may increase a lot, affecting the
  43. # DYNAMIC LIGHT SOURCE only. Map size does not influence the static sources.
  44. #
  45. # 2. Number of effects
  46. # This script draws the effects on the screen, but before drawing, it checks
  47. # if the effect is out of screen (in this case, the script will skip the
  48. # light drawing). Too much effects may cause lag, but this is just a prevision.
  49. #
  50. # 3. Effect's picture size
  51. # The picture size of the DYNAMIC LIGHT SOURCE influences directly on your
  52. # game's performace. The bigger is the picture, the slower it will be to
  53. # draw it dynamically. The recommended maximum size is 200x200 pixels
  54. #
  55. #-------------------------------------------------------------------------------
  56. # * WARNING - Light pictures
  57. #-------------------------------------------------------------------------------
  58. # In order to run this script correctly, the light pictures MUST obey the
  59. # following conditions:
  60. # 1. The picture's size MUST be multiple of 2. Example: 150x150
  61. # 2. The picture's width MUST be equal to it's height. Example: 156x156
  62. # 3. The picture's colors MUST be inverted! This is necessary because
  63. #    the script inverts the colors to draw the effect. The black color
  64. #    will be transparent!
  65. #
  66. #-------------------------------------------------------------------------------
  67. # * Instructions - 1. Setup your effects!
  68. #-------------------------------------------------------------------------------
  69. # In order to setup your static effects, go to the setup part and define your
  70. # effects inside the Effects hash. Do as the following mode:
  71. #
  72. # X => [picture,opacity,variation,cut],   <= Remember to put a comma here!
  73. #
  74. # Where:
  75. # picture => Picture's name, inside the Graphics/Lights folder;
  76. # opacity => Effect's opacity;
  77. # variation => Effect's opacity variation;
  78. # cut => Put true to cut the effect or false to don't;
  79. # X => The effect's ID, it will be used on events.
  80. #
  81. # Check the default effects to understand how they work.
  82. #
  83. #-------------------------------------------------------------------------------
  84. # * Instructions - 2. Use your effects!
  85. #-------------------------------------------------------------------------------
  86. # In order to use a effect, put the following comment on a event:
  87. #
  88. # [light x]
  89. #
  90. # Where x must be the Effect's ID.
  91. #
  92. #-------------------------------------------------------------------------------
  93. # * Instructions - 3. Use an awesome lantern!
  94. #-------------------------------------------------------------------------------
  95. # The dynamic light source (lantern) is initialized invisible by default.
  96. # You may call the following commands:
  97. #
  98. # l = $game_map.lantern
  99. # Gets the lantern into a variable
  100.  
  101. # l.set_graphic(i)
  102. # Sets the lantern's graphic to i, where i must be the picture's file name on
  103. # Graphics/Lights folder.
  104. #
  105. # l.set_multiple_graphics(h)
  106. # Sets the lantern's graphics to h, where h must be a hash with the following
  107. # structure:
  108. #
  109. # h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"}
  110. #
  111. # Where:
  112. # "ld" is the name of the picture when the lantern's owner is looking down;
  113. # "ll" is the name of the picture when the lantern's owner is looking left;
  114. # "lr" is the name of the picture when the lantern's owner is looking right;
  115. # "lu" is the name of the picture when the lantern's owner is looking up.
  116. #
  117. # l.change_owner(char)
  118. # Sets the lantern's owner to char. Char must be ONE of the following commands:
  119. # $game_player           <= The player itself;
  120. # self_event             <= The event where the command was called;
  121. # $game_map.events[x]    <= The event ID x.
  122. #
  123. # l.set_opacity(o,p)
  124. # Sets the lantern's opacity, where:
  125. # o is the opacity itself;
  126. # p is the opacity variation.
  127. #
  128. # l.show
  129. # After setting the lantern with the commands above, you may set it to visible
  130. # using this command.
  131. #
  132. # l.hide
  133. # Use this command to set the lantern as invisible.
  134. #
  135. #-------------------------------------------------------------------------------
  136. # * Instructions - 4. Use the effect's surface!
  137. #-------------------------------------------------------------------------------
  138. # The Awesome Light Effects draws the effects on a surface. In order to make
  139. # the effects visible, the effect's surface MUST be visible. The Effect's
  140. # Surface is initialized with it's opacity set to zero. You can call the
  141. # following commands:
  142. #
  143. # s = $game_map.effect_surface
  144. # Gets the Effect's Surface into a variable
  145. #
  146. # s.set_color(r,g,b)
  147. # Changes the Effect's Surface color instantly, where:
  148. # r => red level;
  149. # g => green level;
  150. # b => blue level;
  151. #
  152. # s.set_alpha(a)
  153. # Changes the Effect's Surface opacity instantly to a.
  154. #
  155. # s.change_color(time,r,g,b)
  156. # Changes the Effect's Surface color ONLY in a certain time, where:
  157. # time => The change's time (frames);
  158. # r => red level;
  159. # g => green level;
  160. # b => blue level;
  161. #
  162. # s.change_color(time,r,g,b,a)
  163. # Changes the Effect's Surface color and it's opacity in a certain time, where:
  164. # time => The change's time (frames);
  165. # r => red level;
  166. # g => green level;
  167. # b => blue level;
  168. # a => opacity
  169. #
  170. # s.change_alpha(time,a)
  171. # Changes the Effect's Surface opacity in a certain time, where:
  172. # time => The change's time (frames);
  173. # a => opacity
  174. #
  175. #-------------------------------------------------------------------------------
  176. # * Instructions - 5. Use the effect's surface with Tone command!
  177. #-------------------------------------------------------------------------------
  178. # You can access the Effect's Surface with the "Screen Tone" command. In order
  179. # to turn this feature on, set the "Surface_UE" constant to true.
  180. #
  181. # If you decided to use this feature, please note some details:
  182. # 1. The colors values must be between 0 and 255;
  183. # 2. The time is in frames;
  184. # 3. The "gray" value will be sent as the opacity value
  185. #
  186. #-------------------------------------------------------------------------------
  187. # * Instructions - 6. Setup your Tileset Tags!
  188. #-------------------------------------------------------------------------------
  189. # In order to cut the effect's picture correctly, there's 3 types of behavior
  190. # for a tile: wall, block and roof. Walls will make shadows as real walls,
  191. # blocks as blocks and roofs as roofs. So, the tileset tags MUST be configured.
  192. # Check the demo to understand how this system works. If the tilesets aren't
  193. # configured correctly, the script won't cut the effects correctly.
  194. #
  195. #-------------------------------------------------------------------------------
  196. # * Setup Part
  197. #-------------------------------------------------------------------------------
  198. module Light_Core
  199.   Effects = { #  <= DON'T change this!
  200. #-------------------------------------------------------------------------------
  201. # PUT YOUR EFFECTS HERE!
  202. #-------------------------------------------------------------------------------
  203.   0 => ["light",255,0,true],
  204.   1 => ["torch",200,20,true],
  205.   2 => ["torch_m",180,30,true],
  206.   3 => ["light_s",255,0,true],
  207.  
  208. #-------------------------------------------------------------------------------
  209. # End of effecs configuration
  210. #-------------------------------------------------------------------------------
  211.   } #  <= DON'T change this!
  212.  
  213.   # Z coordinate of the Effect's Surface
  214.   Surface_Z = 180
  215.  
  216.   # Enable Effect's Surface control by "Screen Tone" command?
  217.   Surface_UE = true
  218.  
  219.   # Roof behavior tag
  220.   Roof_Tag = 5
  221.   # Wall behavior tag
  222.   Wall_Tag = 6
  223.   # Block behavior tag
  224.   Block_Tag = 7
  225.  
  226.   # Don't change this!
  227.   ACC = Math.tan(Math::PI/26)
  228. end
  229. #-------------------------------------------------------------------------------
  230. # Script
  231. #-------------------------------------------------------------------------------
  232. module Cache
  233.   def self.light(filename)
  234.     load_bitmap("Graphics/Lights/", filename)
  235.   end
  236. end
  237. module Light_Bitcore
  238.   include Light_Core
  239.   def self.initialize
  240.     @@buffer = {}
  241.     Effects.values.each { |effect| Light_Bitcore.push(effect[0])}
  242.   end
  243.   def self::[](key)
  244.     return @@buffer[key]
  245.   end
  246.   def self.push(key)
  247.     return if @@buffer.keys.include?(key)
  248.     @@buffer[key] = Cache.light(key)
  249.   end
  250. end
  251. Light_Bitcore.initialize
  252. class Light_SSource
  253.   attr_reader :real_x
  254.   attr_reader :real_y
  255.   attr_reader :range
  256.   attr_accessor :bitmap
  257.   attr_reader :w
  258.   attr_reader :h
  259.   attr_reader :hs
  260.   def initialize(char,bitmap,opacity,plus,hs)
  261.     sync(char)
  262.     @key = bitmap
  263.     @bitmap = Light_Bitcore[@key].clone
  264.     @range = @bitmap.width/2
  265.     @w = @bitmap.width
  266.     @h = @bitmap.height
  267.     @mr = @range - 16
  268.     @opacity = opacity
  269.     @plus = plus
  270.     @hs = hs
  271.     render if @hs
  272.   end
  273.   def render
  274.     tx = x
  275.     ty = y
  276.     tsx = x + @range
  277.     tsy = y + @range
  278.     dr = @range*2
  279.     for s in $game_map.surfaces
  280.       next if !s.visible?(tsx,tsy) || !s.within?(tx,tx+dr,ty,ty+dr)
  281.       s.render_shadow(tx,ty,tsx,tsy,@range,@bitmap)
  282.     end
  283.   end
  284.   def restore
  285.     return unless @bitmap.nil?
  286.     @bitmap = Light_Bitcore[@key].clone
  287.     render if @hs
  288.   end
  289.   def opacity
  290.     @plus == 0 ? @opacity : (@opacity + rand(@plus))
  291.   end
  292.   def sx
  293.     return $game_map.adjust_x(@real_x)*32-@mr
  294.   end
  295.   def sy
  296.     return $game_map.adjust_y(@real_y)*32-@mr
  297.   end
  298.   def sync(char)
  299.     @real_x = char.real_x
  300.     @real_y = char.real_y
  301.   end
  302.   def x
  303.     return (@real_x*32 - @mr).to_f
  304.   end
  305.   def y
  306.     return (@real_y*32 - @mr).to_f
  307.   end
  308.   def dispose
  309.     return if @bitmap.nil?
  310.     @bitmap.dispose
  311.     @bitmap = nil
  312.   end
  313. end
  314. class Light_DSource < Light_SSource
  315.   attr_reader :bitmap
  316.   attr_reader :visible
  317.   def initialize
  318.     @key = nil
  319.     @bitmap = nil
  320.     @opacity = 255
  321.     @plus = 0
  322.     @char = $game_player
  323.     @visible = false
  324.   end
  325.   def set_opacity(o,p)
  326.     @opacity = o
  327.     @plus = p
  328.   end
  329.   def set_graphic(sb)
  330.     dispose
  331.     @key = {2=>sb,4=>sb,6=>sb,8=>sb}
  332.     Light_Bitcore.push(sb)
  333.     @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}
  334.     @range = @bitmap[2].width/2
  335.     @w = @bitmap[2].width
  336.     @h = @bitmap[2].height
  337.     @mr = @range - 16
  338.   end
  339.   def set_multiple_graphics(ba)
  340.     dispose
  341.     @key = ba
  342.     @key.values.each {|key| Light_Bitcore.push(key)}
  343.     @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}
  344.     @range = @bitmap[2].width/2
  345.     @w = @bitmap[2].width
  346.     @h = @bitmap[2].height
  347.     @mr = @range - 16
  348.   end
  349.   def get_graphic
  350.     return @bitmap[@char.direction].clone
  351.   end
  352.   def show
  353.     return if @bitmap.nil?
  354.     @visible = true
  355.   end
  356.   def hide
  357.     @visible = false
  358.   end
  359.   def restore
  360.     return if @key.nil?
  361.     @key.values.each {|key| Light_Bitcore.push(key)}
  362.     @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}
  363.   end
  364.   def dispose
  365.     return if @bitmap.nil?
  366.     @bitmap.values.each { |b| b.dispose }
  367.     @bitmap = nil
  368.   end
  369.   def change_owner(char)
  370.     @char = char
  371.   end
  372.   def render
  373.   end
  374.   def sx
  375.     return $game_map.adjust_x(@char.real_x)*32-@mr
  376.   end
  377.   def sy
  378.     return $game_map.adjust_y(@char.real_y)*32-@mr
  379.   end
  380.   def x
  381.     return (@char.real_x*32 - @mr).to_f
  382.   end
  383.   def y
  384.     return (@char.real_y*32 - @mr).to_f
  385.   end
  386. end
  387. class Light_Surface
  388.   def initialize
  389.     @ta = @a = 0
  390.     @tr = @r = 255
  391.     @tg = @g = 255
  392.     @tb = @b = 255
  393.     @va = @vr = @vg = @vb = 0.0
  394.     @timer = 0
  395.   end
  396.   def refresh
  397.     return if @timer == 0
  398.     @a += @va
  399.     @r += @vr
  400.     @g += @vg
  401.     @b += @vb
  402.     $game_map.light_surface.opacity = @a
  403.     @timer -= 1
  404.   end
  405.   def change_color(time,r,g,b,a=nil)
  406.     r = 0 if r < 0; r = 255 if r > 255
  407.     g = 0 if g < 0; g = 255 if g > 255
  408.     b = 0 if b < 0; b = 255 if b > 255
  409.     unless a.nil?
  410.       a = 0 if a < 0; a = 255 if a > 255
  411.     end
  412.     @timer = time
  413.     @tr = 255-r
  414.     @tg = 255-g
  415.     @tb = 255-b
  416.     @va = (a.nil? ? 0 : (a-@a).to_f/@timer)
  417.     @vr = (@tr - @r).to_f/@timer
  418.     @vg = (@tg - @g).to_f/@timer
  419.     @vb = (@tb - @b).to_f/@timer
  420.   end
  421.   def change_alpha(time,a)
  422.     a = 0 if a < 0; a = 255 if a > 255
  423.     @timer = time
  424.     @ta = a
  425.     @vr = @vg = @vb = 0.0
  426.     @va = (a-@a).to_f/@timer
  427.   end
  428.   def set_color(r,g,b)
  429.     r = 0 if r < 0; r = 255 if r > 255
  430.     g = 0 if g < 0; g = 255 if g > 255
  431.     b = 0 if b < 0; b = 255 if b > 255
  432.     @tr = @r = 255-r
  433.     @tg = @g = 255-g
  434.     @tb = @b = 255-b
  435.     @va = @vr = @vg = @vb = 0.0
  436.     @timer = 0
  437.   end
  438.   def set_alpha(a)
  439.     a = 0 if a < 0; a = 255 if a > 255
  440.     @ta = @a = a
  441.     $game_map.light_surface.opacity = @a
  442.     @va = @vr = @vg = @vb = 0.0
  443.     @timer = 0
  444.   end
  445.   def alpha
  446.     return @a
  447.   end
  448.   def color
  449.     return Color.new(@r,@g,@b)
  450.   end
  451. end
  452. class Game_Map
  453.   include Light_Core
  454.   attr_accessor :light_surface
  455.   attr_accessor :light_sources
  456.   attr_accessor :surfaces
  457.   attr_accessor :effect_surface
  458.   attr_accessor :lantern
  459.   alias kbl_setup_events setup_events
  460.   alias kbl_initialize initialize
  461.   alias kbl_update update
  462.   def initialize
  463.     kbl_initialize
  464.     @effect_surface = Light_Surface.new
  465.     @lantern = Light_DSource.new
  466.   end
  467.   def update(arg)
  468.     @effect_surface.refresh if arg
  469.     kbl_update(arg)
  470.   end
  471.   def first_tag(x,y)
  472.     tag = tileset.flags[tile_id(x,y,0)] >> 12
  473.     return tag > 0 ? tag : 0
  474.   end
  475.   def setup_events
  476.     @light_sources.nil? ? @light_sources = [] : @light_sources.clear
  477.     setup_surfaces
  478.     merge_surfaces
  479.     kbl_setup_events
  480.   end
  481.   def setup_surfaces
  482.     @surfaces = []
  483.     for x in 0..(width-1)
  484.       for y in 0..(height-1)
  485.         tag = first_tag(x,y)
  486.         if tag == Wall_Tag
  487.           i = tile_id(x,y,0)
  488.           if i & 0x02 == 0x02
  489.             @surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32)
  490.           end
  491.           if i & 0x04 == 0x04
  492.             @surfaces << Block_WR.new(x*32+31,y*32,x*32+31,y*32+32)
  493.             @surfaces << Block_IL.new(x*32+32,y*32,x*32+32,y*32+32)
  494.           end
  495.           if i & 0x01 == 0x01
  496.             @surfaces << Block_IR.new(x*32-1,y*32,x*32-1,y*32+32)
  497.             @surfaces << Block_WL.new(x*32,y*32,x*32,y*32+32)
  498.           end
  499.         elsif tag == Roof_Tag
  500.           i = tile_id(x,y,0)
  501.           @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if i & 0x02 == 0x02
  502.           @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if i & 0x04 == 0x04
  503.           @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if i & 0x01 == 0x01
  504.         elsif tag == Block_Tag
  505.           f = tileset.flags[tile_id(x,y,0)]
  506.           @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if f & 0x02 == 0x02
  507.           @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if f & 0x04 == 0x04
  508.           @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if f & 0x08 == 0x08
  509.         end
  510.       end
  511.     end
  512.   end
  513.   def merge_surfaces
  514.     new_surfaces = []
  515.     hs = []; vs = []
  516.     ws = []; is = []
  517.     for surface in @surfaces
  518.       if surface.type & 0x05 == 0
  519.         hs << surface
  520.       else
  521.         if surface.type & 0x010 == 0
  522.           vs << surface
  523.         else
  524.           if surface.type & 0x08 == 0
  525.             ws << surface
  526.           else
  527.             is << surface
  528.           end
  529.         end
  530.       end
  531.     end
  532.     for surface in hs
  533.       surface.ready ? next : surface.ready = true
  534.       for s in hs
  535.         next if s.ready || s.y1 != surface.y1 || surface.type != s.type
  536.         if s.x2 == surface.x1
  537.           surface.x1 = s.x1
  538.           s.trash = true
  539.           s.ready = true
  540.           surface.ready = false
  541.         elsif s.x1 == surface.x2
  542.           surface.x2 = s.x2
  543.           s.trash = true
  544.           s.ready = true
  545.           surface.ready = false
  546.         end
  547.       end
  548.     end
  549.     hs.each { |s| @surfaces.delete(s) if s.trash}
  550.     for surface in vs
  551.       surface.ready ? next : surface.ready
  552.       for s in vs
  553.         next if s.ready || s.x1 != surface.x1
  554.         if s.y2 == surface.y1
  555.           surface.y1 = s.y1
  556.           s.trash = true
  557.           s.ready = true
  558.           surface.ready = false
  559.         elsif s.y1 == surface.y2
  560.           surface.y2 = s.y2
  561.           s.trash = true
  562.           s.ready = true
  563.           surface.ready = false
  564.         end
  565.       end
  566.     end
  567.     vs.each { |s| @surfaces.delete(s) if s.trash}
  568.     for surface in ws
  569.       surface.ready ? next : surface.ready
  570.       for s in ws
  571.         next if s.ready || s.x1 != surface.x1
  572.         if s.y2 == surface.y1
  573.           surface.y1 = s.y1
  574.           s.trash = true
  575.           s.ready = true
  576.           surface.ready = false
  577.         elsif s.y1 == surface.y2
  578.           surface.y2 = s.y2
  579.           s.trash = true
  580.           s.ready = true
  581.           surface.ready = false
  582.         end
  583.       end
  584.     end
  585.     ws.each { |s| @surfaces.delete(s) if s.trash}
  586.     for surface in is
  587.       surface.ready ? next : surface.ready
  588.       for s in is
  589.         next if s.ready || s.x1 != surface.x1
  590.         if s.y2 == surface.y1
  591.           surface.y1 = s.y1
  592.           s.trash = true
  593.           s.ready = true
  594.           surface.ready = false
  595.         elsif s.y1 == surface.y2
  596.           surface.y2 = s.y2
  597.           s.trash = true
  598.           s.ready = true
  599.           surface.ready = false
  600.         end
  601.       end
  602.     end
  603.     is.each { |s| @surfaces.delete(s) if s.trash}
  604.   end
  605. end
  606. class Game_Event < Game_Character
  607.   alias kbl_initialize initialize
  608.   alias kbl_setup_page setup_page
  609.   def initialize(m,e)
  610.     @light = nil
  611.     kbl_initialize(m,e)
  612.   end
  613.   def setup_page(np)
  614.     kbl_setup_page(np)
  615.     setup_light(np.nil?)
  616.   end
  617.   def setup_light(dispose)
  618.     unless @light.nil?
  619.       $game_map.light_sources.delete(self)
  620.       @light.dispose
  621.       @light = nil
  622.     end
  623.     unless dispose && @list.nil?
  624.       for command in @list
  625.         if command.code == 108 && command.parameters[0].include?("[light")
  626.           command.parameters[0].scan(/\[light ([0.0-9.9]+)\]/)
  627.           effect = Light_Core::Effects[$1.to_i]
  628.           @light = Light_SSource.new(self,effect[0],effect[1],effect[2],effect[3])
  629.           $game_map.light_sources << self
  630.           return
  631.         end
  632.       end
  633.     end
  634.   end
  635.   def draw_light
  636.     sx = @light.sx
  637.     sy = @light.sy
  638.     w = @light.w
  639.     h = @light.h
  640.     return if sx > 544 && sy > 416 && sx + w < 0 && sy + h < 0
  641.     $game_map.light_surface.bitmap.blt(sx,sy,@light.bitmap,Rect.new(0,0,w,h),@light.opacity)
  642.   end
  643.   def dispose_light
  644.     @light.dispose
  645.   end
  646.   def restore_light
  647.     @light.restore
  648.   end
  649. end
  650. if Light_Core::Surface_UE
  651.   class Game_Interpreter
  652.     def command_223
  653.       $game_map.effect_surface.change_color(@params[1],@params[0].red,@params[0].green,@params[0].blue,@params[0].gray)
  654.       wait(@params[1]) if @params[2]
  655.     end
  656.   end
  657. end
  658. class Game_Interpreter
  659.   def self_event
  660.     return $game_map.events[@event_id]
  661.   end
  662. end
  663. class Block_Surface
  664.   include Light_Core
  665.   attr_accessor :x1
  666.   attr_accessor :y1
  667.   attr_accessor :x2
  668.   attr_accessor :y2
  669.   attr_accessor :ready
  670.   attr_accessor :trash
  671.   def initialize(x1,y1,x2,y2)
  672.     @x1 = x1
  673.     @y1 = y1
  674.     @x2 = x2
  675.     @y2 = y2
  676.     @ready = false
  677.     @trash = false
  678.   end
  679.   def within?(min_x,max_x,min_y,max_y)
  680.     return @x2 > min_x && @x1 < max_x && @y2 > min_y && @y1 < max_y
  681.   end
  682. end
  683. class Block_SL < Block_Surface
  684.   attr_reader :type
  685.   def initialize(x1,y1,x2,y2)
  686.     super(x1,y1,x2,y2)
  687.     @type = 0x01
  688.   end
  689.   def visible?(sx,sy)
  690.     return sx < @x1
  691.   end
  692.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  693.     @m1 = (@y1-sy)/(@x1-sx)
  694.     @n1 = sy - @m1*sx
  695.     @m2 = (@y2-sy)/(@x2-sx)
  696.     @n2 = sy - @m2*sx
  697.     for x in @x1..(sx+range)
  698.       init = shadow_iy(x)
  699.       bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)
  700.     end
  701.   end
  702.   def shadow_iy(x)
  703.     return @m1*x+@n1
  704.   end
  705.   def shadow_fy(x)
  706.     return @m2*x+@n2
  707.   end
  708. end
  709. class Block_SR < Block_Surface
  710.   attr_reader :type
  711.   def initialize(x1,y1,x2,y2)
  712.     super(x1,y1,x2,y2)
  713.     @type = 0x04
  714.   end
  715.   def visible?(sx,sy)
  716.     return sx > @x1
  717.   end
  718.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  719.     @m1 = (@y1-sy)/(@x1-sx)
  720.     @n1 = sy - @m1*sx
  721.     @m2 = (@y2-sy)/(@x2-sx)
  722.     @n2 = sy - @m2*sx
  723.     for x in (sx-range).to_i..@x1
  724.       init = shadow_iy(x)
  725.       bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)
  726.     end
  727.   end
  728.   def shadow_iy(x)
  729.     return @m1*x+@n1
  730.   end
  731.   def shadow_fy(x)
  732.     return @m2*x+@n2
  733.   end
  734. end
  735. class Block_IL < Block_Surface
  736.   attr_reader :type
  737.   def initialize(x1,y1,x2,y2)
  738.     super(x1,y1,x2,y2)
  739.     @type = 0x019
  740.   end
  741.   def visible?(sx,sy)
  742.     return sx < @x1 && sy > @y1
  743.   end
  744.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  745.     @m1 = (@y1-sy)/(@x1-sx)
  746.     @n1 = @y1 - @m1*@x1
  747.     @m2 = (@y2-sy)/(@x2-sx)
  748.     @m2 = 0 if @m2 > 0
  749.     @n2 = @y2 - @m2*@x2
  750.     for x in @x1..(sx+range)
  751.       init = shadow_iy(x).floor
  752.       bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)
  753.     end
  754.   end
  755.   def shadow_iy(x)
  756.     return @m1*x+@n1
  757.   end
  758.   def shadow_fy(x)
  759.     return @m2*x+@n2
  760.   end
  761. end
  762. class Block_IR < Block_Surface
  763.   attr_reader :type
  764.   def initialize(x1,y1,x2,y2)
  765.     super(x1,y1,x2,y2)
  766.     @type = 0x01c
  767.   end
  768.   def visible?(sx,sy)
  769.     return sx > @x1 && sy > @y1
  770.   end
  771.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  772.     @m1 = (@y1-sy)/(@x1-sx)
  773.     @n1 = @y1 - @m1*@x1
  774.     @m2 = (@y2-sy)/(@x2-sx)
  775.     @m2 = 0 if @m2 < 0
  776.     @n2 = @y2 - @m2*@x2
  777.     for x in (sx-range).to_i..@x1
  778.       init = shadow_iy(x).floor
  779.       bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)
  780.     end
  781.   end
  782.   def shadow_iy(x)
  783.     return @m1*x+@n1
  784.   end
  785.   def shadow_fy(x)
  786.     return @m2*x+@n2
  787.   end
  788. end
  789. class Block_WL < Block_Surface
  790.   attr_reader :type
  791.   def initialize(x1,y1,x2,y2)
  792.     super(x1,y1,x2,y2)
  793.     @type = 0x011
  794.   end
  795.   def visible?(sx,sy)
  796.     return sx < @x1 && sy < @y2
  797.   end
  798.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  799.     @m1 = (@y1-sy)/(@x1-sx)
  800.     @n1 = sy - @m1*sx
  801.     @m2 = (@y2-sy)/(@x2-sx)
  802.     @n2 = sy - @m2*sx
  803.     for x in @x1..(sx+range)
  804.       init = shadow_iy(x)
  805.       bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)
  806.     end
  807.   end
  808.   def shadow_iy(x)
  809.     return @m1*x+@n1
  810.   end
  811.   def shadow_fy(x)
  812.     return @m2*x+@n2
  813.   end
  814. end
  815. class Block_WR < Block_Surface
  816.   attr_reader :type
  817.   def initialize(x1,y1,x2,y2)
  818.     super(x1,y1,x2,y2)
  819.     @type = 0x014
  820.   end
  821.   def visible?(sx,sy)
  822.     return sx > @x1 && sy < @y2
  823.   end
  824.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  825.     @m1 = (@y1-sy)/(@x1-sx)
  826.     @n1 = sy - @m1*sx
  827.     @m2 = (@y2-sy)/(@x2-sx)
  828.     @n2 = sy - @m2*sx
  829.     for x in (sx-range).to_i..@x1
  830.       init = shadow_iy(x)
  831.       bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)
  832.     end
  833.   end
  834.   def shadow_iy(x)
  835.     return @m1*x+@n1
  836.   end
  837.   def shadow_fy(x)
  838.     return @m2*x+@n2
  839.   end
  840. end
  841. class Block_SU < Block_Surface
  842.   attr_reader :type
  843.   def initialize(x1,y1,x2,y2)
  844.     super(x1,y1,x2,y2)
  845.     @type = 0x02
  846.   end
  847.   def visible?(sx,sy)
  848.     return sy < @y1
  849.   end
  850.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  851.     if @x1 == sx
  852.       @m1 = nil
  853.     else
  854.       @m1 = (@y1-sy)/(@x1-sx)
  855.       @m1 += ACC if @m1 < -ACC
  856.       @n1 = @y1 - @m1*@x1
  857.     end
  858.     if @x2 == sx
  859.       @m2 = nil
  860.     else
  861.       @m2 = (@y2-sy)/(@x2-sx)
  862.       @n2 = sy - @m2*sx
  863.     end
  864.     for y in @y1..(sy+range)
  865.       init = shadow_ix(y)
  866.       bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)
  867.     end
  868.   end
  869.   def shadow_ix(y)
  870.     return @m1.nil? ? @x1 : (y-@n1)/@m1
  871.   end
  872.   def shadow_fx(y)
  873.     return @m2.nil? ? @x2 : (y-@n2)/@m2
  874.   end
  875. end
  876. class Block_SD < Block_Surface
  877.   attr_reader :type
  878.   def initialize(x1,y1,x2,y2)
  879.     super(x1,y1,x2,y2)
  880.     @type = 0x08
  881.   end
  882.   def visible?(sx,sy)
  883.     return sy > @y1
  884.   end
  885.   def render_shadow(phx,phy,sx,sy,range,bitmap)
  886.     if @x1 == sx
  887.       @m1 = nil
  888.     else
  889.       @m1 = (@y1-sy)/(@x1-sx)
  890.       @m1 -= ACC if @m1 > ACC
  891.       @n1 = sy - @m1*sx
  892.     end
  893.     if x2 == sx
  894.       @m2 = nil
  895.     else
  896.       @m2 = (@y2-sy)/(@x2-sx)
  897.       @n2 = sy - @m2*sx
  898.     end
  899.     for y in (sy-range).to_i..@y1
  900.       init = shadow_ix(y)
  901.       bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)
  902.     end
  903.   end
  904.   def shadow_ix(y)
  905.     return @m1.nil? ? @x1 : (y-@n1)/@m1
  906.   end
  907.   def shadow_fx(y)
  908.     return @m2.nil? ? @x2 : (y-@n2)/@m2
  909.   end
  910. end
  911. class Spriteset_Map
  912.   include Light_Core
  913.   alias kbl_initialize initialize
  914.   alias kbl_update update
  915.   alias kbl_dispose dispose
  916.   def initialize
  917.     setup_lights
  918.     kbl_initialize
  919.   end
  920.   def update
  921.     kbl_update
  922.     update_lights
  923.   end
  924.   def dispose
  925.     kbl_dispose
  926.     dispose_lights
  927.   end
  928.   def dispose_lights
  929.     $game_map.lantern.dispose
  930.     $game_map.light_sources.each { |source| source.dispose_light }
  931.     $game_map.light_surface.bitmap.dispose
  932.     $game_map.light_surface.dispose
  933.     $game_map.light_surface = nil
  934.   end
  935.   def update_lights
  936.     $game_map.light_surface.bitmap.clear
  937.     $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color)
  938.     $game_map.light_sources.each { |source| source.draw_light }
  939.     return unless $game_map.lantern.visible
  940.     @btr = $game_map.lantern.get_graphic
  941.     x = $game_map.lantern.x
  942.     y = $game_map.lantern.y
  943.     r = $game_map.lantern.range
  944.     sx = x + r
  945.     sy = y + r
  946.     dr = r*2
  947.     $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) }
  948.     $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)
  949.   end
  950.   def setup_lights
  951.     @btr = nil
  952.     $game_map.lantern.restore
  953.     $game_map.light_sources.each { |source| source.restore_light }
  954.     $game_map.light_surface = Sprite.new
  955.     $game_map.light_surface.bitmap = Bitmap.new(544,416)
  956.     $game_map.light_surface.bitmap.fill_rect(0,0,544,416,$game_map.effect_surface.color)
  957.     $game_map.light_surface.blend_type = 2
  958.     $game_map.light_surface.opacity = $game_map.effect_surface.alpha
  959.     $game_map.light_surface.z = Surface_Z
  960.   end
  961. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement