Код:
	=begin
========================== Time management by caveman ==========================
Скрипт позволяет настроить поведение переменных, переключателей и локальных
переключателей в реальном времени в одном или несколько файлов .csv, 
например, для задания смены времен дня, ночи, поведения NPC и прочего.
Файл изначально набивается в excel или calc, для удобста (впрочем, 
можно это сделать и в блокноте, соблюдая формат, описанный ниже):
Name;forest;;;;;; - название для удобства чтения
Cycling;yes;;;;;; - признак, запускать ли обработку циклически 
Time;0:00:00;0:04:00;;;;; - начало и окончание запуска (для циклов особенно полезно)
Commands;;;;;;; - для удобства чтения
Время;Тип;Id;Значение;Map_id;Event _id;Letter;Comment - описание команд, для удобства чтения
0:00:00;Variable;1;1;;;;morning
0:00:30;Variable;1;2;;;;day
0:01:40;Switch;1;True;;;;crow
0:02:10;Switch;1;FALSE;;;;no crow
0:03:35;SelfSwitch;;True;1;3;A;squirrel
0:03:58;SelfSwitch;;FALSE;1;3;A;squirrel
Выше примеры задания обработки данных, для переменной (Variable), 
переключателя (Switch) и локального переключателя (SelfSwitch).
- Время в формате hh:mm:ss
- Название типа переключателя нечувствительно к регистру
- Для переменных и переключателей обязательно задать Id
- Для локального переключателя обязательно задать номер карты, номер события и
букву (А-D), впрочем, скрипт поддержит и расширение (A-Z) для них.
- Последнее слово в строке - необязательный комментарий
NB: ruby не кушает русские символы, сохраненые не в utf-8, так что либо
пишите на латинице, либо сохраняйтся файл csv в utf-8.
Использование в событиях примерно такое:
$time_owner.add_manager(1) - добавить первый менеджер
$time_owner.add_manager(2) - добавить еще один
$time_owner.reload(1, "test") - загрузить данные в первый менеджер
$time_owner.reload(2, "farm") - загрузить данные во второй менеджер
$time_owner.start_all - для простоты - запускаю всё, можно запускать и 
по отдельности, например, командой $time_owner.start(1)
Описание методов в комментах к классу Time_Owner в конце скрипта.
После запуска менеджера, он ведет отсчет с того момента, когда он 
запущен и выполняет простановку значений переменным, переключателям и
локальным переключателям в соответствующее время.
=end
class Time_Command
  attr_accessor :affect_type # 0 - variable, 1 - switch, 2 - self switch
 
  # для selfswitch
  attr_accessor :map_id
  attr_accessor :event_id
  attr_accessor :letter
  attr_accessor :ss_value
 
  # для switch
  attr_accessor :switch_id
  attr_accessor :s_value
 
  # для variable
  attr_accessor :var_id
  attr_accessor :v_value 
 
  attr_accessor :need_refresh # true (пока)
  attr_accessor :time # в секундах
  attr_accessor :is_used # уже пройдено
 
  def initialize
    self.need_refresh = true
  end
end
 
class Time_Manager
  attr_accessor :id # id
  attr_accessor :start_time # в секундах
  attr_accessor :end_time # в секундах
  attr_accessor :cur_time # в секундах
  attr_accessor :real_start_time # в секундах
 
  attr_accessor :need_cycle # запускать циклически
 
  attr_accessor :commands # список команд
  attr_accessor :is_started
 
  def initialize(id)
    self.id = id
    self.commands =[]
    @regexp = /\A(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?);(.*?)\Z/
  end
 
