Код:
=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
Социальные закладки