Плохо! Плохо!:  0
Страница 1 из 3 123 ПоследняяПоследняя
Показано с 1 по 10 из 30

Тема: Khas Awesome Light Effects

  1. #1
    Бывалый Аватар для caveman
    Информация о пользователе
    Регистрация
    15.02.2013
    Сообщений
    766
    Записей в дневнике
    47
    Репутация: 85 Добавить или отнять репутацию

    По умолчанию Khas Awesome Light Effects

    Khas Awesome Light Effects
    Авторы: Khas Arcthunder, caveman
    Версия: 1.1
    Тип: Создание световых эффектов




    Описание:

    Продвинутый скрипт для создания световых эффектов. Можно создать, как статический источник света (лампа), так и динамический (фонарик).

    Особенности:

    • Реалистичный свет
    • Свет не проходит через стены, потолки и препятствия (при условии настройки тегов)
    • Статические источники света
    • Динамические источники света (типа игрока с лампой)
    • Множественные эффекты (подразумевается, что можно подвесить несколько световых эффектов на разные положения события - например, реализовать фонарик)
    • Легкость в использовании


    Использование:

    Читайте инструкцию в самом скрипте.

    Скрипт:

    Спойлер Русская версия:

    Код:
    #-------------------------------------------------------------------------------
    # * [XP] Офигенные световые эффекты Кхаса
    #-------------------------------------------------------------------------------
    # * By Khas Arcthunder - arcthunder.site40.net
    # * Переведен и конвертирован под XP - caveman
    # * Версия: 1.1 RU
    # * Создан: 17/04/2013
    # *
    # * Изменение 1.0 -> 1.1 от 19/04/2013 от caveman
    # * В настройки добавлен параметр R_G, отвечающий за грубость теней => за
    #   скорость работы скрипта.
    #
    #-------------------------------------------------------------------------------
    # * Лицензии и благодарности автору, то есть Кхасу
    #-------------------------------------------------------------------------------
    # При использовании данного скрипта вы автоматически соглашаетесь с тем, что:
    # 1. Вы должны упомянуть в титрах автора;
    # 2. Все скрипты Кхаса находятся под защитой Creative Commons license;
    # 3. Все скрипты Кхаса только для некоммерческого использования. 
    #    Если вы хотите использовать скритпы для вашего коммерческого проекта,
    #    пошлите письмо на nilokruch@live.com с заявкой, и Великий, быть может
    #    одобрит ваш проект
    # 4. Все скрипты Кхаса только для личного использования, вы можете использовать
    #    и редактировать их для под свои нужды, но вам нельзя публиковать
    #    модифицированные версии скрипта.
    #    FUCK YOU, Khas!!!
    # 5. Если вы постите скрипт Кхаса, вы не должны ставить себя в создатели. О как;
    # 6. Если вы хотите запостить скрипт Кхаса - то постите только прямой линк
    #    на сайт Великого arcthunder.site40.net
    #
    #-------------------------------------------------------------------------------
    # * Фичи
    #-------------------------------------------------------------------------------
    # - Реалистичный свет
    # - Свет не проходит через стены, потолки и препятствия (при условии настройки тегов)
    # - Статические истончники света
    # - Динамические источники света (типа игрока с лампой)
    # - Множественные эффекты (подразумевается, что можно подвесить несколько
    #   световых эффектов на разные положения события - например, реализовать фонарик)
    # - Легкость в использовании
    #
    #-------------------------------------------------------------------------------
    # * ВНИМАНИЕ - могут быть проблемы с производительностью
    #-------------------------------------------------------------------------------
    # Тут Кхас утверждает, что скрипт может тормозить на старых процессорах. 
    # Как и автор, я тестил только на i5, все летает - приветствуются комменты
    # от счастливых обладателей различных музейных экспонатов.
    #
    # Возможные источники проблем:
    #
    # 1. Размер карты
    # Так как скрипт бегает по поверхностям карты для обрезания света стенами
    # и прочим, то размер карты влияет на результат - там больше поверхностей.
    # Это верно только для динамических источников света.
    # 
    # Имхо, прямыми руками можно таки смотреть не всю карту, а экран + максимальный
    # размер света - но делать, конечно же лень.
    #
    # 2. Число эффектов
    # Великий все-таки проверяет на попадание в экран статики, но попробуйте запихнуть
    # в один экран кучу источников и посмотрите на тормоза.
    #
    # 3. Размер картинок эффектов
    # Тут все просто, чем больше размер картинок - тем медленнее работают 
    # динамические источники. Автор рекомендует максимум 200x200 пикселей
    # 
    #-------------------------------------------------------------------------------
    # * ВНИМАНИЕ - О картинках для света
    #-------------------------------------------------------------------------------
    # Чтобы скрипт работал корректно, картинки для света долны удовлетворять
    # следующим условиям:
    # 1. Размеры картинки делятся на 2. Например: 150x150
    # 2. Картинки поддерживаются только квадратные (это печаль :(). Например: 156x156
    # 3. Цвета картинок должны быть инвертированы! Черный - прозрачный и наоборот.
    #
    #-------------------------------------------------------------------------------
    # * Инструкция - часть 1. Установите ваши эффекты!
    #-------------------------------------------------------------------------------
    # Для того, чтобы установить статические эффекты, идете в часть установки
    # где-то с 200 строки и заполняете хеш-таблицу как-то так:
    #
    # X => [picture,opacity,variation,cut],   <= не забудьте про запятую в конце
    #
    # Где:
    # picture => название картинки внутри папки Graphics/Lights;
    # opacity => НЕпрозрачность эффекта;
    # variation => Колебания непрозрачности (например, создает эффект дерганья света факела);
    # cut => true - обрезаем эффект на препятствиях;
    # X => ID эффекта (пригодится для установки на события). 
    #
    #-------------------------------------------------------------------------------
    # * Инструкция - часть 2 Используйте ваши эффекты! 
    # (похоже, автор имеет в виду статику)
    #-------------------------------------------------------------------------------
    # Чтобы использовать эффект на событии - просто оставьте в нем коммент:
    # 
    # [light x]
    #
    # Где x - ID эффекта.
    # 
    #-------------------------------------------------------------------------------
    # * Инструкция - часть 3. Используйте офигительные лампы.
    # (тут, очевидно, динамика)
    #-------------------------------------------------------------------------------
    # Лампа (ага! а автор все время динамику во множественном числе упоминает!
    # но, подозреваю, шаловливые ручки могут и это исправить :))
    # по умолчанию невидима. 
    # Вам доступны следущие команды (вводите в событии скриптом):
    # 
    # l = $game_map.lantern
    # Поместить лампу в переменную
     
    # l.set_graphic(i)
    # Проставить лампе графику, i - название файла света в папке Graphics/Lights
    #
    # l.set_multiple_graphics(h)
    # Проставить графику лампе из h, где h - хеш таблица следующей структуры:
    #
    # h = {2=>"ld",4=>"ll",6=>"lr",8=>"lu"}
    # 
    # Где: 
    # "ld" название картинки, если событие смотрит вниз;
    # "ll" название картинки, если событие смотрит влево;
    # "lr" название картинки, если событие смотрит вправо;
    # "lu" название картинки, если событие смотрит вверх;
    #
    # l.change_owner(char)
    # Проставить обладателя лампы. Char - одна из следующих команд:
    # $game_player           <= игрок;
    # self_event             <= событие, из которого вызвали эту команду;
    # $game_map.events[x]    <= ID некоторого события;
    #
    # l.set_opacity(o,p)
    # Проставить лампе непрозрачность:
    # o непрозрачность эффекта;
    # p некий рандом - для "живого" моргания света.
    #
    # l.show
    # Сделать, наконец, эффект видимым
    #
    # l.hide
    # Сделать эффект невидимым
    #
    #-------------------------------------------------------------------------------
    # * Инструкция - часть 4. Используйте эффекты поверхностей!
    #-------------------------------------------------------------------------------
    # Офигенные световые эффекты Кхаса могут применять некоторые эффекты поверхности к карте,
    # естественно, для этого поверхность должна быть видимой.
    # Поверхность инициализируется с непрозрачностью = 0, но вы можете вызвать следующие команды
    # (caveman: в общем это нечто вроде картинки поверх (как настроите Surface_Z) карты, на которой
    # и будет рисоваться свет и тени
    #
    # s = $game_map.effect_surface
    # Поместить поверхность в переменную
    #
    # s.set_color(r,g,b)
    # Задать поверхности цвет
    # r => красный;
    # g => зеленый;
    # b => синий;
    #
    # s.set_alpha(a)
    # Изменить непрозрачность поверхности
    #
    # s.change_color(time,r,g,b)
    # Постепенно изменить цвет поверхности (за время time)
    # time => время изменения (в фреймах);
    # r => красный;
    # g => зеленый;
    # b => синий;
    #
    # s.change_color(time,r,g,b,a)
    # Постепенно изменить цвет поверхности и её непрозрачность (за время time)
    # time => время изменения (в фреймах);
    # r => красный;
    # g => зеленый;
    # b => синий;
    # a => непрозрачность;
    #
    # s.change_alpha(time,a)
    # Постепенно изменить непрозрачность поверхности (за время time)
    # time => время изменения (в фреймах);
    # a => непрозрачность;
    #
    #-------------------------------------------------------------------------------
    # * Инструкция - часть 5. Используйте эффект поверхности с комендой Tone!
    #-------------------------------------------------------------------------------
    # Если вы проставите в настройках скрипта Surface_UE = true, то можете
    # доступаться до эффекта поверхности при помощи обычной команды "Screen Tone",
    # а не дергать скрипты руками
    #
    # Некоторые замечания:
    # 1. Значения цветов должны лежать между 0 и 255;
    # 2. Время - в фреймах;
    # 3. Серый цвет (полоска внизу) означает непрозрачность
    #
    #-------------------------------------------------------------------------------
    # * Инструкция - часть 5. Проставьте теги вашим тайлсетам!
    #-------------------------------------------------------------------------------
    # Чтобы нормально обрезать свет и показывать тени, в вашем тайлсете нужно отметить тегами, 
    # что есть стена, что - крыша, а что просто блок
    # Стена генерирует тени, как реальная стена, блоки как блоки и крыша как крыша.
    # В стандартной настройке надо стенам проставить 5, крыше - 6 и блокам - 7
    # 
    #-------------------------------------------------------------------------------
    # * Настройки
    #-------------------------------------------------------------------------------
    module Light_Core
      Effects = { #  <= Не изменяйте это!
    #-------------------------------------------------------------------------------
    # Если хотите добавить свои эффекты - то дополняйте список! (см "Инструкция - часть 1.")
    #-------------------------------------------------------------------------------
      0 => ["light",255,0,true],
      1 => ["torch",180,20,true],
      2 => ["torch_m",180,30,true],
      3 => ["light_s",255,0,true],
     
    #-------------------------------------------------------------------------------
    # Конец настроек эффектов
    #------------------------------------------------------------------------------- 
      } #  <= Не изменяйте это!
     
      # Z координата поверхности
      Surface_Z = 180
     
      # см "Инструкция - часть 5."
      Surface_UE = true
     
      # Тег крыши
      Roof_Tag = 5
      # Тег стены - свет падает на стену и стена генерирует тени
      Wall_Tag = 6
      # Тег блока, через который свет не пройдет. 
      # Судя по использованию в VX, в XP нужно этот тег проставлять автотайлу "крыши".
      # Например, в подземелье черный обрис вокруг комнаты.
      Block_Tag = 7
     
      # Не изменяйте это!
      ACC = Math.tan(Math::PI/26)
      
      # грубость теней (1 - идеал, чем больше - тем хуже и быстрей)
      R_G = 1
    end
     
     
    # всякие вспомогательные штуки
    module Cache
     
      #--------------------------------------------------------------------------
      # ● загрузка картинки по пути
      #--------------------------------------------------------------------------
      def self.load_bitmap(folder_name, filename, hue = 0)
        @cache ||= {}
        if filename.empty?
          empty_bitmap
        elsif hue == 0
          normal_bitmap(folder_name + filename)
        else
          hue_changed_bitmap(folder_name + filename, hue)
        end
      end
     
      #--------------------------------------------------------------------------
      # ● Пустая картинка, вместо nil 
      #--------------------------------------------------------------------------
      def self.empty_bitmap
        Bitmap.new(32, 32)
      end
     
      #--------------------------------------------------------------------------
      # ● Загрузка обычной картинки
      #--------------------------------------------------------------------------
      def self.normal_bitmap(path)
        @cache[path] = Bitmap.new(path) unless include?(path)
        @cache[path]
      end
     
      #--------------------------------------------------------------------------
      # ● Загрузка с измененной HUE
      #--------------------------------------------------------------------------
      def self.hue_changed_bitmap(path, hue)
        key = [path, hue]
        unless include?(key)
          @cache[key] = normal_bitmap(path).clone
          @cache[key].hue_change(hue)
        end
        @cache[key]
      end
     
      #--------------------------------------------------------------------------
      # ● include?
      #--------------------------------------------------------------------------
      def self.include?(key)
        @cache[key] && !@cache[key].disposed?
      end
     
      #--------------------------------------------------------------------------
      # ● Очистка
      #--------------------------------------------------------------------------
      def self.clear
        @cache ||= {}
        @cache.clear
        GC.start # хоть кто-то юзает в руби GC!!!
      end
    end
     
    class Game_Map
      alias kdi_setup setup
      def setup(map_id)
        @map_id = map_id
        @map = load_data(sprintf("Data/Map%03d.rxdata", @map_id))
        tileset = $data_tilesets[@map.tileset_id]
        @tileset_name = tileset.tileset_name
        @autotile_names = tileset.autotile_names
        @panorama_name = tileset.panorama_name
        @panorama_hue = tileset.panorama_hue
        $game_system.scroll_x = 0
        $game_system.scroll_y = 0
        @fog_name = tileset.fog_name
        @fog_hue = tileset.fog_hue
        @fog_opacity = tileset.fog_opacity
        @fog_blend_type = tileset.fog_blend_type
        @fog_zoom = tileset.fog_zoom
        @fog_sx = tileset.fog_sx
        @fog_sy = tileset.fog_sy
        @battleback_name = tileset.battleback_name
        @passages = tileset.passages
        @priorities = tileset.priorities
        @terrain_tags = tileset.terrain_tags
        @display_x = 0
        @display_y = 0
        @need_refresh = false
     
        # вынесено в отдельный метод, чтобы в главном скрипте переопределить
        setup_events 
     
        @fog_ox = 0
        @fog_oy = 0
        @fog_tone = Tone.new(0, 0, 0, 0)
        @fog_tone_target = Tone.new(0, 0, 0, 0)
        @fog_tone_duration = 0
        @fog_opacity_duration = 0
        @fog_opacity_target = 0
        @scroll_direction = 2
        @scroll_rest = 0
        @scroll_speed = 4
      end
     
      def setup_events
        @events = {}
        for i in @map.events.keys
          @events[i] = Game_Event.new(@map_id, @map.events[i])
        end
        @common_events = {}
        for i in 1...$data_common_events.size
          @common_events[i] = Game_CommonEvent.new(i)
        end
      end
     
      #--------------------------------------------------------------------------
      # ● число тайлов на экране по X
      #--------------------------------------------------------------------------
      def screen_tile_x
        20 #Graphics.width / 32
      end
      #--------------------------------------------------------------------------
      # ● число тайлов на экране по Y
      #--------------------------------------------------------------------------
      def screen_tile_y
        15 #Graphics.height / 32
      end
     
      #--------------------------------------------------------------------------
      # ● Маленькая выравнивалка карты по X
      #--------------------------------------------------------------------------
      def adjust_x(x)
        d_x = @display_x
        if x < d_x - (width - screen_tile_x) * 128
          return x - d_x + @map.width * 128
        else
          return x - d_x
        end
      end
      #--------------------------------------------------------------------------
      # ● Маленькая выравнивалка карты по Y
      #--------------------------------------------------------------------------
      def adjust_y(y)
        d_y = @display_y
        if y < d_y - (height - screen_tile_y) * 128
          return y - d_y + @map.height * 128
        else
          return y - d_y
        end
      end
    end
     
     
    #-------------------------------------------------------------------------------
    # Скрипт
    #-------------------------------------------------------------------------------
    module Cache
      def self.light(filename)
        load_bitmap("Graphics/Lights/", filename)
      end
    end
     
    module Light_Bitcore
      include Light_Core
      def self.initialize
        @@buffer = {}
        Effects.values.each { |effect| Light_Bitcore.push(effect[0])}
      end
     
      def self::[](key)
        return @@buffer[key]
      end
     
      def self.push(key)
        return if @@buffer.keys.include?(key)
        @@buffer[key] = Cache.light(key)
      end
    end
     
    Light_Bitcore.initialize
    #-------------------------------------------------------------------------------
    # Класс - статический источник света
    #-------------------------------------------------------------------------------
    class Light_SSource
      attr_reader :real_x
      attr_reader :real_y
      attr_reader :range
      attr_accessor :bitmap
      attr_reader :w
      attr_reader :h
      attr_reader :hs
     
      def initialize(char,bitmap,opacity,plus,hs)
        sync(char)
        @key = bitmap
        @bitmap = Light_Bitcore[@key].clone
        @range = @bitmap.width/2
        @w = @bitmap.width
        @h = @bitmap.height
        @mr = @range - 16
        @opacity = opacity
        @plus = plus
        @hs = hs
        render if @hs
      end
     
      def render
        tx = x
        ty = y
        tsx = x + @range
        tsy = y + @range
        dr = @range*2
        #p tx.to_s + " " + ty.to_s 
        for s in $game_map.surfaces
          next if !s.visible?(tsx,tsy) || !s.within?(tx,tx+dr,ty,ty+dr)
          s.render_shadow(tx,ty,tsx,tsy,@range,@bitmap)
        end
      end
     
      def restore
        return unless @bitmap.nil?
        @bitmap = Light_Bitcore[@key].clone
        render if @hs
      end
     
      def opacity
        @plus == 0 ? @opacity : (@opacity + rand(@plus))
      end
     
      def sx
        return $game_map.adjust_x(@real_x) / 4 - @mr
      end
     
      def sy
        return $game_map.adjust_y(@real_y) / 4 - @mr
      end
     
      def sync(char)
        @real_x = char.real_x
        @real_y = char.real_y
      end
     
      def x
        return (@real_x/4 - @mr).to_f
      end
     
      def y
        return (@real_y/4 - @mr).to_f
      end
     
      def dispose
        return if @bitmap.nil?
        @bitmap.dispose
        @bitmap = nil
      end
    end
     
    #-------------------------------------------------------------------------------
    # Класс - динамический источник света
    #-------------------------------------------------------------------------------
    class Light_DSource < Light_SSource
      attr_reader :bitmap
      attr_reader :visible
     
      def initialize
        @key = nil
        @bitmap = nil
        @opacity = 255
        @plus = 0
        @char = $game_player
        @visible = false
      end
     
      def set_opacity(o,p)
        @opacity = o
        @plus = p
      end
     
      def set_graphic(sb)
        dispose
        @key = {2=>sb,4=>sb,6=>sb,8=>sb}
        Light_Bitcore.push(sb)
        @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
        @range = @bitmap[2].width/2
        @w = @bitmap[2].width
        @h = @bitmap[2].height
        @mr = @range - 16
      end
     
      def set_multiple_graphics(ba)
        dispose
        @key = ba
        @key.values.each {|key| Light_Bitcore.push(key)}
        @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
        @range = @bitmap[2].width/2
        @w = @bitmap[2].width
        @h = @bitmap[2].height
        @mr = @range - 16
      end
     
      def get_graphic
        return @bitmap[@char.direction].clone
      end
     
      def show
        return if @bitmap.nil?
        @visible = true
      end
     
      def hide
        @visible = false
      end
     
      def restore
        return if @key.nil?
        @key.values.each {|key| Light_Bitcore.push(key)}
        @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
      end
     
      def dispose
        return if @bitmap.nil?
        @bitmap.values.each { |b| b.dispose }
        @bitmap = nil
      end
     
      def change_owner(char)
        @char = char
      end
     
      def render
      end
     
      def sx
       return $game_map.adjust_x(@char.real_x) / 4 - @mr
      end
     
      def sy
        return $game_map.adjust_y(@char.real_y) / 4 - @mr
      end
     
      def x
        return (@char.real_x/4- @mr).to_f
      end
     
      def y
        return (@char.real_y/4 - @mr).to_f
      end
     
    end
     
    #-------------------------------------------------------------------------------
    # Класс поверхности
    #-------------------------------------------------------------------------------
    class Light_Surface
      def initialize
        @ta = @a = 0
        @tr = @r = 255
        @tg = @g = 255
        @tb = @b = 255
        @va = @vr = @vg = @vb = 0.0
        @timer = 0
      end
     
      def refresh
        return if @timer == 0
        @a += @va
        @r += @vr
        @g += @vg
        @b += @vb
        $game_map.light_surface.opacity = @a
        @timer -= 1
      end
     
      def change_color(time,r,g,b,a=nil)
        r = 0 if r < 0; r = 255 if r > 255
        g = 0 if g < 0; g = 255 if g > 255
        b = 0 if b < 0; b = 255 if b > 255
        unless a.nil?
          a = 0 if a < 0; a = 255 if a > 255
        end
        @timer = time
        @tr = 255-r
        @tg = 255-g
        @tb = 255-b
        @va = (a.nil? ? 0 : (a-@a).to_f/@timer)
        @vr = (@tr - @r).to_f/@timer
        @vg = (@tg - @g).to_f/@timer
        @vb = (@tb - @b).to_f/@timer
      end
     
      def change_alpha(time,a)
        a = 0 if a < 0; a = 255 if a > 255
        @timer = time
        @ta = a
        @vr = @vg = @vb = 0.0
        @va = (a-@a).to_f/@timer
      end
     
      def set_color(r,g,b)
        r = 0 if r < 0; r = 255 if r > 255
        g = 0 if g < 0; g = 255 if g > 255
        b = 0 if b < 0; b = 255 if b > 255
        @tr = @r = 255-r
        @tg = @g = 255-g
        @tb = @b = 255-b
        @va = @vr = @vg = @vb = 0.0
        @timer = 0
      end
     
      def set_alpha(a)
        a = 0 if a < 0; a = 255 if a > 255
        @ta = @a = a
        $game_map.light_surface.opacity = @a
        @va = @vr = @vg = @vb = 0.0
        @timer = 0
      end
     
      def alpha
        return @a
      end
     
      def color
        return Color.new(@r,@g,@b)
      end
    end
     
    class Game_Map
      include Light_Core
      attr_accessor :light_surface
      attr_accessor :light_sources
      attr_accessor :surfaces
      attr_accessor :effect_surface
      attr_accessor :lantern
     
      alias kbl_setup_events setup_events
      alias kbl_initialize initialize
      alias kbl_update update
      def initialize
        kbl_initialize
        @effect_surface = Light_Surface.new
        @lantern = Light_DSource.new
      end
     
      def update
        # TODO тут был аргумент
        @effect_surface.refresh
        kbl_update
      end
     
      def first_tag(x,y)
        tag = terrain_tag(x,y)
        return tag > 0 ? tag : 0
      end
     
      def setup_events
        @light_sources.nil? ? @light_sources = [] : @light_sources.clear
        setup_surfaces
        merge_surfaces
        kbl_setup_events
      end
     
      def tile_id(x, y, z)
        @map.data[x, y, z] || 0
      end
     
      def tile_pass?(x, y, d, k)
        unless valid?(x, y)
          return false
        end
        bit = (1 << (d / 2 - 1)) & 0x0f
     
        tile_id = data[x, y, k]
        if tile_id == nil
          return false
        elsif @passages[tile_id] & bit != 0
          return false
        elsif @passages[tile_id] & 0x0f == 0x0f
          return false
        elsif @priorities[tile_id] == 0
          return true
        end
     
        return true
      end
     
      def tile_pass2?(x, y, k)
        unless valid?(x, y)
          return false
        end
     
        tile_id = data[x, y, k]
        if tile_id == nil
          return false
        elsif @priorities[tile_id] != 0
          return false
        end
     
        return true
      end
     
      def setup_surfaces
        @surfaces = []
        for k in 0..2
          for x in 0..(width-1)
            for y in 0..(height-1)
              tag = first_tag(x,y)
              if tag == Wall_Tag
                if y > 0
                  tagU = first_tag(x,y-1)
                  if tagU == Block_Tag
                    @surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32)
                  end
                end
                if x > 0
                  tagL = first_tag(x-1,y)
                  if tagL != Wall_Tag
                    @surfaces << Block_WL.new(x*32,y*32,x*32,y*32+32)
                    @surfaces << Block_IR.new(x*32-1,y*32,x*32-1,y*32+32)
                  end
                end
                if x < width-1
                  tagR = first_tag(x+1,y)
                  if tagR != Wall_Tag
                    @surfaces << Block_IL.new(x*32+32,y*32,x*32+32,y*32+32)
                    @surfaces << Block_WR.new(x*32+31,y*32,x*32+31,y*32+32)
                  end
                end          
              elsif tag == Roof_Tag # не представляю, что это, пилите, Шура
                i = tile_id(x,y,k)
                #@surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32) if tile_pass?(x, y, 2, k)
                @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if tile_pass?(x, y, 8, k)
                @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if tile_pass?(x, y, 6, k)
                @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if tile_pass?(x, y, 4, k)
              elsif tag == Block_Tag            
                if y < height-1
                  tagD = first_tag(x,y+1)
                  if tagD != Block_Tag
                    @surfaces << Block_SD.new(x*32,y*32+31,x*32+32,y*32+31)
                  end
                end
                if y > 0
                  tagU = first_tag(x,y-1)
                  if tagU != Block_Tag
                     @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) 
                  end
                end
                if x > 0
                  tagL = first_tag(x-1,y)
                  if tagL != Block_Tag
                    @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) 
                  end
                end
                if x < width-1
                  tagR = first_tag(x+1,y)
                  if tagR != Block_Tag
                    @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32)
                  end
                end    
               # @surfaces << Block_SD.new(x*32,y*32+31,x*32+32,y*32+31)
               # @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) 
               # @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32)
               # @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) 
              end
            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_refresh refresh
     
      def initialize(m,e)
        @light = nil
        kbl_initialize(m,e)
      end
     
      def refresh
        kbl_refresh
        setup_light(@page.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 > 640 && sy > 480 && 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
     
     
    #-------------------------------------------------------------------------------
    # Этот метод написан в качестве замены VX-овскому clear_rect у битмапа
    #-------------------------------------------------------------------------------
    def clear_rect(bitmap, x1, y1, x2, y2)
      if bitmap != nil
        empty = Color.new(0,0,0,0)
        bitmap.fill_rect(Rect.new(x1, y1, x2, y2), empty) 
      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
        
        i1 = (sx + range - @x1) / R_G
        for i in 0..i1
          x = R_G*i + @x1
          init = shadow_iy(x)
          clear_rect(bitmap, x-phx, init-phy, R_G, 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
        
        i1 = ((sx-range).to_i - @x1) / R_G
        for i in i1..0
          x = @x1 + R_G*i
          init = shadow_iy(x)
          clear_rect(bitmap, x-phx, init-phy, R_G, 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
        
        i1 = (sx + range - @x1) / R_G    
        for i in 0..i1
          x = R_G*i + @x1
          init = shadow_iy(x).floor
          clear_rect(bitmap, x-phx, init-3-phy, R_G, 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
        
        i1 = ((sx-range).to_i - @x1) / R_G 
        for i in i1..0
          x = @x1 + R_G*i
          init = shadow_iy(x).floor
          clear_rect(bitmap, x-phx,init-3-phy,R_G,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
           
        i1 = (sx + range - @x1) / R_G
        for i in 0..i1
          x = R_G*i + @x1
          init = shadow_iy(x)
          clear_rect(bitmap, x-phx,init-phy,R_G,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
        
        i1 = ((sx-range).to_i - @x1) / R_G    
        for i in i1..0
          x = @x1 + R_G*i
          init = shadow_iy(x)
          clear_rect(bitmap, x-phx,init-phy,R_G,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
    
        i1 = (sy + range - @y1) / R_G 
        for i in 0..i1
          y = R_G*i + @y1
          init = shadow_ix(y)
          clear_rect(bitmap, init-phx,y-phy,shadow_fx(y)-init+1,R_G)
        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
        
        i1 = ((sy-range).to_i - @y1) / R_G
        for i in i1..0
          y = @y1 + R_G*i
          init = shadow_ix(y)
          clear_rect(bitmap, init-phx,y-phy,shadow_fx(y)-init+1,R_G)
        end
      end
     
      def shadow_ix(y)
        return @m1.nil? ? @x1 : (y-@n1)/@m1
      end
     
      def shadow_fx(y)
        return @m2.nil? ? @x2 : (y-@n2)/@m2
      end
    end
     
     
    class Spriteset_Map
      include Light_Core
     
      alias kbl_initialize initialize
      alias kbl_update update
      alias kbl_dispose dispose
     
      def initialize
        setup_lights
        kbl_initialize
      end
     
      def update
        kbl_update
        update_lights
      end
     
      def dispose
        kbl_dispose
        dispose_lights
      end
     
      def dispose_lights
        $game_map.lantern.dispose
        $game_map.light_sources.each { |source| source.dispose_light }
        $game_map.light_surface.bitmap.dispose
        $game_map.light_surface.dispose
        $game_map.light_surface = nil
      end
     
      def update_lights
        $game_map.light_surface.bitmap.clear
        $game_map.light_surface.bitmap.fill_rect(0,0,640,4  80,$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.lante  rn.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(640,480)
        $game_map.light_surface.bitmap.fill_rect(0,0,640,4  80,$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


    Оригинал для VX Ace:

    Спойлер Код:

    Код:
    #-------------------------------------------------------------------------------
    # * [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_m",180,30,true],
      3 => ["light_s",255,0,true],
      
    #-------------------------------------------------------------------------------
    # End of effecs configuration
    #------------------------------------------------------------------------------- 
      } #  <= DON'T change this!
      
      # Z coordinate of the Effect's Surface
      Surface_Z = 180
      
      # Enable Effect's Surface control by "Screen Tone" command?
      Surface_UE = true
      
      # 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
    module Light_Bitcore
      include Light_Core
      def self.initialize
        @@buffer = {}
        Effects.values.each { |effect| Light_Bitcore.push(effect[0])}
      end
      def self::[](key)
        return @@buffer[key]
      end
      def self.push(key)
        return if @@buffer.keys.include?(key)
        @@buffer[key] = Cache.light(key)
      end
    end
    Light_Bitcore.initialize
    class Light_SSource
      attr_reader :real_x
      attr_reader :real_y
      attr_reader :range
      attr_accessor :bitmap
      attr_reader :w
      attr_reader :h
      attr_reader :hs
      def initialize(char,bitmap,opacity,plus,hs)
        sync(char)
        @key = bitmap
        @bitmap = Light_Bitcore[@key].clone
        @range = @bitmap.width/2
        @w = @bitmap.width
        @h = @bitmap.height
        @mr = @range - 16
        @opacity = opacity
        @plus = plus
        @hs = hs
        render if @hs
      end
      def render
        tx = x
        ty = y
        tsx = x + @range
        tsy = y + @range
        dr = @range*2
        for s in $game_map.surfaces
          next if !s.visible?(tsx,tsy) || !s.within?(tx,tx+dr,ty,ty+dr)
          s.render_shadow(tx,ty,tsx,tsy,@range,@bitmap)
        end
      end
      def restore
        return unless @bitmap.nil?
        @bitmap = Light_Bitcore[@key].clone
        render if @hs
      end
      def opacity
        @plus == 0 ? @opacity : (@opacity + rand(@plus))
      end
      def sx
        return $game_map.adjust_x(@real_x)*32-@mr
      end
      def sy
        return $game_map.adjust_y(@real_y)*32-@mr
      end
      def sync(char)
        p real_x
        @real_x = char.real_x
        @real_y = char.real_y
      end
      def x
        return (@real_x*32 - @mr).to_f
      end
      def y
        return (@real_y*32 - @mr).to_f
      end
      def dispose
        return if @bitmap.nil?
        @bitmap.dispose
        @bitmap = nil
      end
    end
    class Light_DSource < Light_SSource
      attr_reader :bitmap
      attr_reader :visible
      def initialize
        @key = nil
        @bitmap = nil
        @opacity = 255
        @plus = 0
        @char = $game_player
        @visible = false
      end
      def set_opacity(o,p)
        @opacity = o
        @plus = p
      end
      def set_graphic(sb)
        dispose
        @key = {2=>sb,4=>sb,6=>sb,8=>sb}
        Light_Bitcore.push(sb)
        @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
        @range = @bitmap[2].width/2
        @w = @bitmap[2].width
        @h = @bitmap[2].height
        @mr = @range - 16
      end
      def set_multiple_graphics(ba)
        dispose
        @key = ba
        @key.values.each {|key| Light_Bitcore.push(key)}
        @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
        @range = @bitmap[2].width/2
        @w = @bitmap[2].width
        @h = @bitmap[2].height
        @mr = @range - 16
      end
      def get_graphic
        return @bitmap[@char.direction].clone
      end
      def show
        return if @bitmap.nil?
        @visible = true
      end
      def hide
        @visible = false
      end
      def restore
        return if @key.nil?
        @key.values.each {|key| Light_Bitcore.push(key)}
        @bitmap = {2=>Light_Bitcore[@key[2]].clone,4=>Light_Bitcore[@key[4]].clone,6=>Light_Bitcore[@key[6]].clone,8=>Light_Bitcore[@key[8]].clone}
      end
      def dispose
        return if @bitmap.nil?
        @bitmap.values.each { |b| b.dispose }
        @bitmap = nil
      end
      def change_owner(char)
        @char = char
      end
      def render
      end
      def sx
        return $game_map.adjust_x(@char.real_x)*32-@mr
      end
      def sy
        return $game_map.adjust_y(@char.real_y)*32-@mr
      end
      def x
        return (@char.real_x*32 - @mr).to_f
      end
      def y
        return (@char.real_y*32 - @mr).to_f
      end
    end
    class Light_Surface
      def initialize
        @ta = @a = 0
        @tr = @r = 255
        @tg = @g = 255
        @tb = @b = 255
        @va = @vr = @vg = @vb = 0.0
        @timer = 0
      end
      def refresh
        return if @timer == 0
        @a += @va
        @r += @vr
        @g += @vg
        @b += @vb
        $game_map.light_surface.opacity = @a
        @timer -= 1
      end
      def change_color(time,r,g,b,a=nil)
        r = 0 if r < 0; r = 255 if r > 255
        g = 0 if g < 0; g = 255 if g > 255
        b = 0 if b < 0; b = 255 if b > 255
        unless a.nil?
          a = 0 if a < 0; a = 255 if a > 255
        end
        @timer = time
        @tr = 255-r
        @tg = 255-g
        @tb = 255-b
        @va = (a.nil? ? 0 : (a-@a).to_f/@timer)
        @vr = (@tr - @r).to_f/@timer
        @vg = (@tg - @g).to_f/@timer
        @vb = (@tb - @b).to_f/@timer
      end
      def change_alpha(time,a)
        a = 0 if a < 0; a = 255 if a > 255
        @timer = time
        @ta = a
        @vr = @vg = @vb = 0.0
        @va = (a-@a).to_f/@timer
      end
      def set_color(r,g,b)
        r = 0 if r < 0; r = 255 if r > 255
        g = 0 if g < 0; g = 255 if g > 255
        b = 0 if b < 0; b = 255 if b > 255
        @tr = @r = 255-r
        @tg = @g = 255-g
        @tb = @b = 255-b
        @va = @vr = @vg = @vb = 0.0
        @timer = 0
      end
      def set_alpha(a)
        a = 0 if a < 0; a = 255 if a > 255
        @ta = @a = a
        $game_map.light_surface.opacity = @a
        @va = @vr = @vg = @vb = 0.0
        @timer = 0
      end
      def alpha
        return @a
      end
      def color
        return Color.new(@r,@g,@b)
      end
    end
    class Game_Map
      include Light_Core
      attr_accessor :light_surface
      attr_accessor :light_sources
      attr_accessor :surfaces
      attr_accessor :effect_surface
      attr_accessor :lantern
      alias kbl_setup_events setup_events
      alias kbl_initialize initialize
      alias kbl_update update
      def initialize
        kbl_initialize
        @effect_surface = Light_Surface.new
        @lantern = Light_DSource.new
      end
      def update(arg)
        @effect_surface.refresh if arg
        kbl_update(arg)
      end
      def first_tag(x,y)
        tag = tileset.flags[tile_id(x,y,0)] >> 12
        return tag > 0 ? tag : 0
      end
      def setup_events
        @light_sources.nil? ? @light_sources = [] : @light_sources.clear
        setup_surfaces
        merge_surfaces
        kbl_setup_events
      end
      def setup_surfaces
        @surfaces = []
        for x in 0..(width-1)
          for y in 0..(height-1)
            tag = first_tag(x,y)
            if tag == Wall_Tag
              i = tile_id(x,y,0)
              if i & 0x02 == 0x02
                @surfaces << Block_SD.new(x*32,y*32,x*32+32,y*32)
              end
              if i & 0x04 == 0x04
                @surfaces << Block_WR.new(x*32+31,y*32,x*32+31,y*32+32)
                @surfaces << Block_IL.new(x*32+32,y*32,x*32+32,y*32+32)
              end
              if i & 0x01 == 0x01
                @surfaces << Block_IR.new(x*32-1,y*32,x*32-1,y*32+32)
                @surfaces << Block_WL.new(x*32,y*32,x*32,y*32+32)
              end
            elsif tag == Roof_Tag
              i = tile_id(x,y,0)
              @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if i & 0x02 == 0x02
              @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if i & 0x04 == 0x04
              @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if i & 0x01 == 0x01
            elsif tag == Block_Tag
              f = tileset.flags[tile_id(x,y,0)]
              @surfaces << Block_SL.new(x*32,y*32,x*32,y*32+32) if f & 0x02 == 0x02
              @surfaces << Block_SR.new(x*32+31,y*32,x*32+31,y*32+32) if f & 0x04 == 0x04
              @surfaces << Block_SU.new(x*32,y*32,x*32+32,y*32) if f & 0x08 == 0x08
            end
          end
        end
      end
      def merge_surfaces
        new_surfaces = []
        hs = []; vs = []
        ws = []; is = []
        for surface in @surfaces
          if surface.type & 0x05 == 0
            hs << surface
          else
            if surface.type & 0x010 == 0
              vs << surface
            else
              if surface.type & 0x08 == 0
                ws << surface
              else
                is << surface
              end
            end
          end
        end
        for surface in hs
          surface.ready ? next : surface.ready = true
          for s in hs
            next if s.ready || s.y1 != surface.y1 || surface.type != s.type
            if s.x2 == surface.x1
              surface.x1 = s.x1
              s.trash = true
              s.ready = true
              surface.ready = false
            elsif s.x1 == surface.x2
              surface.x2 = s.x2
              s.trash = true
              s.ready = true
              surface.ready = false
            end
          end
        end
        hs.each { |s| @surfaces.delete(s) if s.trash}
        for surface in vs
          surface.ready ? next : surface.ready
          for s in vs
            next if s.ready || s.x1 != surface.x1
            if s.y2 == surface.y1
              surface.y1 = s.y1
              s.trash = true
              s.ready = true
              surface.ready = false
            elsif s.y1 == surface.y2
              surface.y2 = s.y2
              s.trash = true
              s.ready = true
              surface.ready = false
            end
          end
        end
        vs.each { |s| @surfaces.delete(s) if s.trash}
        for surface in ws
          surface.ready ? next : surface.ready
          for s in ws
            next if s.ready || s.x1 != surface.x1
            if s.y2 == surface.y1
              surface.y1 = s.y1
              s.trash = true
              s.ready = true
              surface.ready = false
            elsif s.y1 == surface.y2
              surface.y2 = s.y2
              s.trash = true
              s.ready = true
              surface.ready = false
            end
          end
        end
        ws.each { |s| @surfaces.delete(s) if s.trash}
        for surface in is
          surface.ready ? next : surface.ready
          for s in is
            next if s.ready || s.x1 != surface.x1
            if s.y2 == surface.y1
              surface.y1 = s.y1
              s.trash = true
              s.ready = true
              surface.ready = false
            elsif s.y1 == surface.y2
              surface.y2 = s.y2
              s.trash = true
              s.ready = true
              surface.ready = false
            end
          end
        end
        is.each { |s| @surfaces.delete(s) if s.trash}
      end
    end
    class Game_Event < Game_Character
      alias kbl_initialize initialize
      alias kbl_setup_page setup_page
      def initialize(m,e)
        @light = nil
        kbl_initialize(m,e)
      end
      def setup_page(np)
        kbl_setup_page(np)
        setup_light(np.nil?)
      end
      def setup_light(dispose)
        unless @light.nil?
          $game_map.light_sources.delete(self)
          @light.dispose
          @light = nil
        end
        unless dispose && @list.nil?
          for command in @list
            if command.code == 108 && command.parameters[0].include?("[light")
              command.parameters[0].scan(/\[light ([0.0-9.9]+)\]/)
              effect = Light_Core::Effects[$1.to_i]
              @light = Light_SSource.new(self,effect[0],effect[1],effect[2],effect[3])
              $game_map.light_sources << self
              return
            end
          end
        end
      end
      def draw_light
        sx = @light.sx
        sy = @light.sy
        w = @light.w
        h = @light.h
        return if sx > 544 && sy > 416 && sx + w < 0 && sy + h < 0
        $game_map.light_surface.bitmap.blt(sx,sy,@light.bi  tmap,Rect.new(0,0,w,h),@light.opacity)
      end
      def dispose_light
        @light.dispose
      end
      def restore_light
        @light.restore
      end
    end
    if Light_Core::Surface_UE
      class Game_Interpreter
        def command_223
          $game_map.effect_surface.change_color(@params[1],@params[0].red,@params[0].green,@params[0].blue,@params[0].gray)
          wait(@params[1]) if @params[2]
        end
      end
    end
    class Game_Interpreter
      def self_event
        return $game_map.events[@event_id]
      end
    end
    class Block_Surface
      include Light_Core
      attr_accessor :x1
      attr_accessor :y1
      attr_accessor :x2
      attr_accessor :y2
      attr_accessor :ready
      attr_accessor :trash
      def initialize(x1,y1,x2,y2)
        @x1 = x1
        @y1 = y1
        @x2 = x2
        @y2 = y2
        @ready = false
        @trash = false
      end
      def within?(min_x,max_x,min_y,max_y)
        return @x2 > min_x && @x1 < max_x && @y2 > min_y && @y1 < max_y
      end
    end
    class Block_SL < Block_Surface
      attr_reader :type
      def initialize(x1,y1,x2,y2)
        super(x1,y1,x2,y2)
        @type = 0x01
      end
      def visible?(sx,sy)
        return sx < @x1 
      end
      def render_shadow(phx,phy,sx,sy,range,bitmap)
        @m1 = (@y1-sy)/(@x1-sx)
        @n1 = sy - @m1*sx
        @m2 = (@y2-sy)/(@x2-sx)
        @n2 = sy - @m2*sx
        for x in @x1..(sx+range)
          init = shadow_iy(x)
          bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)
        end
      end
      def shadow_iy(x)
        return @m1*x+@n1
      end
      def shadow_fy(x)
        return @m2*x+@n2
      end
    end
    class Block_SR < Block_Surface
      attr_reader :type
      def initialize(x1,y1,x2,y2)
        super(x1,y1,x2,y2)
        @type = 0x04
      end
      def visible?(sx,sy)
        return sx > @x1 
      end
      def render_shadow(phx,phy,sx,sy,range,bitmap)
        @m1 = (@y1-sy)/(@x1-sx)
        @n1 = sy - @m1*sx
        @m2 = (@y2-sy)/(@x2-sx)
        @n2 = sy - @m2*sx
        for x in (sx-range).to_i..@x1
          init = shadow_iy(x)
          bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+3)
        end
      end
      def shadow_iy(x)
        return @m1*x+@n1
      end
      def shadow_fy(x)
        return @m2*x+@n2
      end
    end
    class Block_IL < Block_Surface
      attr_reader :type
      def initialize(x1,y1,x2,y2)
        super(x1,y1,x2,y2)
        @type = 0x019
      end
      def visible?(sx,sy)
        return sx < @x1 && sy > @y1
      end
      def render_shadow(phx,phy,sx,sy,range,bitmap)
        @m1 = (@y1-sy)/(@x1-sx)
        @n1 = @y1 - @m1*@x1
        @m2 = (@y2-sy)/(@x2-sx)
        @m2 = 0 if @m2 > 0
        @n2 = @y2 - @m2*@x2
        for x in @x1..(sx+range)
          init = shadow_iy(x).floor
          bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)
        end
      end
      def shadow_iy(x)
        return @m1*x+@n1
      end
      def shadow_fy(x)
        return @m2*x+@n2
      end
    end
    class Block_IR < Block_Surface
      attr_reader :type
      def initialize(x1,y1,x2,y2)
        super(x1,y1,x2,y2)
        @type = 0x01c
      end
      def visible?(sx,sy)
        return sx > @x1 && sy > @y1
      end
      def render_shadow(phx,phy,sx,sy,range,bitmap)
        @m1 = (@y1-sy)/(@x1-sx)
        @n1 = @y1 - @m1*@x1
        @m2 = (@y2-sy)/(@x2-sx)
        @m2 = 0 if @m2 < 0
        @n2 = @y2 - @m2*@x2
        for x in (sx-range).to_i..@x1
          init = shadow_iy(x).floor
          bitmap.clear_rect(x-phx,init-3-phy,1,shadow_fy(x)-init+3)
        end
      end
      def shadow_iy(x)
        return @m1*x+@n1
      end
      def shadow_fy(x)
        return @m2*x+@n2
      end
    end
    class Block_WL < Block_Surface
      attr_reader :type
      def initialize(x1,y1,x2,y2)
        super(x1,y1,x2,y2)
        @type = 0x011
      end
      def visible?(sx,sy)
        return sx < @x1 && sy < @y2
      end
      def render_shadow(phx,phy,sx,sy,range,bitmap)
        @m1 = (@y1-sy)/(@x1-sx)
        @n1 = sy - @m1*sx
        @m2 = (@y2-sy)/(@x2-sx)
        @n2 = sy - @m2*sx
        for x in @x1..(sx+range)
          init = shadow_iy(x)
          bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)
        end
      end
      def shadow_iy(x)
        return @m1*x+@n1
      end
      def shadow_fy(x)
        return @m2*x+@n2
      end
    end
    class Block_WR < Block_Surface
      attr_reader :type
      def initialize(x1,y1,x2,y2)
        super(x1,y1,x2,y2)
        @type = 0x014
      end
      def visible?(sx,sy)
        return sx > @x1 && sy < @y2
      end
      def render_shadow(phx,phy,sx,sy,range,bitmap)
        @m1 = (@y1-sy)/(@x1-sx)
        @n1 = sy - @m1*sx
        @m2 = (@y2-sy)/(@x2-sx)
        @n2 = sy - @m2*sx
        for x in (sx-range).to_i..@x1
          init = shadow_iy(x)
          bitmap.clear_rect(x-phx,init-phy,1,shadow_fy(x)-init+2)
        end
      end
      def shadow_iy(x)
        return @m1*x+@n1
      end
      def shadow_fy(x)
        return @m2*x+@n2
      end
    end
    class Block_SU < Block_Surface
      attr_reader :type
      def initialize(x1,y1,x2,y2)
        super(x1,y1,x2,y2)
        @type = 0x02
      end
      def visible?(sx,sy)
        return sy < @y1
      end
      def render_shadow(phx,phy,sx,sy,range,bitmap)
        if @x1 == sx
          @m1 = nil
        else
          @m1 = (@y1-sy)/(@x1-sx)
          @m1 += ACC if @m1 < -ACC
          @n1 = @y1 - @m1*@x1
        end
        if @x2 == sx
          @m2 = nil
        else
          @m2 = (@y2-sy)/(@x2-sx)
          @n2 = sy - @m2*sx
        end
        for y in @y1..(sy+range)
          init = shadow_ix(y)
          bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)
        end
      end
      def shadow_ix(y)
        return @m1.nil? ? @x1 : (y-@n1)/@m1
      end
      def shadow_fx(y)
        return @m2.nil? ? @x2 : (y-@n2)/@m2
      end
    end
    class Block_SD < Block_Surface
      attr_reader :type
      def initialize(x1,y1,x2,y2)
        super(x1,y1,x2,y2)
        @type = 0x08
      end
      def visible?(sx,sy)
        return sy > @y1
      end
      def render_shadow(phx,phy,sx,sy,range,bitmap)
        if @x1 == sx
          @m1 = nil
        else
          @m1 = (@y1-sy)/(@x1-sx)
          @m1 -= ACC if @m1 > ACC
          @n1 = sy - @m1*sx
        end
        if x2 == sx
          @m2 = nil
        else
          @m2 = (@y2-sy)/(@x2-sx)
          @n2 = sy - @m2*sx
        end
        for y in (sy-range).to_i..@y1
          init = shadow_ix(y)
          bitmap.clear_rect(init-phx,y-phy,shadow_fx(y)-init+1,1)
        end
      end
      def shadow_ix(y)
        return @m1.nil? ? @x1 : (y-@n1)/@m1
      end
      def shadow_fx(y)
        return @m2.nil? ? @x2 : (y-@n2)/@m2
      end
    end
    class Spriteset_Map
      include Light_Core
      alias kbl_initialize initialize
      alias kbl_update update
      alias kbl_dispose dispose
      def initialize
        setup_lights
        kbl_initialize
      end
      def update
        kbl_update
        update_lights
      end
      def dispose
        kbl_dispose
        dispose_lights
      end
      def dispose_lights
        $game_map.lantern.dispose
        $game_map.light_sources.each { |source| source.dispose_light }
        $game_map.light_surface.bitmap.dispose
        $game_map.light_surface.dispose
        $game_map.light_surface = nil
      end
      def update_lights
        $game_map.light_surface.bitmap.clear
        $game_map.light_surface.bitmap.fill_rect(0,0,544,4  16,$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.lante  rn.sx,$game_map.lantern.sy,@btr,Rect.new(0,0,dr,dr  ),$game_map.lantern.opacity)
      end
      def setup_lights
        @btr = nil
        $game_map.lantern.restore
        $game_map.light_sources.each { |source| source.restore_light }
        $game_map.light_surface = Sprite.new
        $game_map.light_surface.bitmap = Bitmap.new(544,416)
        $game_map.light_surface.bitmap.fill_rect(0,0,544,4  16,$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


    Скриншоты и видео:



    Спойлер Скриншоты:






    Спойлер Видео:


    Дополнительная информация:

    В процессе разработки новых уровней понадобилось хорошее освещение в темноте. Добрые люди ткнули меня носом в Khas Awesome Light Effects для VX, и я отконвертил его для себя под XP, заодно перевел инструкцию. Если кому интересно - забирайте из тестового проекта yadi.sk/d/_xz99gOE48hB4 или под спойлером ниже, но, вероятно, скрипт будет еще дорабатываться - мне не нравятся тормоза при динамическом освещении на моем ноуте с i5.[/QUOTE]

    Сделал апдейт 1.1. В настройки добавлен параметр R_G, отвечающий за грубость теней => за скорость работы скрипта.
    Не скажу, что даже при R_G == 4 (вполне себе грубые 4хпиксельнолесенные тени), все летает - особенно в узких проходах - но гораздо лучше, чем изначально в версии 1.0 или при R_G == 1 (идеал)
    Последний раз редактировалось Arnon; 04.06.2013 в 14:10. Причина: шаблон
    back to the primitive

    http://cavemangame.blogspot.ru/ - разные идеи и новости
    http://cavescripts.blogspot.ru/ - мои скрипты
    http://cavecrusader.blogspot.ru/ - текущий проект

  2. #2
    Хранитель Форума Аватар для Валера
    Информация о пользователе
    Регистрация
    15.04.2008
    Адрес
    Москва
    Сообщений
    14,006
    Записей в дневнике
    3
    Репутация: 166 Добавить или отнять репутацию

    По умолчанию

    Ты вроде без очков был и без книжки? Уровни набираешь? А дальше что будет? Татуировки или шляпа? ))

    Спойлер И как тебе не стыдно-то, а, Валера?:


    Оборона форта: http://rghost.ru/8kLGxFtD2
    Сделать, чтоб все происходило, как я хочу, - вот, собственно, и весь мейкер!
    Адский Рейд: http://rpgmaker.su/vbdownloads.php?d...downloadid=106

  3. #3
    Маститый Аватар для HopeBree
    Информация о пользователе
    Регистрация
    27.03.2013
    Сообщений
    1,204
    Записей в дневнике
    6
    Репутация: 38 Добавить или отнять репутацию

    По умолчанию

    а можно под асе подогнать?
    я думаю многие будут благодарны

  4. #4
    Бывалый Аватар для caveman
    Информация о пользователе
    Регистрация
    15.02.2013
    Сообщений
    766
    Записей в дневнике
    47
    Репутация: 85 Добавить или отнять репутацию

    По умолчанию

    Оригинал закинул в первый пост.

    Валера: в первую очередь я хочу новенький каменный топор))
    back to the primitive

    http://cavemangame.blogspot.ru/ - разные идеи и новости
    http://cavescripts.blogspot.ru/ - мои скрипты
    http://cavecrusader.blogspot.ru/ - текущий проект

  5. #5
    Маститый Аватар для Bullet S.D.
    Информация о пользователе
    Регистрация
    27.01.2009
    Адрес
    Москва
    Сообщений
    1,360
    Записей в дневнике
    9
    Репутация: 74 Добавить или отнять репутацию

    По умолчанию

    А можно это в файле проекта выложить и скриншоты пожалуйста, голый код не особо привлекает. Хочется потестить демку.
    Спойлер Проекты Dark Rise INC.:

  6. #6
    Бывалый Аватар для caveman
    Информация о пользователе
    Регистрация
    15.02.2013
    Сообщений
    766
    Записей в дневнике
    47
    Репутация: 85 Добавить или отнять репутацию

    По умолчанию

    В первом топике была ссылка на ядиск.
    Здесь я проапдейтил дему скриптом с настройкой грубости теней http://yadi.sk/d/r_SsESIN4Aa6Y .
    Скриншоты, но там ничего военного нет :
    _d1.png_d2.png
    back to the primitive

    http://cavemangame.blogspot.ru/ - разные идеи и новости
    http://cavescripts.blogspot.ru/ - мои скрипты
    http://cavecrusader.blogspot.ru/ - текущий проект

  7. #7

    По умолчанию

    Жаль оно не работает с скриптом на время. Когда темно становиться они не светятся(

  8. #8
    Бывалый Аватар для caveman
    Информация о пользователе
    Регистрация
    15.02.2013
    Сообщений
    766
    Записей в дневнике
    47
    Репутация: 85 Добавить или отнять репутацию

    По умолчанию

    что за скрипт на время?
    при желании, все мержится жеж
    back to the primitive

    http://cavemangame.blogspot.ru/ - разные идеи и новости
    http://cavescripts.blogspot.ru/ - мои скрипты
    http://cavecrusader.blogspot.ru/ - текущий проект

  9. #9

    По умолчанию

    этот
    Код:
     #Basic Game Time + Night/Day 
    #----------# 
    #Features: Provides a series of functions to set and recall current game time 
    #          as well customizable tints based on current game time to give the 
    #          appearance of night and day. 
    # 
    #Usage:   Script calls: 
    #           GameTime::minute?   - returns the current minute 
    #           GameTime::hour?     - returns the current hour 
    #           GameTime::set(time) - sets the game time to time, in frames (max:1440) 
    #           GameTime::change(time) - increments the game time! (can be negative) 
    #           GameTime::pause_time(set) - stops time for events and stuff, true or false 
    #           GameTime::pause_tint(set) - time runs, but tints do not update 
    #           GameTime::clock(set) - sets whether clock is visible or not 
    #          
    #Customization: Set below, in comments. 
    # 
    #Examples: GameTime::set(360) 
    # 
    #----------# 
    #-- Script by: V.M of D.T 
    #--- Free to use in any project with credit given 
    
    #---Game Clock---# 
    #USE_CLOCK to true to display game time clock 
    #CLOCK_POSITION for position of clock 
    #  1 = topleft, 2 = topright, 3 = bottomleft, 4 = bottomright 
    #CLOCK_TOGGLE is any input button available, see the INPUT help file for options 
    #------# 
    USE_CLOCK       = false 
    CLOCK_POSITION  = 4 
    CLOCK_TOGGLE    = :SHIFT 
    
    module GameTime 
      #---Game Time Details---# 
      #Number of frames in a game minute, 60 frames = 1 second 
      TIME_COUNT      = 60 
      #Sets whether to tint screen based on game time 
      USE_TINT        = true 
    
      #True to pause time while not in map or while during a message 
      PAUSE_IN_COMBAT  = false 
      PAUSE_NOT_IN_MAP = true 
      PAUSE_IN_MESSAGE = false 
    
      #Sets time frames of tints by minute count, one day is 1440 minutes 
      # 0 = 12am, 360 = 6am, 720 = 12pm, 1080 = 6pm  etc... 
      PRESUNRISE_TIME = 240 
      SUNRISE_TIME    = 360 
      NOONSTART_TIME  = 660 
      NOONEND_TIME    = 900 
      PRESUNSET_TIME  = 1080 
      SUNSET_TIME     = 1260 
      MIDNIGHT_TIME   = 60  #Must be greater than 0 
    
      #Sets custome tints 
      PRESUNRISE_TONE = Tone.new(-75,-75,0,50) 
      SUNRISE_TONE    = Tone.new(0,0,0,0) 
      NOONSTART_TONE  = Tone.new(45,45,0,-25) 
      NOONEND_TONE    = Tone.new(0,0,0,0) 
      PRESUNSET_TONE  = Tone.new(-50,-50,0,25) 
      SUNSET_TONE     = Tone.new(-75,-100,0,75) 
      MIDNIGHT_TONE   = Tone.new(-125,-125,0,125) 
    
      #Include the ids of any maps not to be tinted based on time 
      # Usually reserved for indoor maps 
      NOTINTMAPS = [11,4,5,6,7,8,24] 
      #---END---# 
    
      def self.init 
        $game_time = 0 
        $game_time_pause_time = false 
        $game_time_pause_tint = false 
      end 
      def self.update 
        if $game_time_pause_time then return else end 
        case SceneManager::scene_is?(Scene_Map) 
        when true 
          if $game_message.visible == true && PAUSE_IN_MESSAGE then else 
          $game_time += 1 if Graphics.frame_count % TIME_COUNT == 0 end 
        when false 
          if SceneManager::scene_is?(Scene_Battle) && PAUSE_IN_COMBAT != true 
          $game_time += 1 if Graphics.frame_count % TIME_COUNT == 0 end 
        end 
        if $game_time == 1440 then $game_time = 0 end 
        GameTime::tint if $game_time_pause_tint != true 
      end 
      def self.hour? 
        return $game_time / 60 
      end 
      def self.minute? 
        return $game_time % 60 
      end 
      def self.time? 
        meri = "AM" 
        hour = GameTime::hour? 
        minute = GameTime::minute? 
        if hour > 11 then meri = "PM" end 
        if hour == 0 then hour = 12; meri = "AM" end 
        if hour > 12 then hour -= 12 end 
        if hour < 10 then hour = " " + hour.to_s else hour.to_s end 
        if minute < 10 then minute = "0" + minute.to_s else minute.to_s end 
        return hour.to_s + ":" + minute.to_s + " " + meri 
      end 
      def self.set(number) 
        $game_time = number if number <1440> 1440 
        $game_time += 1440 if $game_time < 0 
        GameTime::tint(0) 
      end 
      def self.tint(tint = 60) 
        if USE_TINT != true then return end 
        for i in NOTINTMAPS 
          if $game_map.map_id == i 
            $game_map.screen.start_tone_change(Tone.new(0,0,0,0),0) 
            return 
          end 
        end 
        if SceneManager::scene_is?(Scene_Map) then else return end 
        case $game_time 
        when PRESUNRISE_TIME .. SUNRISE_TIME 
          $game_map.screen.start_tone_change(PRESUNRISE_TONE, tint) 
        when SUNRISE_TIME .. NOONSTART_TIME 
          $game_map.screen.start_tone_change(SUNRISE_TONE, tint) 
        when NOONSTART_TIME .. NOONEND_TIME 
          $game_map.screen.start_tone_change(NOONSTART_TONE, tint) 
        when NOONEND_TIME .. PRESUNSET_TIME 
          $game_map.screen.start_tone_change(NOONEND_TONE, tint) 
        when PRESUNSET_TIME .. SUNSET_TIME 
          $game_map.screen.start_tone_change(PRESUNSET_TONE, tint) 
        when SUNSET_TIME .. 1440 
          $game_map.screen.start_tone_change(SUNSET_TONE, tint) 
        when 0 .. MIDNIGHT_TIME 
          $game_map.screen.start_tone_change(SUNSET_TONE, tint) 
        when MIDNIGHT_TIME .. PRESUNRISE_TIME 
          $game_map.screen.start_tone_change(MIDNIGHT_TONE, tint) 
        end 
      end 
      def self.pause_time(set) 
        $game_time_pause_time = set 
      end 
      def self.pause_tint(set) 
        $game_time_pause_tint = set 
      end 
      def self.clock(set) 
        SceneManager.scene.clock_visible?(set) 
      end 
    
      class Window_Clock < Window_Base 
        def initialize 
          case CLOCK_POSITION 
          when 1 
            super(0,0,115,56) 
          when 2 
            super(429,0,115,56) 
          when 3 
            super(0,360,115,56) 
          when 4 
            super(429,360,115,56) 
          end 
        end 
        def update 
          self.contents.clear 
          self.contents.draw_text(0,0,100,24,GameTime::time?) 
        end 
      end 
    
    end 
    
    module DataManager 
      class << self 
      alias gametime_msc make_save_contents 
      alias gametime_esc extract_save_contents 
      end 
      def self.make_save_contents 
        contents = gametime_msc 
        contents[:gametime] = $game_time 
        contents 
      end 
      def self.extract_save_contents(contents) 
        gametime_esc(contents) 
        $game_time = contents[:gametime] 
      end 
    end 
    
    
    class Scene_Map < Scene_Base 
      alias gametime_post_transfer post_transfer 
      alias gametime_create_all_windows create_all_windows 
      alias gametime_update_map update 
      def post_transfer 
        GameTime::tint(0) 
        gametime_post_transfer 
      end 
      def create_all_windows 
        gametime_create_all_windows 
        @gametimeclock = GameTime::Window_Clock.new if USE_CLOCK 
      end 
      def update 
        gametime_update_map 
        @gametimeclock.update if @gametimeclock.nil? == false 
        if Input.trigger?(CLOCK_TOGGLE) and @gametimeclock.nil? == false 
          @gametimeclock.visible ? @gametimeclock.visible = false : @gametimeclock.visible = true 
        end 
      end 
      def clock_visible?(set) 
        @gametimeclock.visible = set 
      end 
    end 
    
    class Scene_Base 
      alias gametime_update update 
      def update 
        gametime_update 
        GameTime::update 
      end 
    end 
    
    GameTime::init
    Последний раз редактировалось Shiva; 19.04.2013 в 17:05.

  10. #10
    Маститый Аватар для HopeBree
    Информация о пользователе
    Регистрация
    27.03.2013
    Сообщений
    1,204
    Записей в дневнике
    6
    Репутация: 38 Добавить или отнять репутацию

    По умолчанию

    мне оригинал не нужен
    он у меня есть и уже давно, мне нужна сама реализация параметра R_G или же его можно просто скопировать и вставить?
    Shiva, засунь под теги [CODE] скрипт
    Последний раз редактировалось HopeBree; 19.04.2013 в 13:54.

Страница 1 из 3 123 ПоследняяПоследняя

Информация о теме

Пользователи, просматривающие эту тему

Эту тему просматривают: 1 (пользователей: 0 , гостей: 1)

Метки этой темы

Социальные закладки

Социальные закладки

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •  
Khas Awesome Light Effects