Jump to content
Khas

Khas Awesome Light Effects

Recommended Posts

It is in the instructions (in the comments at the beginning of the script):

 

 

#-------------------------------------------------------------------------------
# * Instructions - 2. Use your effects!
#-------------------------------------------------------------------------------
# In order to use a effect, put the following comment on a event:
# [light x]
#
# Where x must be the Effect's ID.
 
 

Share this post


Link to post
Share on other sites

Just copy the script into a blank area of the materials section of the script editor. The effects are listed in the script, so the x you are supposed to use is in there.

 

For example add the comment [light 1] to an event and it will have the light effect listed as 1.

Share this post


Link to post
Share on other sites

But what I do with the x? I am suppsoe to write something where the x is?

 

And how do I find the script? I downloaded the file but it has many folders and a game.

Edited by zenarium

Share this post


Link to post
Share on other sites

x is imaginary. You replace x with the ID of a light source which you've defined in the script. It's really easy once you look at the demo he's provided. I picked it up almost immediately and my game makes extensive use of the lightning, especially in the magic shops.

Share this post


Link to post
Share on other sites

No, it's up. Just went there no problem.

Share this post


Link to post
Share on other sites
So just a couple notes about this script and problems I had, and how I solved it.

 

1) Crashes on reset:

 

The problem is that the Light_Bitcore does not get re-initialized when the game is reset and the bitmaps stored are no longer valid.

I ended up getting rid of the whole Light_Bitcore module myself, mostly so my cache script could handle buffering things it's self. Here is my version if anyone is curious (also dynamically resizes based on your resolution):

 

 

#-------------------------------------------------------------------------------

# * [ACE] Khas Awesome Light Effects

#-------------------------------------------------------------------------------

# * By Khas Arcthunder - arcthunder.site40.net

# * Version: 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),

#    send an email to nilokruch@live.com with your request;

# 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

#

#-------------------------------------------------------------------------------

# * Features

#-------------------------------------------------------------------------------

# - Realistic Light

# - Light does not pass over walls, blocks and roofs

# - Static Light Sources

# - Dynamic Light Sources (like a player's lantern)

# - Multiple effects

# - Easy to use (comments)

#

#-------------------------------------------------------------------------------

# * WARNING - Performance

#-------------------------------------------------------------------------------

# This script may be too heavy to old processors! The Awesome Light Effects was

# tested on a Core 2 Duo E4500 and on a Core i5, without any lag. However,

# there's other factors that may influence the script performance:

#

# 1. Map size

# This script searches surfaces on the map, in order to cut the light pictures.

# In a huge map, the number of surfaces may increase a lot, affecting the

# DYNAMIC LIGHT SOURCE only. Map size does not influence the static sources.

#

# 2. Number of effects

# This script draws the effects on the screen, but before drawing, it checks

# if the effect is out of screen (in this case, the script will skip the

# light drawing). Too much effects may cause lag, but this is just a prevision.

#

# 3. Effect's picture size

# The picture size of the DYNAMIC LIGHT SOURCE influences directly on your

# game's performace. The bigger is the picture, the slower it will be to

# draw it dynamically. The recommended maximum size is 200x200 pixels

#

#-------------------------------------------------------------------------------

# * WARNING - Light pictures

#-------------------------------------------------------------------------------

# In order to run this script correctly, the light pictures MUST obey the

# following conditions:

# 1. The picture's size MUST be multiple of 2. Example: 150x150

# 2. The picture's width MUST be equal to it's height. Example: 156x156

# 3. The picture's colors MUST be inverted! This is necessary because

#    the script inverts the colors to draw the effect. The black color

#    will be transparent!

#

#-------------------------------------------------------------------------------

# * Instructions - 1. Setup your effects!

#-------------------------------------------------------------------------------

# In order to setup your static effects, go to the setup part and define your

# effects inside the Effects hash. Do as the following mode:

#

# X => [picture,opacity,variation,cut],   <= Remember to put a comma here!