#==========================================================#
#========== Загрузка из файла =============================#
#==========================================================#
  def reload(filename)
    if FileTest.exist?(sprintf("%s.csv",filename))
      self.commands = []
      file=File.open(sprintf("%s.csv",filename),"r")
      load_timing(file)
      file.close
    #  p self.commands
    end
  end
 
  def load_timing(file)
    @lines = file.readlines
    @line = 0
    @line += 1 # название
 
    # цикличность
    @lines[@line].gsub(@regexp) do
      self.need_cycle = $2.to_s.upcase == "YES"
    end
    @line += 1
 
    # время начала и конца
    @lines[@line].gsub(@regexp) do
      self.start_time = extract_time($2.to_s)
      self.end_time = extract_time($3.to_s)
    end
    @line += 3 # пропуск строк "команды" и "заголовки"
 
    while @line < @lines.length
      @lines[@line].gsub(@regexp) do
        command = Time_Command.new
 
        command.time = extract_time($1.to_s)
        p $1.to_s
        case $2.to_s.upcase
        when "VARIABLE"
          command.affect_type = 0
          command.var_id = $3.to_i
          command.v_value = $4.to_i
        when "SWITCH"
          command.affect_type = 1
          command.switch_id = $3.to_i
          command.s_value = $4.to_s.upcase == "TRUE"
        when "SELFSWITCH"
          command.affect_type = 2
          command.ss_value = $4.to_s.upcase == "TRUE"
          command.map_id = $5.to_i
          command.event_id = $6.to_i
          command.letter = $7.to_s
        else
          p 'неверный тип!'
        end
        self.commands.push(command)
      end
      @line += 1
    end
  end  
 
  def extract_time(str)
    # выцепим время из строки вида hh:mm:ss
    str.gsub(/\A(.+?)\:(.+?)\:(.+?)\Z/) do
      hh = $1.to_i
      mm = $2.to_i
      ss = $3.to_i
      return hh * 60 * 60 + mm * 60 + ss
    end
  end
#==========================================================#
#========== Управление ====================================#
#==========================================================#  
  def start
    self.cur_time = 0
    self.real_start_time = Graphics.frame_count / Graphics.frame_rate
    self.is_started = true
  end
 
  def stop
    self.is_started = false
  end
 
  def reset
    stop
    start
  end
 
#==========================================================#
#========== Автоапдейт ====================================#
#==========================================================# 
  def update
    if is_started
      flag = false # рефрешить ли карту
      @total_sec = Graphics.frame_count / Graphics.frame_rate
      # время тут - сдвиг от запуска
      self.cur_time = @total_sec - self.real_start_time 
      # для циклического запуска, проверяем конец цикла, сбрасываем всё
      if self.need_cycle && self.cur_time >= self.end_time
        for c in self.commands
          c.is_used = false
        end
        self.cur_time = 0
        self.real_start_time = Graphics.frame_count / Graphics.frame_rate
      end
      # просматриваем команды с точным временем
      for c in self.commands
        if !c.is_used
          if c.time <= self.cur_time
            call_command(c)
            c.is_used = true
            flag = true
          end
        end
      end
      if flag
        $game_map.need_refresh = true
      end
    end
  end
 
  def call_command(c)
    if c.affect_type == 0
      $game_variables[c.var_id] = c.v_value
    elsif c.affect_type == 1
      $game_switches[c.switch_id] = c.s_value
    elsif c.affect_type == 2
      key = [c.map_id, c.event_id, c.letter]
      $game_self_switches[key] = c.ss_value
    end
  end
end
 
class Time_Owner
  attr_accessor :time_managers
 
  def initialize
    self.time_managers = []
  end
 
  # добавить менеджер c кодом id для последующего обращения к нему
  def add_manager(id)
    self.time_managers.push(Time_Manager.new(id))
  end
 
  # удалить менеджер c кодом id
  def remove_manager(id)
    for m in self.time_managers
      if m.id == id
        delete(m)
      end
    end
  end
 
  # загрузить в менеджер с кодом id данные из файла filename
  def reload(id, filename)
    for m in self.time_managers
      if m.id == id
        m.reload(filename)
      end
    end
  end
 
  # запустить менеджер с кодом id
  def start(id)
    for m in self.time_managers
      if m.id == id
        m.start
      end
    end
  end
 
  # запустить все менеджеры
  def start_all
    for m in self.time_managers
      m.start
    end
  end
 
  # остановить менеджер с кодом id
  def stop(id)
    for m in self.time_managers
      if m.id == id
        m.stop
      end
    end
  end
 
  # остановить все менеджеры
  def stop_all
    for m in self.time_managers
      m.stop
    end
  end
 
  # перезапустить менеджер с кодом id
  def reset(id)
    stop(id)
    start(id)
  end
 
  # перезапустить все менеджеры
  def reset_all
    stop_all
    start_all
  end
 
  def update
    for m in self.time_managers
      m.update
    end
  end
end
 
class Scene_Base
  alias tm_update update
  def update
    tm_update
    if $time_owner != nil
      $time_owner.update
    end
  end
end
 
class Scene_Title
  alias tm_start start
  def start
    $time_owner = Time_Owner.new
    tm_start
  end
end
 
Социальные закладки