#

# Where:

# picture => Picture's name, inside the Graphics/Lights folder;

# opacity => Effect's opacity;

# variation => Effect's opacity variation;

# cut => Put true to cut the effect or false to don't;

# X => The effect's ID, it will be used on events.

#

# Check the default effects to understand how they work.

#

#-------------------------------------------------------------------------------

# * Instructions - 2. Use your effects!

#-------------------------------------------------------------------------------

# In order to use a effect, put the following comment on a event:

#

# [light x]

#

# Where x must be the Effect's ID.

#

#-------------------------------------------------------------------------------

# * Instructions - 3. Use an awesome lantern!

#-------------------------------------------------------------------------------

# The dynamic light source (lantern) is initialized invisible by default.

# You may call the following commands:

#

# l = $game_map.lantern

# Gets the lantern into a variable

 

# l.set_graphic(i)

# Sets the lantern's graphic to i, where i must be the picture's file name on

# Graphics/Lights folder.

#

# l.set_multiple_graphics(h)

# Sets the lantern's graphics to h, where h must be a hash with the following

# structure:

#

# h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"}

#

# Where:

# "ld" is the name of the picture when the lantern's owner is looking down;

# "ll" is the name of the picture when the lantern's owner is looking left;

# "lr" is the name of the picture when the lantern's owner is looking right;

# "lu" is the name of the picture when the lantern's owner is looking up.

#

# l.change_owner(char)

# Sets the lantern's owner to char. Char must be ONE of the following commands:

# $game_player           <= The player itself;

# self_event             <= The event where the command was called;

# $game_map.events[x]    <= The event ID x.

#

# l.set_opacity(o,p)

# Sets the lantern's opacity, where:

# o is the opacity itself;

# p is the opacity variation.

#

# l.show

# After setting the lantern with the commands above, you may set it to visible

# using this command.

#

# l.hide

# Use this command to set the lantern as invisible.

#

#-------------------------------------------------------------------------------

# * Instructions - 4. Use the effect's surface!

#-------------------------------------------------------------------------------

# The Awesome Light Effects draws the effects on a surface. In order to make

# the effects visible, the effect's surface MUST be visible. The Effect's

# Surface is initialized with it's opacity set to zero. You can call the

# following commands:

#

# s = $game_map.effect_surface

# Gets the Effect's Surface into a variable

#

# s.set_color(r,g, B)

# Changes the Effect's Surface color instantly, where:

# r => red level;

# g => green level;

# b => blue level;

#

# s.set_alpha(a)

# Changes the Effect's Surface opacity instantly to a.

#

# s.change_color(time,r,g, B)

# Changes the Effect's Surface color ONLY in a certain time, where:

# time => The change's time (frames);

# r => red level;

# g => green level;

# b => blue level;

#

# s.change_color(time,r,g,b,a)

# Changes the Effect's Surface color and it's opacity in a certain time, where:

# time => The change's time (frames);

# r => red level;

# g => green level;

# b => blue level;

# a => opacity

#

# s.change_alpha(time,a)

# Changes the Effect's Surface opacity in a certain time, where:

# time => The change's time (frames);

# a => opacity

#

#-------------------------------------------------------------------------------

# * Instructions - 5. Use the effect's surface with Tone command!

#-------------------------------------------------------------------------------

# You can access the Effect's Surface with the "Screen Tone" command. In order

# to turn this feature on, set the "Surface_UE" constant to true.

#

# If you decided to use this feature, please note some details:

# 1. The colors values must be between 0 and 255;

# 2. The time is in frames;

# 3. The "gray" value will be sent as the opacity value

#

#-------------------------------------------------------------------------------

# * Instructions - 6. Setup your Tileset Tags!

#-------------------------------------------------------------------------------

# In order to cut the effect's picture correctly, there's 3 types of behavior

# for a tile: wall, block and roof. Walls will make shadows as real walls,

# blocks as blocks and roofs as roofs. So, the tileset tags MUST be configured.

# Check the demo to understand how this system works. If the tilesets aren't

# configured correctly, the script won't cut the effects correctly.

#

#-------------------------------------------------------------------------------

# * Setup Part

#-------------------------------------------------------------------------------

module Light_Core

  Effects = { #  <= DON'T change this!

#-------------------------------------------------------------------------------

# PUT YOUR EFFECTS HERE!

#-------------------------------------------------------------------------------

  #0 => ["light",255,0,true],

  1 => ["torch",200,20,true],

  2 => ["torch_small",180,30,true],

  3 => ["light_mid",255,0,true],

  4 => ["fireplace",200,20,false],

  0 => ["window",255,0,false],

 

#-------------------------------------------------------------------------------

# End of effecs configuration

#-------------------------------------------------------------------------------

  } #  <= DON'T change this!

 

  # Z coordinate of the Effect's Surface

  Surface_Z = 100

 

  # Enable Effect's Surface control by "Screen Tone" command?

  Surface_UE = false

 

  # Roof behavior tag

  Roof_Tag = 5

  # Wall behavior tag

  Wall_Tag = 6

  # Block behavior tag

  Block_Tag = 7

 

  # Don't change this!

  ACC = Math.tan(Math::PI/26)

end

#-------------------------------------------------------------------------------

# Script

#-------------------------------------------------------------------------------

module Cache

  def self.light(filename)

    load_bitmap("Graphics/Lights/", filename)

  end

end

 

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 = Cache.light(@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 = Cache.light(@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}

    @bitmap = {

      2=>Cache.light(@key[2]).clone,

      4=>Cache.light(@key[4]).clone,

      6=>Cache.light(@key[6]).clone,

      8=>Cache.light(@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

    @bitmap = {

      2=>Cache.light(@key[2]).clone,

      4=>Cache.light(@key[4]).clone,

      6=>Cache.light(@key[6]).clone,

      8=>Cache.light(@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?

    @bitmap = {

      2=>Cache.light(@key[2]).clone,

      4=>Cache.light(@key[4]).clone,

      6=>Cache.light(@key[6]).clone,

      8=>Cache.light(@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 if $game_map.light_surface

    @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

    @effect_surface.set_alpha(0) if @effect_surface

    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 > Graphics.width && sy > Graphics.height && 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 if $game_map.effect_surface.alpha > 0

  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,Graphics.width, Graphics.height,$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(Graphics.width, Graphics.height)

    $game_map.light_surface.bitmap.fill_rect(0,0,Graphics.width, Graphics.height,$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

 

Share this post


Link to post
Share on other sites

The following error occurs when I try to run the game( after setting up the script):

 

Script"Khas Awesome Light Effects'line 952:NoMethodError occurred.

 

undefined method'restore'for nil:NilClass

 

 

Anyone has any idea of what this is?

Edited by zenarium

Share this post


Link to post
Share on other sites

Someone help me please.

 

I paste the script from the demo to my game and wrote light 1 on a comment but when I try to play the game the error I wrote above occurs.

Share this post


Link to post
Share on other sites

You know I was having problems with fades and priority and I realized that the $game_map.light_surface sprite has no viewport set! If you change the "$game_map.light_surface = Sprite.new" line into "$game_map.light_surface = Sprite.new(@viewport1)" you don't have to worry as much about priority! Oddly I had to add the line "return unless $game_map.light_surface" at the top of Spriteset_Map's update_lights method though... I guess it get's freed prematurely sometimes. Oh! And I also had to swap the order of the two lines in Spriteset_Map's initialize method.

 

Try this version out if you want:

 

 

#-------------------------------------------------------------------------------

# * [ACE] Khas Awesome Light Effects

#-------------------------------------------------------------------------------

# * By Khas Arcthunder - arcthunder.site40.net

# * Version: 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),

#    send an email to nilokruch@live.com with your request;

# 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

#

#-------------------------------------------------------------------------------

# * Features

#-------------------------------------------------------------------------------

# - Realistic Light

# - Light does not pass over walls, blocks and roofs

# - Static Light Sources

# - Dynamic Light Sources (like a player's lantern)

# - Multiple effects

# - Easy to use (comments)

#

#-------------------------------------------------------------------------------

# * WARNING - Performance

#-------------------------------------------------------------------------------

# This script may be too heavy to old processors! The Awesome Light Effects was

# tested on a Core 2 Duo E4500 and on a Core i5, without any lag. However,

# there's other factors that may influence the script performance:

#

# 1. Map size

# This script searches surfaces on the map, in order to cut the light pictures.

# In a huge map, the number of surfaces may increase a lot, affecting the

# DYNAMIC LIGHT SOURCE only. Map size does not influence the static sources.

#

# 2. Number of effects

# This script draws the effects on the screen, but before drawing, it checks

# if the effect is out of screen (in this case, the script will skip the

# light drawing). Too much effects may cause lag, but this is just a prevision.

#

# 3. Effect's picture size

# The picture size of the DYNAMIC LIGHT SOURCE influences directly on your

# game's performace. The bigger is the picture, the slower it will be to

# draw it dynamically. The recommended maximum size is 200x200 pixels

#

#-------------------------------------------------------------------------------

# * WARNING - Light pictures

#-------------------------------------------------------------------------------

# In order to run this script correctly, the light pictures MUST obey the

# following conditions:

# 1. The picture's size MUST be multiple of 2. Example: 150x150

# 2. The picture's width MUST be equal to it's height. Example: 156x156

# 3. The picture's colors MUST be inverted! This is necessary because

#    the script inverts the colors to draw the effect. The black color

#    will be transparent!

#

#-------------------------------------------------------------------------------

# * Instructions - 1. Setup your effects!

#-------------------------------------------------------------------------------

# In order to setup your static effects, go to the setup part and define your

# effects inside the Effects hash. Do as the following mode:

#

# X => [picture,opacity,variation,cut],   <= Remember to put a comma here!

#

# Where:

# picture => Picture's name, inside the Graphics/Lights folder;

# opacity => Effect's opacity;

# variation => Effect's opacity variation;

# cut => Put true to cut the effect or false to don't;

# X => The effect's ID, it will be used on events.

#

# Check the default effects to understand how they work.

#

#-------------------------------------------------------------------------------

# * Instructions - 2. Use your effects!

#-------------------------------------------------------------------------------

# In order to use a effect, put the following comment on a event:

#

# [light x]

#

# Where x must be the Effect's ID.

#

#-------------------------------------------------------------------------------

# * Instructions - 3. Use an awesome lantern!

#-------------------------------------------------------------------------------

# The dynamic light source (lantern) is initialized invisible by default.

# You may call the following commands:

#

# l = $game_map.lantern

# Gets the lantern into a variable

 

# l.set_graphic(i)

# Sets the lantern's graphic to i, where i must be the picture's file name on

# Graphics/Lights folder.

#

# l.set_multiple_graphics(h)

# Sets the lantern's graphics to h, where h must be a hash with the following

# structure:

#

# h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"}

#

# Where:

# "ld" is the name of the picture when the lantern's owner is looking down;

# "ll" is the name of the picture when the lantern's owner is looking left;

# "lr" is the name of the picture when the lantern's owner is looking right;

# "lu" is the name of the picture when the lantern's owner is looking up.

#

# l.change_owner(char)

# Sets the lantern's owner to char. Char must be ONE of the following commands:

# $game_player           <= The player itself;

# self_event             <= The event where the command was called;

# $game_map.events[x]    <= The event ID x.

#

# l.set_opacity(o,p)

# Sets the lantern's opacity, where:

# o is the opacity itself;

# p is the opacity variation.

#

# l.show

# After setting the lantern with the commands above, you may set it to visible

# using this command.

#

# l.hide

# Use this command to set the lantern as invisible.

#

#-------------------------------------------------------------------------------

# * Instructions - 4. Use the effect's surface!

#-------------------------------------------------------------------------------

# The Awesome Light Effects draws the effects on a surface. In order to make

# the effects visible, the effect's surface MUST be visible. The Effect's

# Surface is initialized with it's opacity set to zero. You can call the

# following commands:

#

# s = $game_map.effect_surface

# Gets the Effect's Surface into a variable

#

# s.set_color(r,g, B)

# Changes the Effect's Surface color instantly, where:

# r => red level;

# g => green level;

# b => blue level;

#

# s.set_alpha(a)

# Changes the Effect's Surface opacity instantly to a.

#

# s.change_color(time,r,g, B)

# Changes the Effect's Surface color ONLY in a certain time, where:

# time => The change's time (frames);

# r => red level;

# g => green level;

# b => blue level;

#

# s.change_color(time,r,g,b,a)

# Changes the Effect's Surface color and it's opacity in a certain time, where:

# time => The change's time (frames);

# r => red level;

# g => green level;

# b => blue level;

# a => opacity

#

# s.change_alpha(time,a)

# Changes the Effect's Surface opacity in a certain time, where:

# time => The change's time (frames);

# a => opacity

#

#-------------------------------------------------------------------------------

# * Instructions - 5. Use the effect's surface with Tone command!

#-------------------------------------------------------------------------------

# You can access the Effect's Surface with the "Screen Tone" command. In order

# to turn this feature on, set the "Surface_UE" constant to true.

#

# If you decided to use this feature, please note some details:

# 1. The colors values must be between 0 and 255;

# 2. The time is in frames;

# 3. The "gray" value will be sent as the opacity value

#

#-------------------------------------------------------------------------------

# * Instructions - 6. Setup your Tileset Tags!

#-------------------------------------------------------------------------------

# In order to cut the effect's picture correctly, there's 3 types of behavior

# for a tile: wall, block and roof. Walls will make shadows as real walls,

# blocks as blocks and roofs as roofs. So, the tileset tags MUST be configured.

# Check the demo to understand how this system works. If the tilesets aren't

# configured correctly, the script won't cut the effects correctly.

#

#-------------------------------------------------------------------------------

# * Setup Part

#-------------------------------------------------------------------------------

module Light_Core

  Effects = { #  <= DON'T change this!

#-------------------------------------------------------------------------------

# PUT YOUR EFFECTS HERE!

#-------------------------------------------------------------------------------

  #0 => ["light",255,0,true],

  1 => ["torch",200,20,true],

  2 => ["torch_small",180,30,true],

  3 => ["light_mid",255,0,true],

  4 => ["fireplace",200,20,false],

  0 => ["window",255,0,false],

 

#-------------------------------------------------------------------------------

# End of effecs configuration

#-------------------------------------------------------------------------------

  } #  <= DON'T change this!

 

  # Z coordinate of the Effect's Surface

  Surface_Z = 1000

 

  # Enable Effect's Surface control by "Screen Tone" command?

  Surface_UE = false

 

  # Roof behavior tag

  Roof_Tag = 5

  # Wall behavior tag

  Wall_Tag = 6

  # Block behavior tag

  Block_Tag = 7

 

  # Don't change this!

  ACC = Math.tan(Math::PI/26)

end

#-------------------------------------------------------------------------------

# Script

#-------------------------------------------------------------------------------

module Cache

  def self.light(filename)

    load_bitmap("Graphics/Lights/", filename)

  end

end

 

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 = Cache.light(@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 = Cache.light(@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}

    @bitmap = {

      2=>Cache.light(@key[2]).clone,

      4=>Cache.light(@key[4]).clone,

      6=>Cache.light(@key[6]).clone,

      8=>Cache.light(@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

    @bitmap = {

      2=>Cache.light(@key[2]).clone,

      4=>Cache.light(@key[4]).clone,

      6=>Cache.light(@key[6]).clone,

      8=>Cache.light(@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?

    @bitmap = {

      2=>Cache.light(@key[2]).clone,

      4=>Cache.light(@key[4]).clone,

      6=>Cache.light(@key[6]).clone,

      8=>Cache.light(@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 if $game_map.light_surface

    @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

    @effect_surface.set_alpha(0) if @effect_surface

    @lantern.hide

    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 > Graphics.width && sy > Graphics.height && 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

    kbl_initialize

    setup_lights

  end

 

  def update

    kbl_update

    update_lights if $game_map.effect_surface.alpha > 0

  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

    return unless $game_map.light_surface

    $game_map.light_surface.bitmap.clear

    $game_map.light_surface.bitmap.fill_rect(0,0,Graphics.width, Graphics.height,$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(@viewport1)

    $game_map.light_surface.bitmap = Bitmap.new(Graphics.width, Graphics.height)

    $game_map.light_surface.bitmap.fill_rect(0,0,Graphics.width, Graphics.height,$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

 

Share this post


Link to post
Share on other sites
Khas really needs to update the script so that choice box commands don't have the same tint as the background when using this script. :\

 

I am still having the same problem, does anyone know how to fix this ?

 

post-18572-0-74550900-1359196085_thumb.png

 

---------

EDIT: fixed

Edited by CompassNL

Share this post


Link to post
Share on other sites

I put the z surface at 100, that should solve it.

 

Though you can go lower, I went all the way down to 2 and it didn't really seem to affect anything.

Share this post


Link to post
Share on other sites

Really it probably should be under 50 I guess. Higher then 50 and it may tint pictures and weather effects. I made a version above that forces it into the same viewport as the map and characters, but I guess the sprite can just be rendered between viewports 1 and 2...

 

Honestly I kind of think Khas isn't around anymore, though I may be wrong.

Edited by KilloZapit

Share this post


Link to post
Share on other sites

Technical question here...

 

Does anyone know the exact scripting you'd have to put on a moving event so that it casts light by itself?

 

I have a dark spell shop that I want light by these walking balls of blue light.  I have the blue light color they're going to emit.  So I can change that bit of the coding to point to that image file.  But I can't make them cast light and walk.  If I use the light 4 command -which is what I have the blue light set to- it lights up their starting position but doesn't move with them  If I use the lantern code and set it to be owned by the event itself, it works and then stops but I was using it WITH the light 4 command.  Which left it casting light at it's starting position AND it's moving position.  I removed the light 4 command from the moving event and it stopped casting any light at all. 

 

What am I doing wrong?

Share this post


Link to post
Share on other sites

You can't do that normally with this... but here is a little addon script to do it if you want!

 

 

#-------------------------------------------------------------------------------
# * Dynamic Lights Addon for Khas Awesome Light Effects
#-------------------------------------------------------------------------------
# just use [dlight x] instead of [light x]
#-------------------------------------------------------------------------------

class Light_SSource

  def draw
    sx = self.sx
    sy = self.sy
    w = self.w
    h = self.h
    return if sx > Graphics.width && sy > Graphics.height && 
              sx + w < 0 && sy + h < 0
    $game_map.light_surface.bitmap.blt(sx, sy, self.bitmap,
                                       Rect.new(0,0,w,h), self.opacity)
  end

end

class Light_DSource < Light_SSource

  def set_shadow(shadow)
    @skip_shadow = !shadow
  end

  def draw
    btr = self.get_graphic
    x = self.x
    y = self.y
    r = self.range
    sx = x + r
    sy = y + r
    dr = r*2
    $game_map.surfaces.each do |s|
      if s.visible?(sx,sy) && s.within?(x,x+dr,y,y+dr)
        s.render_shadow(x,y,sx,sy,r,btr)
      end
    end unless @skip_shadow
    $game_map.light_surface.bitmap.blt(self.sx, self.sy, btr,
                                       Rect.new(0,0,dr,dr), self.opacity)
    btr.dispose
  end

end

class Game_Character < Game_CharacterBase

  def set_dlight(light_gfx = nil, light_alpha = 255, 
                 light_flicker = 0, light_shadow = true)
    if light_gfx
      @light = Light_DSource.new unless @light
      @light.change_owner(self)
      @light.set_graphic(light_gfx)
      @light.set_opacity(light_alpha, light_flicker)
      @light.set_shadow(light_shadow)
      @light.show
      $game_map.light_sources |= [self]
    else
      @light.dispose
      @light = nil
      $game_map.light_sources.delete(self)
    end
  end

  def draw_light
    @light.draw if @light
  end

  def dispose_light
    @light.dispose
  end

  def restore_light
    @light.restore
  end

end

class Game_Event < Game_Character

  alias_method :setup_light_dynamic_base, :setup_light
  def setup_light(dispose)
    setup_light_dynamic_base(dispose)
    unless dispose && @list.nil?
      for command in @list
        if command.code == 108 && command.parameters[0].include?("[dlight")
          command.parameters[0].scan(/\[dlight\s*(\d+)\s*\]/)
          effect = Light_Core::Effects[$1.to_i]
          set_dlight(effect[0],effect[1],effect[2],effect[3])
          return
        end
      end
    end
  end


  def draw_light
    super
  end

  def dispose_light
    super
  end

  def restore_light
    super
  end

end

class Spriteset_Map

  def update_lights
    return unless $game_map.light_surface
    $game_map.light_surface.bitmap.clear
    $game_map.light_surface.bitmap.fill_rect(0,0,Graphics.width, Graphics.height,$game_map.effect_surface.color)
    $game_map.light_sources.each { |source| source.draw_light }
    $game_map.lantern.draw if $game_map.lantern.visible
  end

end

 

Edited by KilloZapit

Share this post


Link to post
Share on other sites

Do I add this to the end of Khas' script or just add it as a totally new script?

 

I see where I have to change the image's height and width.   Where do I plug in the image location? 

 

-hasn't been up very long so appologizes for being a little slow-

 

And THANK YOU. 

 

Thank you.  That worked perfectly.  I figured out to add it as it's own script, and just use the coding you indicated in the right place.  The little blue fire balls move and the light moves with them.  -HUGS-  Thank you greatly for helping me on this!

Edited by Notsalony

Share this post


Link to post
Share on other sites

You can put it in a new script under Khas's script. You shouldn't need to enter the image width or height at all! What are you looking at there?

Share this post


Link to post
Share on other sites

Oh I was looking at the h<0 and w<0 and thinking the WRONG things.  I changed nothing of your code and inputted it just under his code and it worked wonderfully.  Sorry for the confusion.  I'm a bit obtuse when I first wake up.  I really aught not to try to code this early in the morning.  -yawns-  But the lighting works perfectly.

 

Just one question.  What exactly is the code to shut off the lighting script when you leave a room.  Right now I've got it set as an event touch switch so that when you walk into a room it grows darker, then when you walk that same way out it turns the settnigs to 255,255,255,255.  But that's not off, that's just full light again.

 

I'm primarily using it in basements and in buildings.  But I'm not wanting the outside world dark, right now.  Later on I might take the time to set up day and night time.

Share this post


Link to post
Share on other sites

Alright. So, uh, I read through everything, though I might have missed something, so I'm sorry if I have- my computer won't let me onto Khas's blog (tried all that I could think of, just know it isn't my firewalls), so I can't get the lighting file. If anyone could put a link or something directly to the mediafire download, that would be fantastic.

Share this post


Link to post
Share on other sites

I am getting a 403 error when going to the site myself... you could just make the bitmaps yourself if you needed to I guess...

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • Recently Browsing   0 members

    No registered users viewing this page.

×
Top ArrowTop Arrow Highlighted